Need help with MySQL query - mysql

I am trying to execute the following query statement contained within a Stored Procedure -
Where all P... are parameters to SP (ex PInitialDateFrom).
SET #stmt_text = CONCAT('SELECT AccountID, Firstname as ClientName, EmailID
, ProductID, InitialPurchaseDate as Purchasedate
FROM client_account
WHERE IsRemoved = 0
AND (InitialPurchasedate between ? and ?)
AND ProductId IN (?)');
PREPARE stmt FROM #stmt_text;
SET #initDt1=PInitialDateFrom, #initDt2 = PInitialDateTo, #inlist=PIDs
, #stmt_text = null;
EXECUTE stmt USING #initDt1, #initDt2, #inlist;
DEALLOCATE PREPARE stmt;
I am passing PID's as a string of ids like 1,2,3
When I try to execute the statement, only the first id is considered. For ex. 1,2,3 is used only 1 is taken, if 3,2,1 is used only 3 is taken.
Can anybody tell what's wrong with this query?

You can't use this part:
and ProductId in (?)
Remember: SQL parameters are not like C macros where you are just doing string replacements. They are more than thar: When you use ?, one and only one parameter gets bound. So, when you try to bind 1,2,3 to that parameter, it's not like you are trying to bind three values but only one.
If your list is going to be of fixed size, you could use:
and ProductId in (?,?,?)
Otherwise, I don't think you will be able to use parameters for that clause. Maybe doing something like:
set #initDt1=PInitialDateFrom,
#initDt2 = PInitialDateTo,
#inlist=PIDs,
#stmt_text = null;
set #stmt_text =
concat('Select AccountID, Firstname as ClientName, EmailID, ProductID
, InitialPurchaseDate as Purchasedate from client_account
where IsRemoved=0 and (InitialPurchasedate between ? and ?)
and ProductId in (', #inlist, ')');
prepare stmt from #stmt_text;
execute stmt using #initDt1, #initDt2;
deallocate prepare stmt;
Make sure you sanitize your input for PIDs so you don't add SQLInjection vulnerabilities to your code.

You should put it like this:
and ProductID = (?)
I hope it works.

Related

MySQL - create a table with all of the fields that two tables have [duplicate]

I have to convert a MSSQL stored proc that passes a varchar that is a query:
INSERT INTO Results
EXEC (#Expresion);
This isn't working. I'm pretty sure that EXEC and EXECUTE aren't MySQL commands, but CALL doesn't work either.
Does anyone know if it's even possible to have something like JavaScript's eval function for MySQL?
I think you're looking for something like this:
SET #queryString = (
SELECT CONCAT('INSERT INTO user_group (`group_id`,`user_id`) VALUES ', www.vals) as res FROM (
SELECT GROUP_CONCAT(qwe.asd SEPARATOR ',') as vals FROM (
SELECT CONCAT('(59,', user_id, ')') as asd FROM access WHERE residency = 9
) as qwe
) as www
);
PREPARE stmt FROM #queryString;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET #asd = NULL;
This is the SQL equivalent of eval(my_string);:
#Expression = 'SELECT "Hello, World!";';
PREPARE myquery FROM #Expression;
EXECUTE myquery;
Basically I combined the existing answers, neither tells you how to do eval exactly.
If you want to add parameters, you can use this:
#username = "test";
#password = "asdf";
#Expression = 'SELECT id FROM Users WHERE name = ? AND pass = ?;'
PREPARE myquery FROM #Expression;
EXECUTE myquery USING #username, #password;
And to answer the original question exactly:
#Expression = 'SELECT "Hello, World!";'
PREPARE myquery FROM #Expression;
INSERT INTO Results
EXECUTE myquery;
Note that the PREPARE ... FROM statement wants a session variable (prefixed with #). If you try to pass a normal variable, it will throw its hands up in the air and it just won't care.
EXECUTE is a valid command in MySQL. MySQL reference manual
The EXECUTE MySQL command can only be used for one prepared statement.
If case you want to execute multiple queries from the string, consider saving them into file and source it, e.g.
SET #query = 'SELECT 1; SELECT 2; SELECT 3;';
SELECT #query INTO OUTFILE '/tmp/temp.sql';
SOURCE /tmp/temp.sql;

use result string from one table as column names for another query

I am trying to trying to simplify the following query :-
SELECT id, m_field_id_46 AS Liverpool,m_field_id_47 AS London,m_field_id_48 AS Belfast FROM member_data
In a way i can dynamically create the column names
SELECT id, (SELECT GROUP_CONCAT('m_field_id_',m_field_id,' AS ',m_field_label) FROM member_fields) as dist FROM member_data
However this is not working. Please help
i got it working by looking at another answer from stackoverflow: -
SET #listStr = ( SELECT GROUP_CONCAT('md.m_field_id_',m_field_id,' AS `',m_field_label,'`') FROM member_fields );
SET #query := CONCAT('SELECT ', #listStr, ' FROM member_data');
PREPARE STMT FROM #query;
EXECUTE STMT;

MySQL: Match against dynamic values

I have a list of values in a table column that I need to match against table names, preferably just using an SQL statement.
If the values were static, I suppose the SELECT statement would be something like this:
SELECT table_name FROM information_schema.TABLES WHERE
match(table_name) against('124512' +'36326' +'23636' IN BOOLEAN MODE)
However, I need to match against dynamic values coming from a SELECT statement:
SELECT tableid FROM databaseName.tableOverviewTableName
WHERE template = 'templateName')
The tableid above is contained in the table_name for the tables that I want.
Is this possible to achieve with an SQL statement?
You can do this via Prepared statement (not directly via a query)
SET #tq = (SELECT tableid FROM databaseName.tableOverviewTableName WHERE template = 'templateName'));
SET #stmq = CONCAT('SELECT * FROM ', #tq);
Prepare stmt FROM #stmq;
Execute stmt;
DEALLOCATE PREPARE stmt;

Is it possible to dynamically create the name of a table in a stored procedure with MySQL?

Take a look at this code. It should show you what I am trying to do:
SELECT type from barcodes where barcode = barcodeApp INTO #barcodeType;
IF (#barcodeType = 'videogame') THEN
SET #barcodeType = 'game';
END IF;
DELETE FROM #barcodeType + itemdetails_custom
WHERE barcode = barcodeApp
AND username = usernameApp;
As you can see, on the DELETE FROM part, I would like to dynamically put together the table name from a result of a previous query. Is this possible?
Also, if you see issues with the above queries, please let me know. I'm by no means a MySQL expert obviously.
You need to use Prepared Statement to execute dynamically prepared queries.
Try following code:
set #del_query = concat( 'DELETE FROM ', #finalType )
set #del_query = concat( '\'', itemdetails_custom, '\'' );
set #del_query = concat( #del_query, ' WHERE barcode = \'', barcodeApp, '\'' );
set #del_query = concat( #del_query, ' AND username = \'', usernameApp, '\'' );
prepare stmt from #del_query;
execute stmt;
drop prepare stmt; -- deallocate prepare stmt;
Note: I assumed that barcodeApp and usernameApp are variables. Otherwise remove single quotes around them in the query above.

Set MySQL Column Alias to a Calculated Date

I'm looking to do something like this:
select data AS curdate() from table;
so the resulting table would look like:
2013-04-26
data 1
data 2
data 3
I can't figure out the syntax, but it must be possible?
I've tried it without quotes of any kind, which returns an error. Single quotes and back ticks both return the SQL itself as the column header.
That's an unusual requirement, but if you insist, you'd have to use dynamic sql.
SET #curdate = CURDATE();
SET #sql = CONCAT('SELECT whatever AS "', #curdate, '" FROM whatever');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
An alias is considered an identifier and cannot be assigned to a function without the use of dynamic SQL. It would break referencing such as:
SELECT *
FROM (SELECT 1 AS curdate()) a