IN Clause dont work in MySQL for me - mysql

I am passing my parameter as 'Suburbun','Indigo' to retrieve records matching both Campaigns in below Stored Procedure created in MySql.
CREATE PROCEDURE `DemoSP`(Campaign VARCHAR(3000))
BEGIN
SET #query = CONCAT('Select * from vicidial_log WHERE campaign_id IN (?)');
PREPARE stmt FROM #query;
SET #CampaignID = Campaign;
EXECUTE stmt USING #CampaignID;
DEALLOCATE PREPARE stmt;
END;
It Doesn't give any rows!
But when i pass only 'Suburbun' in SP, it gives 6 Rows!
Where am i going wrong?
--Answer !
I tried as Lee Fentress commented in http://www.poolofthought.com/index.php/2008/12/28/a-comma-seperated-list-as-parameter-to-mysql-stored-procedure/ and peterm answer reflected similar coding,
It worked!
Thanks, but i find this negative mark as compared to SQL Server.
Gee, Thank you Guys!!

You won't be able to use USING in this case. You can just build the full query sting and execute it without parameters
DELIMITER $$
CREATE PROCEDURE DemoSP(Campaign VARCHAR(3000))
BEGIN
SET #query = CONCAT('SELECT * FROM vicidial_log WHERE campaign_id IN (', Campaign, ')');
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
Note: make sure that delimited values that you pass in Campaign are properly quoted (like you said they are) and quotes in values, if there is any, are escaped.
Here is SQLFiddle demo

Try this:
There is no need to use PREPARE STATEMENT. You can get the result using FIND_IN_SET() function
SELECT * FROM vicidial_log WHERE FIND_IN_SET(campaign_id, Campaign)

try this
"Select * from vicidial_log WHERE campaign_id IN ('?')"
instead of
'Select * from vicidial_log WHERE campaign_id IN (?)'

Related

Can one set a varaible in MYSQL to use as the DB name in an update or select [duplicate]

Is there any way in MySQL to put the name of the database into a variable?
For example, when I have a database called 'db1', can I do something like this:
set #db= 'db1';
select * from #db.mytable;
EDIT: There is another example of what I want to do:
set #dbfrom= 'db1';
set #dbto= 'db2';
insert into #dbto.mytable (col1,col2,col3) select col2,col1,col3 from #dbfrom.mytable;
With considerable effort, yes.
SET #db = 'db1';
SET #q = CONCAT('SELECT * FROM ', #db, '.mycol');
PREPARE stmt FROM #q;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
Using Chaos' 'Prepare Statement' solution I managed to create a Stored Procedure which uses a variable database name.
Works like a charm for migrating data from one database to another with a Stored Procedure. This way the code isn't pinned to a single database.
DELIMITER $$
DROP PROCEDURE IF EXISTS `SampleProcedure` $$
CREATE PROCEDURE `SampleProcedure`(IN HubDatabaseName VARCHAR(255))
BEGIN
SET #db = HubDatabaseName;
SET #q = CONCAT('
/* Import data from Hub database to local database */
INSERT INTO `table_name_in_local_database`
SELECT
*
FROM
', #db ,'.`tablename`
');
PREPARE stmt FROM #q;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
If you have PHP installed you could use this script to replace the mysql variables to there actual value:
<?php
$sqlFile = 'migration.sql';
$fromDb = 'db1';
$toDb = 'db2';
echo str_replace(['#fromDb', '#toDb'], [$fromDb, $toDb], file_get_contents($sqlFile));

Using dynamic SQL in MySql function

I have created a function in phpMyAdmin as shown in this screenshot.
When I try to use it like this:
Select DMax ("id","customers")
I get error #1305 saying that uTable does not exist. This is probably some basic syntax issue, as uTable in the sql statement is taken literally and not seen as a parameter. So how do I make it work?
You can't use parameters to a procedure for column or table names. Instead, you need to prepare a statement using those values and execute that. For example:
BEGIN
DECLARE uValue INT(11);
SET #sql = CONCAT('SELECT MAX(', uField, ') INTO uValue FROM ', uTable);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
RETURN uValue;
END
Note that you cannot use dynamic SQL in a function, so you would need to convert this into a stored procedure with uValue an OUT parameter i.e.
CREATE PROCEDURE DMax(
IN uField VARCHAR(100),
IN uTable VARCHAR(100),
OUT uValue <appropriate type>
)
BEGIN
DECLARE uValue INT(11);
SET #sql = CONCAT('SELECT MAX(', uField, ') INTO uValue FROM ', uTable);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
Then you would need to call the procedure, something like
CALL DMax('table1', 'column1', #DMax)
and you can then
SELECT #DMax
(yes, this is a monumental pain)

Table in FROM clause defined by variable in MySQL

I want to create a SQL script for MySQL 5.7 that inserts data from a table of a database origin into a table of another target database.
I want to have this source-database defined by a variable.
USE my_target_db;
SET #origin_db='my_origin_db';
SET #origin_table = concat(#origin_db,'.','tablename');
INSERT INTO target_table SELECT * FROM #origin_table;
Variables are used in various example to define column names but I never seen a way to define a table with it.
Is anyone has a trick for this ?
Variables won't use in table name in MySQL. You only can use a prepared statement for dynamic build query. For example:
USE my_target_db;
SET #origin_db='my_origin_db';
SET #origin_table = CONCAT(#origin_db,'.','tablename');
SET #query = CONCAT('INSERT INTO target_table SELECT * FROM ', #origin_table);
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
You can read more detail about it in official documentation
You can use Prepared Statement like this:
USE my_target_db;
SET #origin_db='my_origin_db';
SET #origin_table = concat(#origin_db,'.','tablename');
SET #qry1 = concat('INSERT INTO target_table SELECT * FROM ', #origin_table);
PREPARE stmt1 from #qry1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;

how to define a stored procedures which accepts 2 parameteres

I´m trying to define a stored procedures which accepts 2 parameteres , one would be the table column which has to be equal with the second parameter i will provide.
Code :
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `selectUserByField`(IN _field varchar(150) , IN _value varchar(150))
BEGIN
SET #sql = CONCAT('SELECT * FROM Users WHERE', _field, '=' ,_value);
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
The thing is that i don´t know how to provide the _value param as a string. If i run it like this i get a Mysql 1064 near ´=myEmail´( params where ´userEmail´,´myEmail´). Thanks !
In your below code, you are missing a space after WHERE. It should be like below; give a space after WHERE and in =
SET #sql = CONCAT('SELECT * FROM Users WHERE ', _field, ' = ' ,_value);

use a variable for table name in mysql sproc

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.