Im trying to write a procedure, but in my #qr2 the CONCAT gets escaped when i pass the arg for the substring_index().
Any idea how i can pass the '-' into the function, without having it escaping the CONCAT function??
I have tried using "'-'" or \'-\' but nothing works, it keeps escaping it.
DELIMITER //
CREATE PROCEDURE filter_bar (IN bar_state VARCHAR(20), done_state VARCHAR(20))
BEGIN
set #qr1 = CONCAT('CREATE TABLE ', done_state, ' like ', bar_state, ';');
PREPARE smt from #qr1;
EXECUTE smt;
DEALLOCATE smt;
set #qr2 = CONCAT('UPDATE ', bar_state, ' SET date = SUBSTRING_INDEX(date,'-',-1);');
PREPARE smt from #qr2;
EXECUTE smt;
DEALLOCATE smt;
set #qr3 = CONCAT('INSERT into', done_state,'select name, business_id, date, sum(count) as count from', bar_state,' group by name, business_id, date;');
PREPARE smt from #qr3;
EXECUTE smt;
END //
You could use '':
set #qr2=CONCAT('UPDATE ',bar_state,' SET date=SUBSTRING_INDEX(date,''-'',-1);');
You also need a space:
set #qr3 = CONCAT('INSERT into', done_state,' select name, business_id, date, ...'
-- here
And finally:
DEALLOCATE smt;
=>
DEALLOCATE PREPARE smt;
DBFiddle Demo
EDIT:
To avoid problems with SQL Injection you should wrap each occurrence of identifier with quoting:
The quote_identifier() Function
Given a string argument, this function produces a quoted identifier suitable for inclusion in SQL statements. This is useful when a value to be used as an identifier is a reserved word or contains backtick (`) characters.
bar_state
=>
sys.quote_identifier(bar_state)
done_state
=>
sys.quote_identifier(done_state)
Related
I have a stored procedure like the following:
CREATE PROCEDURE `proc_getNames`(
iName varchar(255)
)
BEGIN
SET #sql = CONCAT('
select distinct Name, Age, Grade, Class from tblStudents
where Name in (', iName, ')
');
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END
I'm calling the SP like below and getting the data:
CALL `db_datauniverse`.`proc_getNames` ('\'smith\',\'john\',\'doe\'');
My question is how can I pass this kind of a value via code (like node.js).
I tried to pass comma(,) separated values like 'smith,john,doe', but it didn't work.
Could you please help me with the correct structure to pass to SP?
I just had to prepare a string like the following: "'smith','john','doe'".
Wrap every element with quotes and join them with ','.
I have a comma separated string variable v_combined_prodid .
But i wants to convert comma separated string variable to comma separated int value or in loop where we can update one table with where clause prodid as int.
we cant use FIND_IN_SET(prodid, v_combined_prodid )
we can use stored procedure.
DECLARE v_combined_prodid varchar(800);
set v_combined_prodid ='1,2,3,4,5';
below statement exactly requirement.
update mytable t set t.status=2
WHERE prodid in (1,2,3,4,5)
and t.status=0 ;
You are better off creating a dynamic query and then execute it.
See Mysql dynamically build query string in a stored procedure based on logic for an example.
DECLARE v_combined_prodid varchar(800);
set v_combined_prodid ='1,2,3,4,5';
set #query = CONCAT(' update mytable t set t.status = 2 where prodid in ('
, v_combined_prodid
, ') and t.status = 0');
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
I'm trying a simple update using a stored proc using data from a web service but it is failing saying Unknown column 'USERNAME' in 'field list' due to the single quotes not being recognised in the stored proc.
BEGIN
UPDATE PYBUsers set IsMember = 1 where user = p_user;
END
as you can see the p_user is supplied but the web service and does not have single quotes so gets rejected. I have also tried
SET #query = CONCAT('UPDATE PYBUsers set IsMember = 1 where user = \'', p_user, '''');
and
SET #query = CONCAT('UPDATE PYBUsers set IsMember = 1 where user = ', "'",p_user,"'");
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt
but no luck. is there an easy solution that I'm missing?
Try
SET #query = CONCAT('UPDATE PYBUsers set IsMember = 1 where user = ''',p_user,'''');
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt
To add a single quotes into a string you have to put two single quotes together i.e.
'This is Dan''s string; Single quote is inserted between the n and s
''''; this one is a little awkward to read, but here goes. The first quote opens the string, the next two quotes generate a single quote in the string. The final quote closes the string.
INSERT INTO myTable values ('''')
The above would result in one quote being stored in the table
i have tried to create MySQL store procedure in that i want to make dynamic query.
code on which i working..
DELIMITER $$
DROP PROCEDURE IF EXISTS `test`.`selectp` $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `selectp`(in a_str_Condition varchar(500))
BEGIN
SET #Query = 'SELECT * from test123';
IF a_str_Condition != ''
THEN
SET #strCondition = CONCAT(' WHERE ? ');
SET #param = a_str_Condition;
ELSE
SET #strCondition = ' Order by aaa desc';
END IF
SET #Query = CONCAT(#Query, #strCondition );
PREPARE stmt FROM #Query;
EXECUTE stmt USING #param;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
here i want pass parameter as aaa = 3 and concat it with mysql query, but it show me error as below.
please let me clear on this store procedure. Any help will be Appreciate.
Trying to answer to your ...what is wrong with MySQL select Store Procedure..?
As others mentioned you have ; missing. That only solves a syntax error.
But you have bigger problems with the way you try to construct your query and EXECUTE it:
You're incorrectly trying to treat all where conditions as one parameter with WHERE ?, instead of parameterizing values like WHERE id = ?
In case you don't pass a condition you can't use USING in EXECUTE. It'll fail.
Now since you don't execute your query multiple times, you pass conditions as a string anyway, and it seems that you're more after flexibility than security, IMHO there is no much sense in using parameters here.
That being said a more succinct version of your SP might look like this
DELIMITER $$
CREATE PROCEDURE selectp(IN _conditions VARCHAR(500), IN _orderby VARCHAR(500))
BEGIN
SET #sql = CONCAT(
'SELECT * FROM test123 WHERE 1 = 1',
COALESCE(CONCAT(' AND ', NULLIF(_conditions, '')), ''),
' ORDER BY ',
COALESCE(NULLIF(_orderby, ''), 'id DESC')
);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
Usage examples:
-- default parameters either with null or an empty string
CALL selectp('', '');
CALL selectp(NULL, NULL);
-- set where conditions
CALL selectp('id IN(1, 3)', NULL);
-- set order by
CALL selectp(NULL, 'col1 DESC, col2');
Here is SQLFiddle demo
You've lost a semicolon after END IF.
And that's what mysql is pointed you to - it always shows you the expression part it couldn't parse. So always look at the code right before the one from the error description.
There should be a semi column after the END IF statement:
ELSE
SET #strCondition = ' Order by aaa desc';
END IF; //add semicolumn here
Before this line:
SET #Query = CONCAT(#Query, #strCondition );
I'm trying to pass a table name into my mysql stored procedure to use this sproc to select off of different tables but it's not working...
this is what I"m trying:
CREATE PROCEDURE `usp_SelectFromTables`(
IN TableName varchar(100)
)
BEGIN
SELECT * FROM #TableName;
END
I've also tried it w/o the # sign and that just tells me that TableName doesn't exist...which I know :)
SET #cname:='jello';
SET #vname:='dwb';
SET #sql_text = concat('select concept_id,concept_name,',#vname,' from enc2.concept a JOIN enc2.ratings b USING(concept_id) where concept_name like (''%',#cname,'%'') and 3 is not null order by 3 asc');
PREPARE stmt FROM #sql_text;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
An extra bit that caused me problems.
I wanted to set the table name and field dynamically in a query as #kyle asked, but I also wanted to store the result of that query into a variable #a within the query.
Instead of putting the variable #a into the concat literally, you need to include it as part of the string text.
delimiter //
CREATE PROCEDURE removeProcessed(table_name VARCHAR(255), keyField VARCHAR(255), maxId INT, num_rows INT)
BEGIN
SET #table_name = table_name;
SET #keyField = keyField;
SET #maxId = maxId;
SET #num_rows = num_rows;
SET #sql_text1 = concat('SELECT MIN(',#keyField,') INTO #a FROM ',#table_name);
PREPARE stmt1 FROM #sql_text1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
loop_label: LOOP
SET #sql_text2 = concat('SELECT ',#keyField,' INTO #z FROM ',#table_name,' WHERE ',#keyField,' >= ',#a,' ORDER BY ',#keyField,' LIMIT ',#num_rows,',1');
PREPARE stmt2 FROM #sql_text2;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
...Additional looping code...
END LOOP;
END
//
delimiter ;
So in #sql_text1 assign the result of the query to #a within the string using:
') INTO #a FROM '
Then in #sql_text2 use #a as an actual variable:
,' WHERE ',#keyField,' >= ',#a,' ORDER BY '
It depends on the DBMS, but the notation usually requires Dynamic SQL, and runs into the problem that the return values from the function depend on the inputs when it is executed. This gives the system conniptions. As a general rule (and therefore probably subject to exceptions), DBMS do not allow you to use placeholders (parameters) for structural elements of a query such as table names or column names; they only allow you to specify values such as column values.
Some DBMS do have stored procedure support that will allow you to build up an SQL string and then work with that, using 'prepare' or 'execute immediate' or similar operations. Note, however, that you are suddenly vulnerable to SQL injection attacks - someone who can execute your procedure is then able to control, in part, what SQL gets executed.