the query works and updates as it supposed to, but when I tried to make it into a stored procedure, it fails with "error near WHERE". Can anyone see what is wrong please?
DELIMITER //
DROP procedure if exists update_trans_with_tags//
CREATE PROCEDURE update_trans_with_tags()
BEGIN
UPDATE transactions
SET trans_cat = CASE WHEN trans_desc LIKE '%abc%' THEN 1
WHEN trans_desc LIKE '%def%' THEN 2
WHEN trans_desc LIKE '%ghi%' THEN 4
ELSE trans_cat
END;
WHERE trans_cat IS NULL;
END//
DELIMITER ;
Take the ; off of the first END; ; still terminates statements within the stored procedure. If the hanging WHERE didn't prevent you from saving the procedure; the "first" statement would UPDATE all transactions.
Related
Consider the following stored procedure and its usage:
DROP PROCEDURE IF EXISTS ShowMIHoles;
DELIMITER $$
CREATE PROCEDURE ShowMIHoles(IN CourseID VARCHAR(255))
BEGIN
select * from tblcourses where id=CourseID;
END $$
DELIMITER ;
call ShowMIHoles(1299)
That works, and returns the row of table tblcourses with id 1299.
However, it isn't protected from SQL injection.
So, I read that quote() should be used to make a value safe.
This is my attempt to use quote:
DROP PROCEDURE IF EXISTS ShowMIHoles;
DELIMITER $$
CREATE PROCEDURE ShowMIHoles(IN CourseID VARCHAR(255))
BEGIN
select * from tblcourses where id=quote(CourseID);
END $$
DELIMITER ;
call ShowMIHoles(1299)
That results in "0 rows returned". No error message. MySQL 5.7.28.
I tried various tests to see what was going wrong. The ones that don't use CourseID parameter, I tested both inside procedure, and as a stand-alone query.
select quote(1299);
=> '1299'
select * from tblcourses where id='1299';
=> The expected row with id 1299.
select * from tblcourses where id=quote(1299);
=> 0 rows returned.
It is possible to make this work, via prepared statement:
...
BEGIN
SET #sql = CONCAT('select * from tblcourses where id=', quote(CourseID));
prepare stmt from #sql;
execute stmt;
END $$
...
=> The expected row with id 1299.
Question:
Is there any way to safely use this parameter as an expression value in the where clause, without dynamically preparing a statement?
You do not need to worry about SQL injection inside a stored procedure unless you are using dynamic SQL. Strings will always be treated like whole string and numbers as numbers.
So, the first version you are showing is perfectly fine. Just make sure that when you call the procedure, your code is safe.
I'm using sybase powerbilder12 IDE and mySQL.
I have a stored procedure like this:
DELIMITER //
CREATE PROCEDURE CRTempTable(IN loc_code CHAR(6))
BEGIN
create temporary table mstparameter (select * from mstparameter_consolidate where location_code = 'loc_code');
END//
DELIMITER ;
I'm calling it in the powerbuilder12 like this:
DECLARE TempTBCRCall PROCEDURE FOR TempTableCR
location_code = :gs_location_code_mstparameter ;
execute TempTBCRCall;
It gives me the error :
Stored procedure execution failure1054 SQLSTATE = S0022
[MySQL][ODBC 5.2(a) Driver][mysqld-5.5.25a]Unknown column
'location_code' in 'field list'... Error Code 0
but location_code is there in my mstparameter_consolidate table.
If I set to enter the location_code manually it works fine.
This is an example that works, I hope it helps you.
DECLARE pb_acceso_usuario PROCEDURE FOR SP_ACCESO_VALIDA_DATOS_USUARIO (:gs_cod_usuario,:ls_password);
execute pb_acceso_usuario;
if SQLCA.sqlcode = 0 then
FETCH pb_acceso_usuario INTO :ln_count,:gs_des_usuario,:ls_estado;
CLOSE pb_acceso_usuario;
end if
try putting "table-name." in front of the column-name.
I have the next SQL code:
DELIMITER $$
CREATE PROCEDURE `test`.`new_procedure` (queryString VARCHAR(255))
BEGIN
SELECT #tempValue = COUNT(*) FROM test.userdata_extended WHERE inn LIKE queryString;
IF #tempValue > 0 SELECT * FROM test.userdata_extended WHERE inn LIKE queryString;
END $$
I'm putting the COUNT* result into #tempValue variable.
Then I'm trying to compare it for being greater than zero.
I'm getting error with the statement comparing process. MySQL reports me a UNEXPECTED SELECT SYM error. What does it mean?
Also this would be a check for another tables. I need IF-ELSE statements, because basing on several query result my procedure must return the exact code error value (which could be different) for the my developed application to handle or giving the data, if all is fine.
How to fix this issue?
Thanks
You have forgot the THEN in your if statement. You need to add the THEN.
Like this:
IF #tempValue > 0 THEN ...your statement
END IF;
You have also forgot to add the END IF; add this also.
Reference site is here.
You forgot THEN and END IF;
IF #tempValue > 0 THEN
SELECT * FROM test.userdata_extended WHERE inn LIKE queryString;
END IF;
I am new to mysql and I cant see why I have an error when I create my stored procedure.
DELIMITER |
CREATE PROCEDURE lastscan(IN task_id_var INT)
BEGIN
SELECT COUNT(*) FROM debugger WHERE task_id=task_id_var INTO #total|
SET #total=#total+1|
INSERT INTO debugger SET scan_num=#total, task_id=task_id_var|
END|
DELIMITER;
I get :
#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
I also dont get, why do I need to use that delimiter syntax.. ? DELIMITER | and then again DELIMITER;...what its function
DELIMITER |
CREATE PROCEDURE lastscan(IN task_id_var INT, IN file_name_var VARCHAR(110))
BEGIN
SELECT COUNT(*) FROM debugger WHERE task_id=task_id_var INTO #total;
SET #total=#total+1;
INSERT INTO debugger SET scan_num=#total, task_id=task_id_var, file_name=file_name_var;
END|
DELIMITER;
This works for me. no need to put | delimiter in sored procedure. I think it is meant to be for the stored procedure and not for what is inside the body
You can't simply assign variables like that, you need the SET keyword first.
http://dev.mysql.com/doc/refman/5.1/en/set-statement.html
So you code should be something like this (tested with phpMyAdmin):
DELIMITER //
CREATE PROCEDURE lastscan(IN task_id_var INT)
BEGIN
SELECT COUNT(*) FROM debugger WHERE task_id=task_id_var INTO #total;
SET #total=#total+1;
INSERT INTO debugger SET scan_num=#total, task_id=task_id_var;
END;//
DELIMITER ;
The DELIMITER keyword is used to stop additional semicolons in your procedure to be the end of the current statement, so by redefining the delimiter to // MySql will process the whole CREATE PROCEDURE-block as one single statement and not stop at the first semicolon but instead wait for the first occurrence of //.
http://dev.mysql.com/doc/refman/5.1/en/stored-programs-defining.html
I used MSSQL stored procedures and triggers for a while; MySQL is getting me absolutely crazy about how to write even the simpler procedure.
Why I get a syntax error in this so stuoid trigger?
CREATE TRIGGER set_prio_default BEFORE INSERT ON categories
FOR EACH ROW
BEGIN
set #my_prio := 1;
SET new.prio := #my_prio;
END
In facts this TRIGGER is an oversemplification of:
DELIMITER $$
DROP PROCEDURE IF EXISTS `slot08`.`test` $$
CREATE PROCEDURE `slot08`.`test` ()
BEGIN
select 1 + max(prio) from categories INTO #my_prio;
select #my_prio;
END $$
DELIMITER ;
Still i do not understand how to use variables in procedures. If I use a DECLARE statement and the variable name miss the # character I got an error from mysql telling me "unknown system variable" - but many examples I saw used this syntax
I mean:
this does not work
CREATE TRIGGER set_prio_default BEFORE INSERT ON categories
FOR EACH ROW
BEGIN
declare my_prio integer default 1;
set my_prio := 1;
SET new.prio := my_prio;
END
If I use # I get syntax error.
Have some hints?
Thanks!
I dont think you have to use the := operator. A simple equals will do. All variables declared inside the stored procedure must be prefixed with the #symbol.
Hey, found the answer. Hope that people with so little experience as me in MySQL procedures could avoid to spend the time I have spent on the same issue. This does work:
DELIMITER $$
CREATE TRIGGER blablabla
BEFORE INSERT ON myStupidTable
FOR EACH ROW
BEGIN
declare my_prio integer;
select 1 + max(prio) from myStupidTable INTO my_prio;
SET new.prio := my_prio;
END $$
DELIMITER ;
It seems that the MySQL syntax errors experienced so far were a delimiter issue.
Greetings
Daniel