sql if-else procedure prob, cant create procedure - mysql

delimiter//
create procedure exercise(out stat char(10),out fee double)
begin
if stat=='AC executive' then set fee=100;
else if stat=='AC Economi' then set fee=50;
else set saldo=20;
end if;
end//
delimiter;

Your if-else if is not correct it should be
if condition then do something
elseif condition then do something
else do something
There is no space between elseif. Also I suppose you mean fee not saldo in the else part. And out stat char(10) should be in stat varchar(100), since you are using the param as input
delimiter //
create procedure exercise(in stat varchar(100),out fee double)
begin
if stat ='AC executive' then set fee=100;
elseif stat = 'AC Economi' then set fee=50;
else set fee=20;
end if;
end;//
delimiter;
Here is a test on mysql
mysql> delimiter //
mysql> create procedure exercise(in stat varchar(100),out fee double)
-> begin
-> if stat ='AC executive' then set fee=100;
-> elseif stat = 'AC Economi' then set fee=50;
-> else set fee=20;
-> end if;
-> end;//
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call exercise('AC executive',#o);
Query OK, 0 rows affected (0.00 sec)
mysql> select #o ;
+------+
| #o |
+------+
| 100 |
+------+
1 row in set (0.00 sec)

Related

Mysql Error #1064 near Null in call stored procedure with out param

I'm quite new with MySQL. I have to call a stored procedure with output param. I've searched a lot on internet but I've not found the correct solution to my problem. If I call the stored procedure with the #outputParamName it says that I have an error #1064 near NULL. If I call the procedure with the 'outputParamName' without the # it says thath it is not an OUT or INOUT correct param. Someone can help me please?
the stored procedure just have to check if surname and name in DB exists on the same row:
CREATE PROCEDURE InsertProc (INOUT existsInDb BOOLEAN,
IN dbName VARCHAR(50)
IN tableName VARCHAR(50)
IN surnameNew VARCHAR(50)
IN nameNew VARCHAR(50))
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
DECLARE rowSurnameName int;
SET #sqlSel = CONCAT('SELECT COUNT(*) INTO ', rowSurnameName, ' FROM ', dbName, '.', tableName, ' WHERE COGNOME=', surnameNew, ' AND NOME=', nameNew);
PREPARE stmtSel FROM #sqlSel;
EXECUTE stmtSel;
DEALLOCATE PREPARE stmtSel;
IF (rowSurnameName=0) THEN
SET #sqlIns = CONCAT('INSERT INTO ', dbName, '.', tableName, ' (NOME, COGNOME) VALUES (', nameNew, ', ', surnameNew,')');
PREPARE stmtIns FROM #sqlIns;
EXECUTE stmtIns;
DEALLOCATE PREPARE stmtIns;
SELECT false INTO existsInDb;
ELSE SELECT true INTO existsInDb;
END IF;
END
The CALL Statement is:
SET #dbName = 'DBNAME';
SET #tableName = 'DBTABLE';
SET #surname = 'SURNAME';
SET #name = 'NAME';
PREPARE s FROM 'CALL InsertProc(?,?,?,?,?)';
EXECUTE s USING #existsInDB, #dbName, #tableName, #surname, #name;
SELECT #existsInDB;
And the ERROR Line is:
#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 'NULL' at line 1
A couple of notes:
You can't use a local variable in a prepared statement.
C.1 Restrictions on Stored Programs
...
SELECT ... INTO local_var cannot be used as a prepared statement.
...
The error shown in your question occurs because the local variable rowSurnameName has the value NULL, see:
mysql> DROP PROCEDURE IF EXISTS `InsertProc`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DELIMITER //
mysql> CREATE PROCEDURE `InsertProc`()
-> BEGIN
-> DECLARE `rowSurnameName` INT;
-> SELECT `rowSurnameName`;
-> SET #`sqlSel` := CONCAT('SELECT COUNT(*) INTO ', `rowSurnameName`);
-> SELECT #`sqlSel`;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL `InsertProc`;
+------------------+
| `rowSurnameName` |
+------------------+
| NULL |
+------------------+
1 row in set (0.00 sec)
+-----------+
| #`sqlSel` |
+-----------+
| NULL |
+-----------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
If you try to use the rowSurnameName local variable in the prepared statement, you will get the error:
mysql> DROP PROCEDURE IF EXISTS `InsertProc`;
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER //
mysql> CREATE PROCEDURE `InsertProc`()
-> BEGIN
-> DECLARE `rowSurnameName` INT;
-> SET #`sqlSel` := CONCAT('SELECT 100 INTO `rowSurnameName`');
-> SELECT #`sqlSel`;
-> PREPARE `stmtSel` FROM #`sqlSel`;
-> EXECUTE `stmtSel`;
-> DEALLOCATE PREPARE `stmtSel`;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL `InsertProc`;
+----------------------------------+
| #`sqlSel` |
+----------------------------------+
| SELECT 100 INTO `rowSurnameName` |
+----------------------------------+
1 row in set (0.00 sec)
ERROR 1327 (42000): Undeclared variable: rowSurnameName
You need to use 9.4 User-Defined Variables in your prepared statement:
mysql> DROP PROCEDURE IF EXISTS `InsertProc`;
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER //
mysql> CREATE PROCEDURE `InsertProc`()
-> BEGIN
-> SET #`sqlSel` := CONCAT('SELECT 100 INTO #`rowSurnameName`');
-> SELECT #`sqlSel`;
-> PREPARE `stmtSel` FROM #`sqlSel`;
-> EXECUTE `stmtSel`;
-> DEALLOCATE PREPARE `stmtSel`;
-> IF (#`rowSurnameName` = 0) THEN
-> SELECT 'NotExistsInDbAndInsert';
-> ELSE
-> SELECT 'existsInDb';
-> END IF;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL `InsertProc`;
+-----------------------------------+
| #`sqlSel` |
+-----------------------------------+
| SELECT 100 INTO #`rowSurnameName` |
+-----------------------------------+
1 row in set (0.00 sec)
+------------+
| existsInDb |
+------------+
| existsInDb |
+------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)

setting variable in case of exception

I have a stored procedure which will set my customized error as well as set an out variable to some value . I tried the following procedure .
***delimiter //
drop procedure if exists test_dalpu //
create procedure test_dalpu(out out_value int)
begin
DECLARE EXIT HANDLER FOR SQLSTATE '22001'
BEGIN
set out_value = 1;
SIGNAL SQLSTATE '22001' SET
MYSQL_ERRNO = 2,
MESSAGE_TEXT = 'Too long ';
END;
insert into abc_test values ( 5,"eerrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr");***
end//
delimiter ;
Then after executing
**call test_dalpu(#out_value);**
I got the correct output as Error code 2 Too long as expected, But after that If I do
select #out_value;
Am getting the value as null instead of 1 .
Is it the correct way?
Try:
mysql> DROP PROCEDURE IF EXISTS `test_dalpu`;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS `abc_test`;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE IF NOT EXISTS `abc_test` (
-> `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
-> `description` CHAR(10)
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER //
mysql> CREATE PROCEDURE `test_dalpu`(`out_value` VARCHAR(64))
-> BEGIN
-> DECLARE EXIT HANDLER FOR SQLSTATE '22001'
-> BEGIN
-> ROLLBACK;
-> SET #`set_variable` := CONCAT('SET #`', `out_value`, '` := 1');
-> PREPARE `stmt` FROM #`set_variable`;
-> EXECUTE `stmt`;
-> DEALLOCATE PREPARE `stmt`;
-> SIGNAL SQLSTATE '22001' SET
-> MYSQL_ERRNO = 2,
-> MESSAGE_TEXT = 'Too long';
-> END;
-> START TRANSACTION;
-> INSERT INTO `abc_test`
-> (`description`)
-> VALUES
-> ('ABCDEFGHIJK');
-> COMMIT;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> SET #`out_value` := NULL;
Query OK, 0 rows affected (0.00 sec)
mysql> CALL `test_dalpu`('out_value');
ERROR 2 (22001): Too long
mysql> SHOW WARNINGS;
+-------+------+----------+
| Level | Code | Message |
+-------+------+----------+
| Error | 2 | Too long |
+-------+------+----------+
1 row in set (0.00 sec)
mysql> SELECT #`out_value`;
+--------------+
| #`out_value` |
+--------------+
| 1 |
+--------------+
1 row in set (0.00 sec)

how programming a business rule on a trigger in mysql

I'm trying to programm a business rule in a trigger using MySQL, but it doesn't work.
What I want to do is that if the condition is false then the insert must fail and rollback it. The problem is that MySQL doesn't permit using rollback inside a trigger.
I've also tried to use SIGNAL and text message but it fails.
The code is:
CREATE TRIGGER tr_NewTeacher
AFTER INSERT ON teachers FOR EACH ROW
BEGIN
IF (salary > 1300 AND budget < 15000)
BEGIN
ROLLBACK TRANSACTION;
END
END
In MySQL trigger will rollback transaction if it fails.
So, you must raise exception within trigger body:
...
if [Test]
then
SIGNAL sqlstate '45001' set message_text = "No way ! You cannot do this !";
end if ;
...
You should be using before insert and for getting the column values you need to use new
So the trigger would be as
delimiter //
create trigger tr_NewTeacher before insert on teacher
for each row
begin
if new.salaRY>1300 AND new.budget<15000 then
signal sqlstate '45000' set message_text = 'Your error message';
end if;
end;//
delimiter ;
Here is a test case in mysql
mysql> create table teacher (id int auto_increment primary key,salaRY int , budget int);
Query OK, 0 rows affected (0.17 sec)
mysql> delimiter //
mysql> create trigger tr_NewTeacher before insert on teacher
-> for each row
-> begin
-> if new.salaRY>1300 AND new.budget<15000 then
-> signal sqlstate '45000' set message_text = 'Your error message';
-> end if;
-> end;//
Query OK, 0 rows affected (0.14 sec)
mysql> insert into teacher (salaRY,budget) values (1200,16000);
Query OK, 1 row affected (0.04 sec)
mysql> insert into teacher (salaRY,budget) values (1400,13000);
ERROR 1644 (45000): Your error message
mysql> select * from teacher ;
+----+--------+--------+
| id | salaRY | budget |
+----+--------+--------+
| 1 | 1200 | 16000 |
+----+--------+--------+
1 row in set (0.00 sec)

MYSQL stored procedure not checking the where clause and returning entire table

CREATE DEFINER=`root`#`localhost` PROCEDURE `Viewuser`(IN `userID` VARCHAR(50))
BEGIN
SELECT * FROM `tbl_userdetails` WHERE `UserID`=userID;
END
In the above code the user details of given user id should be return. But it returning the entire table while i execute this stored procedure.
try this method:
mysql> delimiter //
mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
-> BEGIN
-> SELECT COUNT(*) INTO param1 FROM t;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> CALL simpleproc(#a);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT #a;
+------+
| #a |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
https://dev.mysql.com/doc/refman/5.5/en/create-procedure.html
Got the answer. The field name in table should not be same as variable name.. That is the problem
CREATE DEFINER=root#localhost PROCEDURE Viewuser(IN ID VARCHAR(50))
BEGIN
SELECT * FROM tbl_userdetails WHERE UserID=ID;
END
This is working fine

mySQL Stored Procedure for splitting strings by delimiter

I'm into writing a stored procedure which explodes a passed string by a
passed delimiter and returns the n-th element of the result. n is passed
too.
So this is what I came up with:
CREATE PROCEDURE SPLIT(IN strToSplit text, IN strDelimiter varchar(1), IN nPartToGet int,OUT strSlice varchar(255))
BEGIN
SET strSlice = replace(substring(substring_index(strToSplit, strDelimiter, nPartToGet),
length(substring_index(strToSplit,strDelimiter, nPartToGet - 1)) + 1), strDelimiter, '')
END
;
Sadly mysql keeps naging me that I've got an syntax error in there. IMHO this should work. Could anyone pls poke me on where I'm going wrong?
thanks in advance
K
You need to end your SET with a ';' and, given that the client interprets ; as the delimiter, you need to change the delimiter so you can enter an actual ; into the procedure.
mysql> delimiter //
mysql> CREATE PROCEDURE SPLIT(IN strToSplit text, IN strDelimiter varchar(1), IN nPartToGet int,OUT strSlice varchar(255))
-> BEGIN
-> SET strSlice = replace(substring(substring_index(strToSplit, strDelimiter,
-> nPartToGet), length(substring_index(strToSplit,strDelimiter,
-> nPartToGet - 1)) + 1), strDelimiter, '');
-> END
-> //
Query OK, 0 rows affected (0.01 sec)
mysql> delimiter ;
mysql> CALL SPLIT('1;2;3;4;5',';',3,#str);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT #str;
+------+
| #str |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
Relevant docs: http://dev.mysql.com/doc/refman/5.0/en/stored-routines.html