MySQL Select into variable not working always - mysql

I am facing a strange behavior.
SELECT INTO and SET Both works for some variables and not for others. Event syntaxes are the same.
SET #Invoice_UserId := (SELECT UserId FROM invoice WHERE InvoiceId = #Invoice_Id LIMIT 1); -- Working
SET #myamount := (SELECT amount FROM invoice WHERE InvoiceId = #Invoice_Id LIMIT 1); - Not working
SELECT Amount INTO #myamount FROM invoice WHERE InvoiceId = 29 LIMIT 1; - Not working
If I run these queries directly then works, but not working in the stored procedure.

All of the syntaxes are valid and will work (apart from the invalid comment - which should be --.
If you have a problem, please post the full stored procedure.
In the stored procedure you should use local variables (DECLARE var) instead of user defined variables (#var) as local variables are strongly typed and have scope of the routine.

Related

Less than date value in Stored Procedures is not working

I have couple of tables
Movements
Entries
and want to get the stock balance of items up to a given date. So I created queries and INNER JOINED to make a single table so it is easy to get the balance. This program is saved in a SP called
StblAsAt(IN RefDate DATE,IN Store VARCHAR,OUT #STBL DOUBLE)
However when I user the date format in the body as appears in the following line it works fine.
purchaseinvoice.invoiceDate<='2021-08-30'
But when it is changed to use the parameter, it returns zero (0). No matter what date I pass.
This is my code as it is in Stored Procedure
BEGIN
SELECT (Purchase+SalesReturns+TransferIn)-(PurchaseReturns+Sales+TransferOut) INTO #STBL FROM(
SELECT COALESCE(P.Purchase,0)AS 'Purchase',
COALESCE(Sr.SalesReturn,0)AS 'SalesReturns',
COALESCE(Ti.TransferIn,0)AS 'TransferIn',
COALESCE(Pr.PurchaseReturns,0)AS 'PurchaseReturns',
COALESCE(S.Sales,0) AS 'Sales',
COALESCE(Tout.TransferOut,0)AS 'TransferOut'
FROM(
(SELECT
'OTHRMA1032' AS 'Item',
SUM(movement.itemQty) AS 'Purchase'
FROM movement
WHERE
movement.movementType=0 AND
movement.entryDate<=DATE_FORMAT(#RefDate,'%Y-%m-%d')AND #Tried #RefDate and it fails
movement.itemId='OTHRMA1032' AND
movement.reference2 IN(
SELECT purchaseinvoice.GRNId
FROM purchaseinvoice
WHERE
purchaseinvoice.invoiceDate<=DATE_FORMAT(#RefDate,'%Y-%m-%d') AND
purchaseinvoice.inwardStore='Main store'
))P
(Didn't include all queries as it would make the post junk)
This is how I call the procedure from MySql
CALL StblAsAt('2021-08-30','Main store',#STBL);
Whenever the parameter is used, it returns zero and when the date is typed in, it returns the correct value.

Pass a Running Total query using CodeIgniter

I am using CodeIgniter and trying run a query but it will not work. I believe that the error relates to the SET #runtot:=0; line. Here is the code:
<?php
$qryRunningTotalRFRs = $this->db->query("
SET #runtot:=0;
SELECT
q1.w,
q1.c,
(#runtot := #runtot + q1.c) AS rt
FROM
(SELECT week(IssuesFiledDate) AS w,
count(*) AS c
FROM tblappeals
WHERE tblappeals.Outcome = 'Upcoming'
AND tblappeals.`Year` = 2013
AND `IssuesFiledDate` >= '2013-03-31'
GROUP BY w
ORDER BY w )
AS q1
"); ?>
Can someone suggest a way to modify this so that I can pass this running sum query to MySQL? Thanks.
I read the following comment on this question which said:
Don't miss the SET statement at the top to initialize the running total variable first or you will just get a column of NULL values.
For this reason, I believed that the SET statement was required for my query to work correctly. Problem was, the query would not run with the SET statement. I deleted the SET statement, and now it works fine. For whatever reason, I guess the SET statement is not required in this context.

SQL Server Stored Procedure Email verification

I have an ASP.net that requests client's information from stored procedure in SQL Server 2008 based on a client's email address until the # sign. Since the clients often change after 3 months in this small organization, but the email addresses remain the same.
E.g. a client with email address obois_in4#cegepoutaouais.qc.ca finishes his/her contract after 3-4 months and then that email address is assigned to someone else.
Now, here's my question: I want my stored procedure to find the client information, after he/she entered obois_in4 and presses the Search button. The reason I don't want them to enter the whole email is because it's too long, and secondly they can make a mistake while typing, but typing such as obois_in4 isn't a big deal.
I wrote a code that can search a client by name, but again, the clients always change after 3-4 months but the email address remains the same.
ALTER PROCEDURE [dbo].[sp_find_client_information]
-- Add the parameters for the stored procedure here
#client_email varchar (50) = null
AS Declare #numOfRows int BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT #numOfRows = COUNT (*)
From helpdesk_clients
Where --change first name and
client_firstName = #client_email or client_lastName = #client_email;
begin
if (#numOfRows = 0)
select #numOfRows;
else if (#numOfRows = 1)
select
client_id,
client_firstName,
client_lastName,
client_work_email,
client_work_phone,
client_work_phone_ext,
client_office,
dept_nom,
client_position
from
helpdesk_clients join departments
on
helpdesk_clients.dept_id = departments.dept_id
where client_firstName like '%'+#client_email+'%';
end
END
The email address always starts with obois followed by an underscore _ then the name of the department information technology as in and then by a digit such as 4 in this case. e.g. obois_in4#cegepoutaouais.qc.ca
I am surprised nobody even bothered looking into this. The best solution is to use Substring() and CharIndex()
With SUBSTRING ( expression ,start , length ) we can truncate the string starting from a position within the string until a specified position within a string. With CHARINDEX ( expressionToFind ,expressionToSearch [ , start_location ] ), we can find the the position of a character within a given string.
substring (work_email, 1, CHARINDEX('#', work_email)-1) = #work_email ensures that a parameter doesn't have to be like shawn.smith#cegepoutaouais.qc.ca, and it's a big hassle for a client to enter his full email like shawn.smith#cegepoutaouais.qc.ca, he will only be required to enter shwan.smith, the script will search for shawn.smith in shawn.smith#cegepoutaouais.qc.ca until the # sign.
e.g.
In the stored procedure, assuming the #work_email is parameter and it's value is 'shawn.smith'
select
client_id,
client_firstName,
client_lastName,
client_work_email,
client_work_phone,
client_work_phone_ext,
client_office,
dept_nom,
client_position
from
helpdesk_clients join departments
on
helpdesk_clients.dept_id = departments.dept_id
where substring (work_email, 1, CHARINDEX('#', work_email)-1) = #work_email;
Will return the all the details mentioned in the Select statement.

MySQL design; View or Stored Procedure with variable

I've to execute a complex query, selecting several columns from 7-8 tables.
We don't want to write that query in programming language (PHP - Symfony 1.4/Propel 1.4 in our case) but to create a view or stored procedure to have very simple select query for developers. I'm confused what will be better approach.
We need query in following format:
SET #PlayerId = 1;
SELECT CASE WHEN mat.player1id = #PlayerId THEN mat.player2id ELSE mat.player1id END as opponent
/*plus many other columns*/
FROM `wzo_matches` as mat /*plus few other tables*/
WHERE (mat.player1id =#PlayerId OR mat.player2id=#PlayerId)
/*plus other join conditions*/
Problem with view is, SET #PlayerId=xx statement. We don't know player id in advance but will be passed through PHP. I hope this is the reason to rule out views; is there any workaround for that?
Other option will be stored procedure. Only issue with that is, it will create a new view for every query so operation will be very heavy for DB.
Can someone suggest best approach so that developers can get required data from above query without writing above complex query in PHP. (Obviously through SP or view & simple select query from there)
Based on reply of Can I create view with parameter in MySQL?, My issue is fixed with following queries:
create function getPlayer() returns INTEGER DETERMINISTIC NO SQL return #getPlayer;
create view getPlay as
SELECT
CASE WHEN play.hiderid = getPlayer() THEN play.seekerid ELSE play.hiderid END AS opponent, play . *
FROM odd_play play, odd_match mat
WHERE (seekerid = getPlayer() OR hiderid = getPlayer())
AND play.id = mat.latestplay;
select play.*
from (select #getPlayer:=1 p) ply, getPlay play;
CREATE PROCEDURE SELECT_PLAYER(p INT) SET #PlayerId = p
SELECT CASE WHEN mat.player1id = #PlayerId THEN mat.player2id ELSE mat.player1id END as opponent
/*plus many other columns*/
FROM `wzo_matches` as mat /*plus few other tables*/
WHERE (mat.player1id =#PlayerId OR mat.player2id=#PlayerId)
/*plus other join conditions*/

Help with MySQL Coalesce and Stored Procedures

I'm (attempting) to write a MySQL stored procedure that parses a large text file. Part of what this procedure does is check to see if the entities (in this case, government contractors) named in each record are already contained in the db. (This is a follow up to this question.) This is my first stored procedure and so I'm sure I've wondered off the rails here, and I would appreciated any help.
Here's what I have right now (after declaring the variables):
-- try and fetch first organization (a government agency)
SET agency = COALESCE(SELECT org_agency_o_id FROM orgs_agencies WHERE org_agency_code = maj_agency_cat,SELECT min(org_id) FROM orgs WHERE org_name LIKE CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5)))
-- check to see if that worked
IF agency = NULL THEN
INSERT INTO orgs (org_name,org_name_length,org_type,org_sub_types) VALUES (CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5)),LENGTH(CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5))),'org','Org,GovernmentEntity,Federal,Agency');
SET agency = LAST_INSERT_ID();
END IF;
-- try and fetch second organization
SET org = COALESCE(SELECT MIN(org_id) FROM orgs WHERE org_name IN (vendorname, vendoralternatename, vendorlegalorganizationname, vendordoingasbusinessname), SELECT MIN(org_alias_org_id) FROM orgs_aliases WHERE org_alias in (endorname, vendoralternatename, vendorlegalorganizationname, vendordoingasbusinessname))
IF org = NULL THEN
INSERT INTO orgs(org_name,org_name_length,org_type,org_sub_types,org_created) VALUES (vendorname,LENGTH(vendorname),'org','org',DATE());
SET org = LAST_INSERT_ID();
END IF
Right now MySQL is throwing an error on the line:
SET agency = COALESCE(SELECT org_agency_o_id FROM orgs_agencies WHERE org_agency_code = maj_agency_cat,SELECT min(org_id) FROM orgs WHERE org_name LIKE CONCAT('U.S. ',SUBSTRING(maj_agency_cat,5)))
'maj_agency_cat' is a variable that I declare at the beginning of the procedure and then is assigned dynamically using a cursor that goes through my staging data. The full stored procedure can be viewed here.
I'm sure I'm missing something basic and would appreciate any help.
Try wrapping another () around the inner SELECT statements in your COALESCE arguments. Otherwise, they are not treated as subqueries to be executed first and the value returned, but as query objects passed into COALESCE, which is not a valid argument type for COALESCE:
SET agency = COALESCE((SELECT ..), (SELECT ..))