getting wrong value of out param on mysql procedure - mysql

I created a procedure on mysql.
Here's my sql.
drop procedure if exists proc_serial_no;
DELIMITER //
CREATE PROCEDURE `proc_serial_no`(IN comp_code varchar(20), IN meat_rule_one varchar(20),OUT serial_no int)
LANGUAGE SQL
NOT DETERMINISTIC
MODIFIES SQL DATA
SQL SECURITY INVOKER
COMMENT 'serial no generator for trace code'
begin
declare current_no int default 0;
select serial_no into current_no from t_serial_no where comp_code = comp_code and rule = meat_rule_one;
if current_no = 0
then insert into t_serial_no (id,no,comp_code,rule) values ( replace(uuid(),'-',''),1,comp_code,meat_rule_one);
else update t_serial_no set no = no + 1 where comp_code = comp_code and rule = meat_rule_one;
end if;
select serial_no = current_no + 1;
end
I'm expecting the out param [serial_no] to increase every time I call the procedure,but it's always zero.
When I change sql related to the out param to
select no into serial_no from t_serial_no where comp_code = comp_code and rule = meat_rule_one;
It worked!
I could't figure out why. Anyone can answer this would be in great help!

This may be right or wrong. But it may be due to ,
Everytime you call the procedure , the local variable current_no is by its default value it is 0.
When the scope moves out of the procedure and again when you call that procedure, it again starts with its default value 0 again and again.
And also,
May be everytime you pass the value 0 to serial_no param everytime you call that procedure and it again starts with 0 everytime when the scope moves out and comes in.

Related

MySql syntax error on procedure parameter

I am trying to write a simple procedure but am encountering a syntax error at the first parameter. As best I can tell I'm following the syntax of CREATE PROCEDURE correctly.
I am limited to accessing my database with phpMyAdmin. Here is the create script I'm trying to run:
DROP PROCEDURE IF EXISTS product_index_swap/
CREATE PROCEDURE product_index_swap (#id INT, #oldIndex INT, #newIndex INT)
BEGIN
DECLARE #swapID;
SET #swapID = (SELECT `id` FROM `product` WHERE `order_index` = #newIndex LIMIT 1);
UPDATE `products` SET `order_index` = (CASE WHEN `id` = #id THEN #newIndex
WHEN `id` = #swapID THEN #oldIndex END)
WHERE `id` IN (#id, #swapID);
END
I am using the option on phpMyAdmin to change the delimiter to /.
I receive a syntax error "near '#id INT, #oldIndex INT....". I thought I may encounter more delimiter errors since I'm not entirely clear on the scope of them. I believe if that was the problem the error would be on a new line in the procedure when it failed to understand a semicolon, not at the parameters declaration.
You're using the Microsoft SQL Server convention of putting # before all the parameters and local variables. MySQL doesn't do this.
In MySQL syntax, procedure parameters have no sigil.
Also parameters are typically declared IN or OUT or INOUT.
CREATE PROCEDURE product_index_swap (IN id INT, IN oldIndex INT, IN newIndex INT)
BEGIN
DECLARE swapID;
...
MySQL variables that have the # sigil are session variables.
See also:
https://dev.mysql.com/doc/refman/5.7/en/create-procedure.html
https://dev.mysql.com/doc/refman/5.7/en/declare-local-variable.html
https://dev.mysql.com/doc/refman/5.7/en/set-variable.html
In MySQL, the #var variables are session level variables.
Use normal variables without the # and make sure you do not have conflict with column names:
CREATE PROCEDURE product_index_swap (in_id INT, in_oldIndex INT, in_newIndex INT)
BEGIN
DECLARE v_swapID int;
SELECT id into v_swapID
FROM product
WHERE order_index = in_newIndex
LIMIT 1;
UPDATE products
SET order_index = CASE WHEN id = in_id THEN in_newIndex
WHEN id = v_swapID THEN in_oldIndex
END
WHERE id IN (in_id, v_swapID);
END

error code 1414 in mysql when i am call store procedure

any body help me..
i am call sp not succses,
--==================================================================================
Query: call `sp_MasterDataPegawai`('','0123555','neni','P','001','001',1,'',null)
Error Code: 1414
OUT or INOUT argument 9 for routine #maninds_std_mwt.sp_MasterDataPegawai is not a variable or NEW pseudo-variable in BEFORE trigger
--==================================================================================
and this is my sp :
--==================================================================================
DELIMITER $$
USE `#maninds_std_mwt`$$
DROP PROCEDURE IF EXISTS `sp_MasterDataPegawai`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_MasterDataPegawai`(
IN p_IdPegawai CHAR(10),
IN NIK CHAR(10),
IN p_NamaLengkap VARCHAR(50),
IN p_JenisKelamin CHAR(1),
IN p_KdDivisi CHAR(3),
IN p_KdJabatan CHAR(3),
IN p_KdStatusAktif TINYINT(1),
IN p_status CHAR(1),
OUT OutputId VARCHAR(10)
)
BEGIN
/* ======Local variabel==========*/
DECLARE pLoc_TempIdPegawai VARCHAR(10);
DECLARE pLoc_TempIdPegawai_i INTEGER;
DECLARE i INTEGER;
DECLARE pLoc_KdTitle CHAR(2);
DECLARE pLoc_KdJenisPegawai CHAR(3);
/*===============================*/
IF p_JenisKelamin = 'L' THEN
SET pLoc_KdTitle = '01';
ELSE
SET pLoc_KdTitle = '02';
END IF;
SET pLoc_KdJenisPegawai = '001';
SELECT pLoc_TempIdPegawai = `IdPegawai`,COUNT(*) FROM `tbl_data_pegawai` WHERE `IdPegawai` = p_IdPegawai;
IF COUNT(*) = 0 THEN
SELECT pLoc_TempIdPegawai_i = MAX(RIGHT(`IdPegawai`,6)) FROM `tbl_data_pegawai` WHERE `IdPegawai` <> '7777777777';
IF pLoc_TempIdPegawai_i IS NULL THEN
SET pLoc_TempIdPegawai = CONCAT(p_JenisKelamin,pLoc_KdJenisPegawai,'000001');
ELSE
SET i = RIGHT(pLoc_TempIdPegawai_i,6) + 1;
SET pLoc_TempIdPegawai = CONCAT(p_JenisKelamin ,`fc_FormatNomor`(pLoc_KdJenisPegawai,3),fc_FormatNomor(i,6));
END IF;
INSERT INTO `tbl_data_pegawai`
(
`IdPegawai`,
`NIK`,
`KdTitle`,
`NamaLengkap`,
`JenisKelamin`,
`TempatLahir`,
`Alamat`,
`TglLahir`
)
VALUES
(
pLoc_TempIdPegawai,
p_NIK,
pLoc_KdTitle,
p_NamaLengkap,
p_JenisKelamin,
NULL,
NULL,
NULL
);
/*insert ke tabel tbl_data_current_pegawai */
INSERT INTO `tbl_data_current_pegawai`
(
`IdPegawai`,
`KdJenisPegawai`,
`KdJabatan`,
`KdDivisi`,
`KdAgama`,
`KdPendidikan`,
`StatusEnabled`
)
VALUES
(
pLoc_TempIdPegawai,
pLoc_KdJenisPegawai,
p_KdJabatan,
p_KdDivisi,
NULL,
NULL,
p_KdStatusAktif
);
SET OutputId = pLoc_TempIdPegawai;
-- else
IF UPPER(p_Status)= 'A' THEN
UPDATE `tbl_data_pegawai`
SET
`IdPegawai`=p_IdPegawai,
`KdTitle`=pLoc_KdTitle,
`NamaLengkap`=p_NamaLengkap,
`JenisKelamin`=p_JenisKelamin
WHERE `IdPegawai`=p_IdPegawai AND `KdTitle`=pLoc_KdTitle;
/* Update tbl_data_current_pegawai */
UPDATE `tbl_data_current_pegawai`
SET
`IdPegawai`=p_IdPegawai,
`KdJabatan`=p_KdJabatan,
`KdDivisi`=p_KdDivisi,
`StatusEnabled`=p_KdStatusAktif
WHERE `IdPegawai`=p_IdPegawai;
ELSE
DELETE FROM `tbl_data_pegawai` WHERE `IdPegawai`=p_IdPegawai;
DELETE FROM `tbl_data_current_pegawai` WHERE `IdPegawai`=p_IdPegawai;
SET OutputId = p_IdPegawai;
END IF;
END IF;
END$$
DELIMITER ;
--==================================================================================
how clear this error?
i am sorry because my english language not good.
thank you
When we specify the parameter as OUT or INOUT, the stored procedure should be able to operate on that parameter. So it expects the paramter to be a variable which the caller can use later. If we specify a VALUE, its not possible for the Stored Procedure to manipulate that value, thus it will throw an 1414 error.
We can pass values only for IN parameter of the Stored procedure.
So define a session variable and then send that variable as a parameter.
13.2.1 CALL Syntax
...
To get back a value from a procedure using an OUT or INOUT parameter,
pass the parameter by means of a user variable, and then check the
value of the variable after the procedure returns. (If you are calling
the procedure from within another stored procedure or function, you
can also pass a routine parameter or local routine variable as an IN
or INOUT parameter.)
...
Try:
-- call `sp_MasterDataPegawai`('','0123555','neni','P','001','001',1,'',null)
call `sp_MasterDataPegawai`('','0123555','neni','P','001','001',1,'',#`_OutputId`);
Need to call the parameters in mysql like this
call sp_MasterDataPegawai('','0123555','neni','P','001','001',1,'',#message);
select #message ;

Mysql UDF to return record id if exists else insert and return recordid`

I am trying to write a Mysql Function to return a contactID if the record exists based on the parameters supplied, If the record is not present, I am adding the record and then returning the contactID of the new record.
But the function is throwing 1048error, Can you check and correct me if I went wrong in writing this.
DELIMITER $$
CREATE DEFINER=`root`#`%` FUNCTION `GetContactID`(accountNumber CHAR(45),UserID INT(11)) RETURNS char(1) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE ContactID INT DEFAULT 0;
SELECT ContactID INTO #ContactID FROM Contact WHERE AccountNumber = #accountNumber AND UserID = #UserID AND Status =1;
IF ContactID = 0 or ContactID is null THEN
INSERT INTO Contact(AccountNumber,UserID) VALUES (#accountNumber,#UserID);
SELECT ContactID INTO #ContactID FROM Contact WHERE AccountNumber = #accountNumber AND UserID = #UserID;
END IF;
RETURN ContactID;
END
Can someone help me where I went wrong.
Thanks
The problem results from mixing user variables, local variables and parameters.
#UserId is not the same as UserId - they are different variables.
UserId is also a name of column in the table.
User defined variables are wirtten as #var_name, are stored in the user session and can be used to pass values between differend stored routines that reference them, see this link for details: http://dev.mysql.com/doc/refman/5.7/en/user-variables.html
local variables are declared in stored routines using DECLARE keyword, their scope is local within the stored routine, see this link for details: http://dev.mysql.com/doc/refman/5.7/en/declare-local-variable.html
Parameters of function/procedure - they are declared in the procedure/function declaration, they are used to pass parameters to the stored routine from the caller, can be also used to return results from the routine to the caller (if declared as OUT or INOUT). Their scope is similar to local variables. For details see this link: http://dev.mysql.com/doc/refman/5.7/en/create-procedure.html
Try this code:
DELIMITER $$
CREATE DEFINER=`root`#`%` FUNCTION `GetContactID`(p_accountNumber CHAR(45),p_UserID INT(11)) RETURNS char(1) CHARSET latin1
DETERMINISTIC
BEGIN
DECLARE v_ContactID INT DEFAULT 0;
SELECT ContactID INTO v_ContactID
FROM Contact
WHERE AccountNumber = p_accountNumber AND UserID = p_UserID AND Status =1;
IF v_ContactID = 0 or v_ContactID is null THEN
INSERT INTO Contact(AccountNumber,UserID)
VALUES (p_accountNumber,p_UserID);
SELECT ContactID INTO v_ContactID FROM Contact
WHERE AccountNumber = p_accountNumber AND UserID = p_UserID;
END IF;
RETURN v_ContactID;
END;
Notice that:
function parameters are declared with prefix p_
local variables are declared with prefix v_
the function doesn't use any user variables (prefixed by #)
These prefixes help to avoid ambiguity - we know that p_UserID is a parameter, v_UserId is a local variable, and UserID is a column name in the table (If we would use #UserId, we knew that this was the user variable).

Calling a stored procedure within an IF statement MySQL

Does anybody know if this is allowed?
IF CALL GET_RIGHT_NODE(edge) = 15
THEN
SELECT "IT WORKS";
I'm getting an error on this syntax, is it possible any other way?
The return values from stored procedures should be captured in OUT paramters (whereas those from user defined functions can be captured as #returnValue = function()).
So, your GET_RIGHT_NODE should take an OUT parameter and set it to the return value.
CREATE PROCEDURE GET_RIGHT_NODE
(
#edge INT,
#returnValue INT OUTPUT
)
AS
-- Definition of the proc.
then you would call the procedure as follows:
DECLARE #returnValue INT
CALL GET_RIGHT_NODE(#edge, #returnValue)
IF (#returnValue = 15)
THEN
SELECT 'IT WORKS'

Weird issue with a stored procedure in MySQL

I need to add a new stored procedure on our company's MySQL server. Since it's just slightly different, I used an already existing one, added the additional field and changed the name of the procedure. The weird thing now is that when I want to execute the statement, it returns:
Error Code: 1064. 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 '' at line 3
reffering to the 0 in this line: SET #update_id := 0; What makes it weird is, that I queried that stored procedure by using SHOW CREATE PROCEDURE . It's saved in our database and is working fine. I just can't use it as a new stored procedure (no matter if I try to apply it to the new test database or if I use it on the existing database by giving it a new name).
I searched the internet for a solution. Unfortunately to no avail. I even set up a new database with a new table and some demo values where I tried to execute the original, unaltered stored procedure. It returns the exact same error.
Here's the currently used and working stored procedure I'm talking about:
CREATE DEFINER=`root`#`localhost` PROCEDURE `customer_getcard`(IN Iinstance INT, IN Itimebuy DOUBLE, IN Iprice DECIMAL(10,2), IN Itariff INT, IN Icomment VARCHAR(128))
BEGIN
SET #update_id := 0;
UPDATE customer_shop SET state = 1, id = (SELECT #update_id := id), instance=Iinstance, timebuy=Itimebuy, price=Iprice, comment=Icomment WHERE tariff=Itariff AND state = 0 LIMIT 1;
SELECT * FROM customer_shop WHERE id = #update_id;
END
I hope you guys can help me as I am completely out of ideas what's wrong. :/
Regards, Mark
You need to define an alternative command delimiter, as MySQL currently thinks your CREATE PROCEDURE command ends at the first ; it encounters (on line 3, after the 0), which would be a syntax error as it's after a BEGIN but before the corresponding END:
DELIMITER ;; -- or anything else you like
CREATE PROCEDURE
...
END;; -- use the new delimiter you chose above here
DELIMITER ; -- reset to normal
MySQL stored procedures do not use ":=" for value assignment, just use "=".
Also don't think "id = (SELECT #update_id := id)" is acceptable. Here's an alternative solution (untested):
CREATE DEFINER=`root`#`localhost` PROCEDURE `customer_getcard`(IN Iinstance INT, IN Itimebuy DOUBLE, IN Iprice DECIMAL(10,2), IN Itariff INT, IN Icomment VARCHAR(128))
BEGIN
select id into #update_id from customer_shop WHERE tariff=Itariff AND state = 0 LIMIT 1;
UPDATE customer_shop SET state = 1, instance=Iinstance, timebuy=Itimebuy, price=Iprice, comment=Icomment where id = #update_id;
SELECT * FROM customer_shop WHERE id = #update_id;
END
You may also want to put error handlers in case there's no matching row to be edited.