Running the same SQL script on different tables - mysql

I have a manually created conversion script that changes a product ID to another. It does it for a thousand products and I need to run it on 10 different tables. Can I do it without duplicating the script?
I hoped to do it like this, but it is not supported:
convert_one.sql:
UPDATE #table SET product_id=12345 where product_id=123
... a thousand similar lines
convert_all.sql:
SET #table = 'table1';
SOURCE convert_one.sql;
SET #table = 'table2';
SOURCE convert_one.sql;

You have to use prepared statements. Otherwise your variable is simply treated like a string and you can't select from or update a string.
Try it like this:
SET #table = 'table1';
PREPARE stmt FROM CONCAT('UPDATE ', #table, ' SET product_id=12345 where product_id=123;');
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Related

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;

MySQL query, create table with variable

How do you include a variable into a create table query(.sql file)? I have tried everything to my knowledge, but it simply sets the #variable name itself as the table name instead of the actual variable.
(I.e it sets #preset as the name instead of "cart_")
SET #Preset='cart_';
CREATE TABLE IF NOT EXISTS `#preset,Customer` (....
You need dynamic sql. To do this, you are going to have to use prepared statements
Try something like:
SET #SQL = CONCAT('CREATE TABLE ',CONCAT('cart_',customer), ..;
PREPARE stmt FROM #SQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

Executing a prepared statement within a query

I have this below piece of code. I would like to populate the KPI_RESULTS table using computed data from variable data. The variable data receives different fomulas. eg( n1*n7)*100 depending on the definition of the KPI fomula by the engineer. n1 ----n! are column names.
Am however getting an error when I try to execute the below scripts.
enter code here
set #data = 'n2/n1';
set #s = Concat("select datetime , element NODE,",#data," RESULTS from loas");
PREPARE STMT FROM #s;
INSERT INTO KPI_results(date_time,node_name,results) values(execute STMT );
That's unfortunately not supported. You'll have to PREPARE the dynamically generated INSERT query you want to run instead:
mysql> set #formula='n2/n1'
mysql> set #sql = CONCAT('INSERT INTO KPI_results SELECT foo, bar, ', #formula, ' FROM t')
mysql> PREPARE stmt FROM #sql
mysql> EXECUTE stmt

How to get variable value as table name in select statement

SET Project_List_val=CONCAT(Project_Number_val,'_List');
Insert Into test (Manthan_Panel_Id) select Manthan_Panel_Id from Project_List_val where Project_Number_val='9';
In the insert statement there is the variable named 'Project_List_val' which consist of table name as concated in the above step. This statement is not taking the content of the variable as table name instead it is taking 'Project_List_val' as table name and giving table not found error.
Any suggestions?
By default you cannot parameterized table names and column names so you need to create Dynamic SQL for that,
SET #Project_List_val = CONCAT(Project_Number_val, '_List');
SET #projNum = 9;
SET #sql = CONCAT(' INSERT INTO test (Manthan_Panel_Id)
SELECT Manthan_Panel_Id
FROM ', #Project_List_val, '
WHERE Project_Number_val = ?');
PREPARE stmt FROM #sql;
EXECUTE stmt USING #projNum;
DEALLOCATE PREPARE stmt;

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.