I receive error 1318 when I call this procedure in MYSQL. What am I doing wrong with this stored procedure? Am I even allowed to do something like this?
CREATE DEFINER=`root`#`localhost` PROCEDURE `CN_renumber`
(
OUT #maxCn,
OUT param1 INT,
OUT update_count INT
)
BEGIN
DECLARE sql_error TINYINT DEFAULT FALSE;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET sql_error = TRUE;
START TRANSACTION;
/*Renumber Cn in DBO*/
/* Set max cn and incremented afterwords */
SET #maxCn = '23206';
UPDATE dbo.billadr SET Cn = (#maxCn:=#maxCn + 1);
IF sql_error = FALSE THEN SET update_count = 1;
COMMIT;
ELSE
SET update_count = 0;
ROLLBACK;
END IF;
END
There was a problem with parameters. Try this procedure, it will fix error 1318 -
CREATE DEFINER='root'#'localhost' PROCEDURE CN_renumber
(OUT maxCn int, OUT param1 int, OUT update_count int)
BEGIN
SET #maxCn = 23206;
UPDATE billadr SET Cn = (#maxCn := #maxCn + 1);
SET maxCn = #maxCn;
END
Usage example -
SET #maxCn = NULL;
SET #param1 = NULL;
SET #update_count = NULL;
CALL CN_renumber(#maxCn, #param1, #update_count);
SELECT #maxCn, #param1, #update_count;
Related
This is my code:
BEGIN
DECLARE _cnt INT;
DECLARE i INT DEFAULT 0 ;
DECLARE j INT DEFAULT 0 ;
DECLARE _FIPSAPNCombo VARCHAR(30) DEFAULT '00000';
DECLARE _prv_FIPSAPNCombo VARCHAR(30) DEFAULT '00000';
DECLARE _Rollyear INT DEFAULT 2000;
DECLARE _first_Rollyear INT DEFAULT 2000;
DECLARE eof boolean default FALSE;
DECLARE _AvTotal INT;
DECLARE _prv_AvTotal INT default 0;
DECLARE _YOY_PCT INT;
DECLARE _YOY_USD INT;
DECLARE _in_pct INT;
DECLARE _in_usd INT;
DECLARE _last INT;
DECLARE _id INT;
DECLARE _idx INT;
DECLARE _prv_id INT;
DECLARE get_FIPSAPNCombo CURSOR
FOR
SELECT 0, '0', 2000, 1
UNION
SELECT id, FIPSAPNCombo, rollyear, AvTotal
FROM AvHistory_06037 AS h
WHERE substr(h.FIPSAPNCombo,1,8) = _in_FIPSAPNCombo_8
AND h.AvTotal > 0
ORDER BY 2, 3
;
DECLARE CONTINUE HANDLER
FOR NOT FOUND
SET eof = TRUE;
SELECT YOY_PCT, YOY_USD INTO _in_pct, _in_usd FROM AlertSearches WHERE id = _in_AlertSearchesID;
START TRANSACTION;
OPEN get_FIPSAPNCombo;
doit: LOOP
fetch get_FIPSAPNCombo INTO _id, _FIPSAPNCombo, _Rollyear, _AvTotal;
SET _YOY_USD = _AvTotal - _prv_AvTotal;
SET _YOY_PCT = ROUND((((_AvTotal - _prv_AvTotal) / _prv_AvTotal) * 100),0);
IF eof = TRUE THEN
LEAVE doit;
END IF;
IF _FIPSAPNCombo != _prv_FIPSAPNCombo THEN SET _first_Rollyear = _Rollyear; ELSE SET _first_Rollyear = '2000'; END IF;
IF _YOY_PCT >= _in_pct AND _YOY_USD >= _in_usd and _Rollyear != _first_Rollyear THEN
BEGIN
DELETE FROM AvHistoryAlerts WHERE FIPSAPNCombo = _FIPSAPNCombo AND AlertSearchesID = _in_AlertSearchesID;
INSERT INTO AvHistoryAlerts VALUES (_id, _FIPSAPNCombo, '06037', _Rollyear, _AvTotal, _YOY_PCT, _YOY_USD, _prv_id, _prv_AvTotal, _in_AlertSearchesID);
UPDATE AvHistory SET CausalTransfer = NULL WHERE FIPSAPNCombo = _FIPSAPNCombo;
UPDATE AvHistory SET CausalTransfer = 'Green' WHERE id = _id;
SET i = i + 1;
IF mod(i,1000) = 0 THEN insert into error_log VALUES (concat(_in_FIPSAPNCombo_8, ' > calc_YOY_increase i = ', i, ' ',now())); COMMIT; START TRANSACTION; END IF;
END;
END IF;
SET _prv_FIPSAPNCombo = _FIPSAPNCombo;
SET _prv_AvTotal = _AvTotal;
SET _prv_id = _id;
SET eof = FALSE;
END LOOP;
COMMIT;
CLOSE get_FIPSAPNCombo;
END
I thought that the procedure would commit every 1000 records processed and that this would be reflected in the error_log table in real time.
But, the data is only available after the procedure finishes completely and then all the records show up all at once in the error_log table.
That, by itself, is not the issue: what I am concerned about is the the procedure seems to dwell on "waiting for handler commit" for a long time at the end of the procedure.
So, I'm not sure what's going on: is it storing everything in memory or in a temp table or file and then needs a lot if time for cleanup?
I thought that a commit would clear all that... but it does not seem to commit until the end of the whole procedure
Any ideas?
I'm really struggling with this LOOP in my procedure. I can't understand what the error means. I guess anyone can just try to run this without any knowledge of the database...
DROP PROCEDURE IF EXISTS removeDuplicates;
DELIMITER $$
CREATE PROCEDURE removeDuplicates(str TEXT)
BEGIN
DECLARE temp_word TEXT;
DECLARE last_word TEXT;
DECLARE result TEXT;
DECLARE finished INT DEFAULT false;
DECLARE words_cursor CURSOR FOR
SELECT word FROM explosion;
DECLARE CONTINUE handler FOR NOT found
SET finished = true;
CALL explode(str);
DROP TABLE IF EXISTS temp_words;
CREATE TABLE temp_words (id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, t VARCHAR(100));
OPEN words_cursor;
loop_words: LOOP
FETCH words_cursor INTO temp_word;
IF finished THEN
LEAVE loop_words;
IF temp_word = "" THEN
SET result = CONCAT(result, temp_word, " ");
SET last_word = temp_word;
ELSEIF last_word = temp_word THEN
SET last_word = temp_word;
ELSE
INSERT INTO temp_words (t) VALUES (temp_word);
END IF;
END LOOP loop_words;
CLOSE words_cursor;
RETURN result;
END$$
DELIMITER ;
Any pointers would be gratefully received. The error I am getting is:
[ERROR in query 2] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LOOP loop_words;
CLOSE words_cursor;
RETURN result;
END' at line 29
I'm sure it must be something simple, but I'll be damned if I can work it out.
Thanks, Chris
DROP PROCEDURE IF EXISTS removeDuplicates;
DELIMITER $$
CREATE PROCEDURE removeDuplicates(str TEXT , OUT OUT_STR_RESULT TEXT)
BEGIN
DECLARE temp_word TEXT;
DECLARE last_word TEXT;
DECLARE result TEXT;
DECLARE finished INT DEFAULT false;
DECLARE words_cursor CURSOR FOR
SELECT word FROM explosion;
DECLARE CONTINUE handler FOR NOT found
SET finished = true;
CALL explode(str);
DROP TABLE IF EXISTS temp_words;
CREATE TABLE temp_words (id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, t VARCHAR(100));
OPEN words_cursor;
loop_words: LOOP
FETCH words_cursor INTO temp_word;
IF finished THEN
LEAVE loop_words;
IF temp_word = "" THEN
SET result = CONCAT(result, temp_word, " ");
SET last_word = temp_word;
ELSEIF last_word = temp_word THEN
SET last_word = temp_word;
ELSE
INSERT INTO temp_words (t) VALUES (temp_word);
END IF;
END IF; -- i had made changes at this line.
END LOOP loop_words;
CLOSE words_cursor;
SET OUT_STR_RESULT =result;
-- RETURN result;
END$$
;
You missed one END IF.
One more thing: you can't put RETURN statement in procedure; it's only allowed in FUNCTION. Instead of that you can use OUT parameter for same.
Try above code.
delimiter %%
create procedure getFileID(in fname varchar(100), out fId int)
begin
select ID from File
where Name = fname
into fId;
end %%
delimiter ;
delimiter $$
create procedure FileINFO(in fname varchar(100))
begin
declare SMS_done, Par_don boolean default false;
declare SMSID int;
declare SMSName varchar(100) default "";
declare SMSCode varchar(100) default "";
declare ParamName varchar(100) default "";
declare fId int default 0;
call getFileID(fname, fId);
declare c1 cursor for select ID, Code, Name from SMSTemplate where F_ID = fId;
declare continue handler for not found set SMS_done = true;
open c1;
SMS_loop : loop
fetch from c1 into SMSID, SMSCode, SMSName;
if SMS_done then
close c1;
leave SMS_loop;
end if;
block2 : begin
declare c2 cursor for
select Name from ParameterType where ST_ID = SMSID;
declare continue handler for not found set Par_done = true;
open c2;
Par_loop : loop
fetch from c2 into ParamName;
if SMS_done then
set SMS_done = false;
close c2;
leave Par_loop;
end if;
insert into FileDetails
(FileName, SMSName, SMSCode, ParamName)
values
(fname, SMSName, SMSCode, ParamName);
end loop Par_loop;
end block2;
end loop SMS_loop;
select * from FileDetails;
end $$
delimiter ;
and i get that error
ERROR 1064 (42000): You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for
the right syntax to use
near 'declare c1 cursor for select ID, Code, Name from SMSTemplate where F_ID = fId;' at line 10
for starters get the declares all grouped together at the top.
Also there is no such thing as fetch into so those two things were fixed.
Par_don / Par_done had a typo in the declare.
Also, for sanity, have a drop if exist for the stored proc right above each one, so it is easily scripted and maintained.
drop procedure if exists FileINFO;
delimiter $$
create procedure FileINFO(in fname varchar(100))
begin
declare SMS_done, Par_done boolean default false;
declare SMSID int;
declare SMSName varchar(100) default "";
declare SMSCode varchar(100) default "";
declare ParamName varchar(100) default "";
declare fId int;
declare c1 cursor for select ID, Code, Name from SMSTemplate where F_ID = fId;
declare continue handler for not found set SMS_done = true;
call getFileID(fname, fId );
open c1;
SMS_loop : loop
fetch c1 into SMSID, SMSCode, SMSName;
if SMS_done then
close c1;
leave SMS_loop;
end if;
block2 : begin
declare c2 cursor for
select Name from ParameterType where ST_ID = SMSID;
declare continue handler for not found set Par_done = true;
open c2;
Par_loop : loop
fetch from c2 into ParamName;
if SMS_done then
set SMS_done = false;
close c2;
leave Par_loop;
end if;
insert into FileDetails
(FileName, SMSName, SMSCode, ParamName)
values
(fname, SMSName, SMSCode, ParamName);
end loop Par_loop;
end block2;
end loop SMS_loop;
select * from FileDetails;
end $$
delimiter ;
Does the table SMSTemplate have a field F_ID??
If not, that could be why you're getting this error.
This procedure does not return 2, it always returns 1. How to return 1 when insert happens, and return 2 when an update happens?
It is perfectly insert and update but return value always 1.
CREATE PROCEDURE [dbo].[sp_SaveEmployeeDetails]
#employeeID int
,#first_name varchar(255)
,#middle_name varchar(255)
,#last_name varchar(255)
,#gender varchar(255)
,#date_of_birth date
,#EntryBy varchar(255)
--,#ActionStatus int = NULL OUTPUT
AS
BEGIN
SET NOCOUNT OFF;
DECLARE #ActionStatus int;
IF NOT EXISTS(Select * From employees
Where employeeID =#employeeID)
BEGIN
INSERT INTO [dbo].[employees] ([first_name], [middle_name], [last_name], [gender], [date_of_birth], [EntryBy], [EntryDate])
VALUES (#first_name, #middle_name, #last_name, #gender, #date_of_birth, #EntryBy, getdate())
SET #ActionStatus = 1;
END
ELSE
BEGIN
UPDATE employees
SET [first_name] = #first_name,
[middle_name] = #middle_name,
[last_name] = #last_name,
[gender] = #gender,
[date_of_birth] = #date_of_birth,
[EntryBy] = #EntryBy,
[EntryDate] = getdate()
WHERE
employeeID = #employeeID
SET #ActionStatus = 2;
END
RETURN #ActionStatus;
--also try SELECT #ActionStatus;
END
The value you return here
RETURN #ActionStatus;
...might be set to a variable directly, its the procedure's "own" return value. Look at this example:
CREATE PROCEDURE dbo.TestReturn(#IntValue INT)
AS
BEGIN
IF #IntValue=0
RETURN 0;
ELSE
RETURN 1;
END
GO
DECLARE #RetVal INT;
EXEC #RetVal = dbo.TestReturn -1;
SELECT #RetVal;
EXEC #RetVal = dbo.TestReturn 0;
SELECT #RetVal;
EXEC #RetVal = dbo.TestReturn 1;
SELECT #RetVal;
GO
DROP PROCEDURE dbo.TestReturn;
It comes back with 1-0-1 as expected.
But this return value is bound to INT and is meant to reflect execution states (like error codes, success level...) In your case this seems to be the case...
If you think about output of any other data use OUTPUT parameters.
CREATE PROCEDURE dbo.TestReturn(#IntValue INT, #TestPrm VARCHAR(100) OUTPUT)
AS
BEGIN
IF #IntValue=0
BEGIN
SET #TestPrm='Value was 0'
RETURN 0;
END
ELSE
BEGIN
SET #TestPrm='Value was something else';
RETURN 1;
END
END
GO
DECLARE #RetVal INT;
DECLARE #RetVarchar VARCHAR(100);
EXEC #RetVal = dbo.TestReturn -1,#RetVarchar OUTPUT;
SELECT #RetVal,#RetVarchar;
EXEC #RetVal = dbo.TestReturn 0,#RetVarchar OUTPUT;
SELECT #RetVal,#RetVarchar;
EXEC #RetVal = dbo.TestReturn 1,#RetVarchar OUTPUT;
SELECT #RetVal,#RetVarchar;
GO
DROP PROCEDURE dbo.TestReturn;
I am having a very bad time with a MySQL stored procedure, I can't created this procedure in the database (MySQL 5.5.27)
I a wondering why its rejecting my from variable declaration, multiple select and if else (Hopefully is some code error) I am pasting my code in!
DELIMITER $$
DROP PROCEDURE IF EXISTS EditEnterprise
$$
CREATE PROCEDURE EditEnterprise(
IN pEnterpriseId VARCHAR(32),
IN pEnterpriseName VARCHAR(64)
)
/* declare the new variables */
DECLARE nEnterpriseId VARCHAR(32);
DECLARE nEnterpriseName VARCHAR(64);
/* declare the old variables */
DECLARE oEnterpriseId VARCHAR(32);
DECLARE oEnterpriseName VARCHAR(64);
BEGIN
SET autocommit = 0;
/* get the old variables */
SELECT
Enterprise_ID = oEnterpriseId,
Enterprise_Name = oEnterpriseName
FROM
enterprise
WHERE
Enterprise_ID = pEnterpriseId;
/* set the variables with the new inputs */
IF pEnterpriseName = NULL
SET nEnterpriseName = oEnterpriseName
ELSE IF pEnterpriseName = ''
SET oEnterpriseName = NULL
ELSE
SET nEnterpriseName = pEnterpriseName
UPDATE enterprise
SET
Enterprise_Name = nEnterpriseName
WHERE Enterprise_ID = pEnterpriseId;
COMMIT;
END $$
DELIMITER ;
There are some mistakes in the SP and it should be something like this
DELIMITER $$
DROP PROCEDURE IF EXISTS EditEnterprise
$$
CREATE PROCEDURE EditEnterprise(
IN pEnterpriseId VARCHAR(32),
IN pEnterpriseName VARCHAR(64)
)
BEGIN
/* declare the new variables */
DECLARE nEnterpriseId VARCHAR(32);
DECLARE nEnterpriseName VARCHAR(64);
/* declare the old variables */
DECLARE oEnterpriseId VARCHAR(32);
DECLARE oEnterpriseName VARCHAR(64);
SET autocommit = 0;
/* get the old variables */
SELECT
#oEnterpriseID := Enterprise_ID,
#oEnterpriseName := Enterprise_Name
FROM
enterprise
WHERE
Enterprise_ID = pEnterpriseId;
/* set the variables with the new inputs */
IF pEnterpriseName = NULL THEN
SET #nEnterpriseName = #oEnterpriseName;
ELSEIF pEnterpriseName = '' THEN
SET #oEnterpriseName = NULL;
ELSE
SET #nEnterpriseName = pEnterpriseName;
END IF;
UPDATE enterprise
SET
Enterprise_Name = nEnterpriseName,
Enterprise_Established_Date = nEnterpriseCreateDate,
Enterprise_Description = nEnterpriseDetails,
Enterprise_Type = nEnterpriseType,
Enterprise_Status = nEnterpriseStatus
WHERE Enterprise_ID = pEnterpriseId;
COMMIT;
END $$
DELIMITER ;
Some errors to point out
Its ELSEIF instead if ELSE IF for multiple conditions
After declaring a variable "DECLARE myvar VARCHAR(32)", we need to use := to assign values to it if we are not using the SET command.
In Mysql (which differs from Oracle), DECLARE goes after BEGIN
Your code should be:
DELIMITER $$
DROP PROCEDURE IF EXISTS EditEnterprise$$
CREATE PROCEDURE EditEnterprise(
IN pEnterpriseId VARCHAR(32),
IN pEnterpriseName VARCHAR(64)
)
BEGIN
/* declare the new variables */
DECLARE nEnterpriseId VARCHAR(32);
DECLARE nEnterpriseName VARCHAR(64);
/* declare the old variables */
DECLARE oEnterpriseId VARCHAR(32);
DECLARE oEnterpriseName VARCHAR(64);
SET autocommit = 0;
/* get the old variables */
SELECT
Enterprise_ID := oEnterpriseId,
Enterprise_Name := oEnterpriseName
FROM
enterprise
WHERE
Enterprise_ID = pEnterpriseId;
/* set the variables with the new inputs */
IF pEnterpriseName IS NULL THEN
SET nEnterpriseName = oEnterpriseName;
ELSEIF pEnterpriseName = '' THEN
SET oEnterpriseName = NULL;
ELSE
SET nEnterpriseName = pEnterpriseName;
END IF;
UPDATE enterprise SET
Enterprise_Name = nEnterpriseName
WHERE Enterprise_ID = pEnterpriseId;
COMMIT;
END$$
DELIMITER ;
I also added the missing ;, THEN and END IF keywords.
Also, take note that you might have a typo at this line:
SET oEnterpriseName = NULL;
You probably meant:
SET nEnterpriseName = NULL;
Now I think you should reconsider your stored procedure. Indeed, all this could be done in a single SQL query. Do you really need a stored procedure for this? Except if you have a restrictive grants policy it might just be superfluous.