Creating and then using a database with a declared variable name - mysql

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.

Related

Using a variable OUTFILE in a MySQL scheduled event

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;

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;

printing a mysql query

I prepared a statement:
set #table_name = 'W13LAT';
set #sql_text = concat('drop table if exists ',#table_name);
set #sql_text2 = concat('create table ', #table_name, '
(`Student_ID_NUMBER` int(9) unsigned NOT NULL)
ENGINE=MyISAM DEFAULT CHARSET=latin1
');
prepare stmt from #sql_text;
prepare stmt2 from #sql_text2;
execute stmt;
execute stmt2;
The problem is that it doesn't create the table. I'd like to debug by printing out the mysql query generated from the prepared statements. Is this possible right from the mysql command line? For example, I'd like to remove the execute stmt; and execute stmt2; and replace them with echo stmt; or print stmt; or whatever the command is to see the actual statement generated. Also, if you see an error i made as to why it didn't create the table, please let me know!
Thanks!
You're right...it does work. There's this tiny little button at the bottom of Sequel Pro that says 'refresh table list' :/
And thanks for the select #sql_text statement. It worked as well.

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?

MySQL User-Defined Variable Values Can't be Used as Identifiers. How do I do this?

According to the manual:
User variables... cannot be used
directly in an SQL statement as an
identifier or as part of an
identifier, such as in contexts where
a table or database name is expected
Which explains why what I've been trying doesn't work:
set #databaseName := 'job_hunt_2';
drop database #databaseName;
create database #databaseName;
use #databaseName;
Is there a way to accomplish this, or is it simply impossible? Thanks!
may be you should try following approach:
set #databaseName := 'job_hunt_2';
SET #s = CONCAT('drop database ', #databaseName);
PREPARE stmt1 FROM #s;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;