Using a variable OUTFILE in a MySQL scheduled event - mysql

I am using phpMyAdmin to try to schedule an event that runs every hour. I need it to select data from one of my tables and export it to csv that has a unique name which includes the current timestamp. Outside of an event, I can successfully output from my table to a csv like so:
SET #TimeStamp = DATE_FORMAT(NOW(),'__%Y_%m_%d__%H.%i.%s');
SELECT CONCAT(
'SELECT form_value INTO OUTFILE \'D:/Websites/RTP/contact_form_data/form_data_',
#TimeStamp,
'.csv\' ',
'FROM wp_db7_forms'
) INTO #SQL;
PREPARE stmt from #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
However, I can't for the life of me figure out how to get this working in an event. phpMyAdmin doesn't give very specific error messages, but it seems that the event doesn't like the fact that I am using a variable (it also doesn't seem to like CONCAT). From my research, I've found that this may be because each event executes in a new session, and user-defined variables have session scope.
I tried creating a stored procedure to execute this same block of code, but that experiences similar issues.
Any ideas on an approach I can take to get my code to properly execute in an event?

Try this.
SET #sql =
CONCAT(
'SELECT form_value INTO OUTFILE \'D:/Websites/RTP/contact_form_data/form_data_',
DATE_FORMAT(NOW(),'__%Y_%m_%d__%H.%i.%s'),
'.csv\' ',
'FROM wp_db7_forms'
) ;
PREPARE stmt from #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
The session variable for time is not needed and the session variable #sql must be set as show in the code
This can be saved in mysql 8 and Workbench
DELIMITER $$
CREATE EVENT export_contact_Form_data
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 MINUTE
ON COMPLETION PRESERVE
DO BEGIN
SET #sql =
CONCAT(
'SELECT form_value INTO OUTFILE \'D:/Websites/RTP/contact_form_data/form_data_',
DATE_FORMAT(NOW(),'__%Y_%m_%d__%H.%i.%s'),
'.csv\' ',
'FROM wp_db7_forms'
) ;
PREPARE stmt from #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
This runs only once in one minute, so that you can i peace check
every thing
and of course the delete query
DROP EVENT IF Exists export_contact_Form_data;

Related

Creating and then using a database with a declared variable name

I'm trying to create a database named 'uppg' and then use that database once it's created.
The first statement executes as it should, but nothing happens when I try to use the database with the variable. I have tried multiple variations but I don't know why it's not working.
SET #dbname = 'uppg';
SET #q1 = CONCAT(
'CREATE DATABASE `', #dbname, '`');
PREPARE stmt1 FROM #q1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
SET #q2 = CONCAT(
'USE ', #dbname,
);
PREPARE stmt2 FROM #q2;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
There exists complete list of statements allowed in PREPARE: SQL Syntax Permitted in Prepared Statements.
USE is not mentioned in it. So you cannot alter current database using dynamic SQL.
The simplest solution: use complete tables names (including database name) in your queries. In this case the current DB can be any (but not none) - this won't effect your queries.

Create a dynamic procedure call statement in mysql

if I want to call a procedure with different input in each time input1,input2, input 3, ... and different output out1,out2,...and so on
proc(input1,out1) proc(input2,out2)...
can I made only one prepared statement inside a while loop to do that job? something like this
while c <= 10 DO
SET #sql = CONCAT('call proc(input',c,',out',c')');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set c=c+1;
end while;

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;

IN Clause dont work in MySQL for me

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 (?)'

how to create MYSQL prepare statements and resetting them in 1 stored procedure

I currently am looping through a list of userNames from the DB. as such :
DECLARE
cur1 CURSOR FOR
select user_name
from users
where user_type = 'SP'
and active = 'Y';
OPEN cur1;
read_loop : LOOP
FETCH cur1 INTO userName;
Now for each userName, i am creating tables with data. Obviously, within the above LOOP, i have multiple PREPARE statements like :
set l_table_name = concat("tmp_rec_",userName);
set l_select_cnt = concat("SELECT count(1) into #l_cnt
from information_schema.tables
where table_schema = 'greptlat_db'
and table_name = '", l_table_name, "'");
PREPARE stmt2 FROM #l_select_cnt;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
if l_cnt > 0 then
set droptable = concat("drop table ", l_table_name);
PREPARE stmt1 FROM #droptable;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END IF;
I have more PREPARE statements that build the data that i want and inserts it into the table that i create for each user.
Now because this is in a LOOP, for each user, i have read that PREPARE statements are global. Which means, the above code, "PREPARE stmt1 FROM #droptable", stmt1 will never change even though it gors through the LOOP for each user. Even if i DEALLOCATE it, it still remains for that stored procedure.
How can i reset this stmt1,stmt2,stmt3 ...etc for each time the LOOP starts again ?
Basically l_table_name will change for each time the LOOP goes through, but stmt1 doesnt change.. I need stmt1 to change so that it will use the new l_table_name everytime
Normally a prepare statement deallocated implicitly before the new statement is prepared. So what is the result if you remove DEALLOCATE PREPARE stmt1;. Did you check the '#droptable' value in each loop?