mysql dynamic queries execution - mysql

I'm trying to write MySQL script dropping some tables selected by pattern but my procedure doesn't compile. Could anybody please advice what is wrong with it please?
delimiter #
drop procedure if exists drop_audit_tables #
create procedure drop_audit_tables()
begin
declare done int default false;
declare cmd varchar(4000);
declare cmds cursor for select 'drop table [' + table_name + ']' from information_schema.tables where table_name like '%_audit';
declare continue handler for not found set done = true;
open cmds;
tLoop: loop
fetch cmds into cmd;
if done then
leave tLoop;
end if;
PREPARE STMT FROM cmd;
EXECUTE STMT;
DEALLOCATE PREPARE STMT;
end loop tLoop;
close cmds;
end #
the error message:
[42000][1064] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'cmd; EXECUTE STMT; DEALLOCATE PREPARE STMT; end loop tLoop; close cm' at line 13

You can avoid the cursor:
mysql> DROP TABLE IF EXISTS `one_audit`;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE IF EXISTS `two_audit`;
Query OK, 0 rows affected (0.01 sec)
mysql> DROP TABLE IF EXISTS `three_audit`;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `one_audit`(`a` INT);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `two_audit`(`a` INT);
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `three_audit`(`a` INT);
Query OK, 0 rows affected (0.00 sec)
mysql> SET #`drop_tables` := (
-> SELECT
-> CONCAT('DROP TABLE IF EXISTS ',
-> GROUP_CONCAT(CONCAT('`', `TABLE_NAME`, '`') SEPARATOR ', '))
-> FROM
-> `information_schema`.`TABLES`
-> WHERE
-> `TABLE_SCHEMA` = DATABASE() AND
-> `TABLE_TYPE` = 'BASE TABLE' AND
-> `TABLE_NAME` LIKE '%_audit'
-> );
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT #`drop_tables`;
+--------------------------------------------------------------+
| #`drop_tables` |
+--------------------------------------------------------------+
| DROP TABLE IF EXISTS `one_audit`, `three_audit`, `two_audit` |
+--------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> PREPARE `exec` FROM #`drop_tables`;
Query OK, 0 rows affected (0.00 sec)
Statement prepared
mysql> EXECUTE `exec`;
Query OK, 0 rows affected (0.00 sec)
mysql> DEALLOCATE PREPARE `exec`;
Query OK, 0 rows affected (0.00 sec)
You must be careful with the system variable group_concat_max_len.
UPDATE
Using cursor:
DELIMITER #
DROP PROCEDURE IF EXISTS `drop_audit_tables`#
CREATE PROCEDURE `drop_audit_tables`()
BEGIN
DECLARE `done` BOOL DEFAULT 0;
DECLARE `cmd` VARCHAR(4000);
DECLARE `cmds` CURSOR FOR
SELECT
CONCAT('DROP TABLE IF EXISTS `', `TABLE_NAME`, '`')
FROM
`information_schema`.`TABLES`
WHERE
`TABLE_SCHEMA` = DATABASE() AND
`TABLE_TYPE` = 'BASE TABLE' AND
`TABLE_NAME` LIKE '%_audit';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET `done` := 1;
OPEN `cmds`;
`tLoop`: LOOP
FETCH `cmds` INTO `cmd`;
IF `done` THEN
CLOSE `cmds`;
LEAVE `tLoop`;
END IF;
SET #`cmd` := `cmd`;
PREPARE `STMT` FROM #`cmd`;
EXECUTE `STMT`;
DEALLOCATE PREPARE `STMT`;
END LOOP `tLoop`;
SET #`cmd` := NULL;
END#
CALL `drop_audit_tables`#
DELIMITER ;
14.5.1 PREPARE
Syntax
PREPARE stmt_name FROM preparable_stmt
...
preparable_stmt is either a string literal or a user variable that
contains the text of the SQL statement.
...

Your line:
declare cmds cursor for select 'drop table [' + table_name + ']' from information_schema.tables where table_name like '%_audit';
.. uses table_name without defining it first.
Try defining it first with something like:
create procedure drop_audit_tables(IN table_name VARCHAR(64))
You may want to consider the security implications of taking a variable directly from the stored procedure and placing it into your ad-hoc query.
Still, define table_name somewhere. In this case table_name would be supplied as an argument to your stored procedure. Your task then is to gather an array of table names and run this code in a for/foreach loop.
Basic (non-robust) PHP (PDO)
/* Get the audit tables. */
$stmt = $pdo->query(`CALL get_audit_tables()`)
$tables = $stmt->fetch();
$stmt->close()
$stmt = $pdo->prepare('CALL drop_audit_tables(:table)')
/* Drop each audit table. */
foreach($tables as $table)
{
$stmt->bindParam(:table, $table, PDO::PARAM_STR)
$stmt->execute();
}
$stmt->close();
Something like that, anyway.
MySQL: CREATE PROCEDURE
Specifying a parameter as IN, OUT, or INOUT is valid only for a PROCEDURE. For a FUNCTION, parameters are always regarded as IN parameters.
PHP Manual: PDO::prepare
Prepares an SQL statement to be executed by the PDOStatement::execute() method. The SQL statement can contain zero or more named (:name) or question mark (?) parameter markers for which real values will be substituted when the statement is executed.
A solution like this would make your life easier. You only need to define a basic query that finds your audit tables. Less code. Simpler.

Related

Problems creating a temporary table in mysql

I want to create a stored procedure in Mysql that removes a certain temporary table (if it exists) and then creates this temporary table in the database 'prs1'.
The procedure that I have created is this:
CREATE PROCEDURE `CrearTablaTemporal`(table_name VARCHAR(100))
BEGIN
SET #TablaTemporal = table_name;
SET #sql_query1 = CONCAT('DROP temporary table if exists ',#TablaTemporal);
PREPARE stmt1 FROM #sql_query1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
SET #sql_query2 = CONCAT('CREATE TEMPORARY TABLE IF NOT EXISTS prs1.',#TablaTemporal,' (ean13 VarChar(13)) Engine=MyISAM');
PREPARE stmt2 FROM #sql_query2;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
END
When I execute the stored procedure, no error appears but if I execute the following SQL sentence it tells me that the table does not exist:
When I execute the stored procedure from my project (created in Xojo) I don't get any error but I don't know how to check if it is created perfectly since from programs with Navicat, Valentina Studio, etc. when I check the database, the table doesn't exist.
The question is, how do I keep the table open, insert values and retrieve the query?. I explain myself, my application has the connection open permanently to the database all the time until I close the application. In my method, I start the transaction, execute the sentence that creates the temporary table (thanks to the stored procedure) and finish the transaction. I don't close the connection to the database but then I don't know how to maintain the table.
How could I solve it, please?.
Thank you very much.
Sergio
Temporary tables are only available in the session in which they were created. As soon as the connection is terminated, temporary tables are dropped.
A common usecase for using temporary tables are test frameworks, where you use temporary tables to avoid further cleanup.
Session 1:
mysql> delimiter !!
mysql> CREATE PROCEDURE CreateTable(table_name VARCHAR(100))
-> BEGIN
-> SET #a:= CONCAT("CREATE OR REPLACE TEMPORARY TABLE ", table_name, " (a int)");
-> EXECUTE IMMEDIATE #a;
-> END!!
Query OK, 0 rows affected (0,01 sec)
mysql> delimiter ;
mysql> select connection_id();
+-----------------+
| connection_id() |
+-----------------+
| 4118 |
+-----------------+
1 row in set (0,00 sec)
mysql> describe foobar;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| a | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
1 row in set (0,00 sec)
Session 2:
mysql> select connection_id();
+-----------------+
| connection_id() |
+-----------------+
| 4119 |
+-----------------+
1 row in set (0,01 sec)
mysql> describe foobar;
ERROR 1146 (42S02): Table 'test.foobar' doesn't exist
So in case you need to check integrity or content of a temporary table, you need to do that either within the same connection or you have use non temporary tables.
Finally I have the solution with the help of all those who have written to me. I program in Xojo so the queries to the database are made from this program. With Georg's help I have realized that the temporary table only exists in that session and if you close it, the temporary table is deleted. This is how I solved my problem.
I have created a method with these steps:
// Start the transaction
DB.SQLExecute("START TRANSACTION")
// Drop the temporary table if it exists and if not we create it.
We must use these two SQL sentences:
'DROP temporary table if exists #TemporalTable'
'CREATE temporary table if NOT exists #TablaTemporal(field1 VarChar(13))
// OPTIONAL: check if the created time table exists (see below)
// Insert the values into the temporary table
Dim stmSQL As String
DB.SQLExecute("START TRANSACTION")
stmSQL = "INSERT INTO #TablaTemporal(field1)"
stmSQL = stmSQL + " VALUES(?)"
Dim ps As MySQLPreparedStatement = DB.Prepare(stmSQL)
If BBDD.Error = True Then MsgBox DB.ErrorMessage
ps.BindType( 0, MySQLPreparedStatement.MYSQL_TYPE_STRING)
ps.Bind( 0, field1)
ps.SQLExecute
DB.Commit
Return Not DB.Error
//Recover the results of the consultation against the time table
Dim stmSQL As String = "SELECT * FROM #Template"
Return DB.SQLSelect( stmSQL )
//Drop the temporary table
DROP temporary table if exists 'Temporary Table
// Finish the transaction
DB.CommitTransaction
To check and verify if the temporary table exists, I have created a "stored procedure" in the MySQL database that has this code:
CREATE PROCEDURE check_table_exists(table_name VARCHAR(100))
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02' SET #err = 1;
SET #err = 0;
SET #table_name = table_name;
SET #sql_query = CONCAT('SELECT 1 FROM ',#table_name);
PREPARE stmt1 FROM #sql_query;
IF (#err = 1) THEN
SET #table_exists = 0;
ELSE
SET #table_exists = 1;
DEALLOCATE PREPARE stmt1;
END IF;
END
Then from Xojo we only have to call the procedure with this code:
Dim stmSQL As String = "CALL check_table_exists('#TableTemporal')""
ExecuteSQL(stmSQL) database
And execute this SQL query:
Dim stmSQL As String = "SELECT #table_exists"
Return DB.SQLSelect(stmSQL)
If the result is '1', the table has been created and exists; and if it is '0', the table does not exist.
I hope this can help someone... in my case it was for pure self-learning.
A greeting,
Sergio

Debugging mysql sproc, right syntax near 'NULL'

I have written a sproc that will be triggered on inserting a new record to the table.
When called it returns an error 1064 and states:
'You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'NULL' at line 1'
The problem I'm having is I can't debug the inner query to find out where 'NULL' is. Or why its appearing.
Would appreciate if anyone can suggest how I could debug this, or, spot whats up with my code. N.B. I dont believe I can test the dynamic query outside of a sproc.
DROP PROCEDURE IF EXISTS SetUniqueCodeCustomLength;
DELIMITER $$
CREATE PROCEDURE SetUniqueCodeCustomLength (
IN TableName VARCHAR(255),
IN FieldName VARCHAR(255),
IN PKName VARCHAR(250),
IN PKID INT,
IN CodeLength INT)
BEGIN
SET #pass = '';
SET #loop = 0;
SET #matchCount = 1;
SET #sSQL = '';
WHILE #matchCount > 0 DO
SET #loop = 0;
WHILE #loop < CodeLength DO
-- random number from x-uy
SET #chr = SUBSTRING('abcdefghjkpqrstuvwxyz23456789', CAST( ROUND(RAND()*(29-1)+1) AS INT), 1);
SET #pass = #pass + #chr;
SET #loop = #loop + 1;
END WHILE;
-- Check for unique-ness.
SET #sSQL = CONCAT('SELECT COUNT(*) INTO #matchCount FROM ' + #TableName + ' WHERE ' + #FieldName + ' = ''' + #pass + '''');
PREPARE stmt FROM #sSQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END WHILE;
SELECT #pass;
-- perform the update
SET #sSQL = CONCAT('UPDATE ' + #TableName + ' SET ' + #FieldName + ' = ''' + #pass + ''' WHERE ' + #PKName + ' = ' + #PKID);
PREPARE stmt FROM #sSQL;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
Calling with:
CALL SetUniqueCodeCustomLength('Posts', 'PostCode', 'PostID', 7, 6);
Some observations:
Stored procedure's parameters (13.1.16 CREATE PROCEDURE and CREATE FUNCTION Syntax) are different from User-Defined Variables (9.4 User-Defined Variables), eg.: IN TableName != #TableName.
Check CONCAT() syntax.
Be careful with prepared statements (security) and possible SQL Injections.
mysql> DROP PROCEDURE IF EXISTS `SetUniqueCodeCustomLength`;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> DELIMITER $$
mysql> CREATE PROCEDURE `SetUniqueCodeCustomLength` (
-> IN `TableName` VARCHAR(255)
-> )
-> BEGIN
-> SET #`sSQL` := CONCAT('SELECT ', #`TableName`); -- NULL
-> SELECT #`sSQL`;
->
-> SET #`sSQL` := CONCAT('SELECT ', `TableName`); -- SELECT Posts
-> SELECT #`sSQL`;
-> END$$
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL `SetUniqueCodeCustomLength`('Posts');
+---------+
| #`sSQL` |
+---------+
| NULL |
+---------+
1 row in set (0.00 sec)
+--------------+
| #`sSQL` |
+--------------+
| SELECT Posts |
+--------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)

Mysql Error #1064 near Null in call stored procedure with out param

I'm quite new with MySQL. I have to call a stored procedure with output param. I've searched a lot on internet but I've not found the correct solution to my problem. If I call the stored procedure with the #outputParamName it says that I have an error #1064 near NULL. If I call the procedure with the 'outputParamName' without the # it says thath it is not an OUT or INOUT correct param. Someone can help me please?
the stored procedure just have to check if surname and name in DB exists on the same row:
CREATE PROCEDURE InsertProc (INOUT existsInDb BOOLEAN,
IN dbName VARCHAR(50)
IN tableName VARCHAR(50)
IN surnameNew VARCHAR(50)
IN nameNew VARCHAR(50))
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
BEGIN
DECLARE rowSurnameName int;
SET #sqlSel = CONCAT('SELECT COUNT(*) INTO ', rowSurnameName, ' FROM ', dbName, '.', tableName, ' WHERE COGNOME=', surnameNew, ' AND NOME=', nameNew);
PREPARE stmtSel FROM #sqlSel;
EXECUTE stmtSel;
DEALLOCATE PREPARE stmtSel;
IF (rowSurnameName=0) THEN
SET #sqlIns = CONCAT('INSERT INTO ', dbName, '.', tableName, ' (NOME, COGNOME) VALUES (', nameNew, ', ', surnameNew,')');
PREPARE stmtIns FROM #sqlIns;
EXECUTE stmtIns;
DEALLOCATE PREPARE stmtIns;
SELECT false INTO existsInDb;
ELSE SELECT true INTO existsInDb;
END IF;
END
The CALL Statement is:
SET #dbName = 'DBNAME';
SET #tableName = 'DBTABLE';
SET #surname = 'SURNAME';
SET #name = 'NAME';
PREPARE s FROM 'CALL InsertProc(?,?,?,?,?)';
EXECUTE s USING #existsInDB, #dbName, #tableName, #surname, #name;
SELECT #existsInDB;
And the ERROR Line is:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL' at line 1
A couple of notes:
You can't use a local variable in a prepared statement.
C.1 Restrictions on Stored Programs
...
SELECT ... INTO local_var cannot be used as a prepared statement.
...
The error shown in your question occurs because the local variable rowSurnameName has the value NULL, see:
mysql> DROP PROCEDURE IF EXISTS `InsertProc`;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> DELIMITER //
mysql> CREATE PROCEDURE `InsertProc`()
-> BEGIN
-> DECLARE `rowSurnameName` INT;
-> SELECT `rowSurnameName`;
-> SET #`sqlSel` := CONCAT('SELECT COUNT(*) INTO ', `rowSurnameName`);
-> SELECT #`sqlSel`;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL `InsertProc`;
+------------------+
| `rowSurnameName` |
+------------------+
| NULL |
+------------------+
1 row in set (0.00 sec)
+-----------+
| #`sqlSel` |
+-----------+
| NULL |
+-----------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
If you try to use the rowSurnameName local variable in the prepared statement, you will get the error:
mysql> DROP PROCEDURE IF EXISTS `InsertProc`;
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER //
mysql> CREATE PROCEDURE `InsertProc`()
-> BEGIN
-> DECLARE `rowSurnameName` INT;
-> SET #`sqlSel` := CONCAT('SELECT 100 INTO `rowSurnameName`');
-> SELECT #`sqlSel`;
-> PREPARE `stmtSel` FROM #`sqlSel`;
-> EXECUTE `stmtSel`;
-> DEALLOCATE PREPARE `stmtSel`;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL `InsertProc`;
+----------------------------------+
| #`sqlSel` |
+----------------------------------+
| SELECT 100 INTO `rowSurnameName` |
+----------------------------------+
1 row in set (0.00 sec)
ERROR 1327 (42000): Undeclared variable: rowSurnameName
You need to use 9.4 User-Defined Variables in your prepared statement:
mysql> DROP PROCEDURE IF EXISTS `InsertProc`;
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER //
mysql> CREATE PROCEDURE `InsertProc`()
-> BEGIN
-> SET #`sqlSel` := CONCAT('SELECT 100 INTO #`rowSurnameName`');
-> SELECT #`sqlSel`;
-> PREPARE `stmtSel` FROM #`sqlSel`;
-> EXECUTE `stmtSel`;
-> DEALLOCATE PREPARE `stmtSel`;
-> IF (#`rowSurnameName` = 0) THEN
-> SELECT 'NotExistsInDbAndInsert';
-> ELSE
-> SELECT 'existsInDb';
-> END IF;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> DELIMITER ;
mysql> CALL `InsertProc`;
+-----------------------------------+
| #`sqlSel` |
+-----------------------------------+
| SELECT 100 INTO #`rowSurnameName` |
+-----------------------------------+
1 row in set (0.00 sec)
+------------+
| existsInDb |
+------------+
| existsInDb |
+------------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)

set name of table with variables in mysql [duplicate]

How do you build and use dynamic sql in a MySQL stored procedure?
After 5.0.13, in stored procedures, you can use dynamic SQL:
delimiter //
CREATE PROCEDURE dynamic(IN tbl CHAR(64), IN col CHAR(64))
BEGIN
SET #s = CONCAT('SELECT ',col,' FROM ',tbl );
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
//
delimiter ;
Dynamic SQL does not work in functions or triggers. See the MySQL documentation for more uses.
I don't believe MySQL supports dynamic sql. You can do "prepared" statements which is similar, but different.
Here is an example:
mysql> PREPARE stmt FROM
-> 'select count(*)
-> from information_schema.schemata
-> where schema_name = ? or schema_name = ?'
;
Query OK, 0 rows affected (0.00 sec)
Statement prepared
mysql> EXECUTE stmt
-> USING #schema1,#schema2
+----------+
| count(*) |
+----------+
| 2 |
+----------+
1 row in set (0.00 sec)
mysql> DEALLOCATE PREPARE stmt;
The prepared statements are often used to see an execution plan for a given query. Since they are executed with the execute command and the sql can be assigned to a variable you can approximate the some of the same behavior as dynamic sql.
Here is a good link about this:
Don't forget to deallocate the stmt using the last line!
Good Luck!
You can pass thru outside the dynamic statement using User-Defined Variables
Server version: 5.6.25-log MySQL Community Server (GPL)
mysql> PREPARE stmt FROM 'select "AAAA" into #a';
Query OK, 0 rows affected (0.01 sec)
Statement prepared
mysql> EXECUTE stmt;
Query OK, 1 row affected (0.01 sec)
DEALLOCATE prepare stmt;
Query OK, 0 rows affected (0.01 sec)
mysql> select #a;
+------+
| #a |
+------+
|AAAA |
+------+
1 row in set (0.01 sec)

Mysql Triggers, declare a variable and use it as column name

I have the table "mytable" that contains the "columnname" field wich is the name of a column in mytable2.
I use this one for the selection:
SET #DptScn = (SELECT columnname FROM mytable WHERE tablename = 'CustomTableName' AND fieldlabel = 'CustomField');
SET #identifiedid=144;
but, when I try:
SELECT #DptScn FROM mytable2 WHERE identifiedid = #identifiedid;
this give me NOT the content of the field but the name containted into variable #DptScn...
Any advice?
I can't use Prepared Statement because I'm in a Trigger...
UPDATE:
As suggested by spencer7593 I'm creating a procedure:
DROP PROCEDURE IF EXISTS p_t;
DELIMITER $$
CREATE PROCEDURE p_t (IN DptTcn VARCHAR(255), IN tid INT, OUT tT INT)
BEGIN
SET #DptTcn = DptTcn;
SET #tid = tid;
SET #sql = CONCAT('SELECT #DptTcn FROM mytable3 WHERE tid = #tid');
PREPARE stmt FROM #sql;
EXECUTE stmt;
END$$
DELIMITER ;
Then I try it:
SET #DptTcn = (SELECT columnname mytable WHERE tablename = 'CustomTableName' AND fieldlabel = 'CustomField');
SET #identifiedid=145;
CALL proc_ticket(#DptTcn, #identifiedid, #DptT);
But I receive a:
#2014 - Commands out of sync; you can't run this command now
One option to consider is creating a PROCEDURE that makes use of prepared statements, and then calling the the stored procedure from the trigger.
The SQL statement you execute to get the value from a particular column MUST have the column_name specified in the SQL text; this can't be derived "dynamically" in the execution of the statement.
To achieve something like this, you'll need to run two separate statements; one to get the column_name; the second to "SELECT column_name FROM". And the MySQL provided mechanism for executing that second query is a prepared statement.
Followup
Here's an example. I tried to get this built in SQLFiddle, but wasn't able to get it working (it just hung. So, here's the output from a mysql command line client instead.
(All of the statements below use the same delimiter // because we can't use a semicolon as a delimiter for the stored procedure. In SQLFiddle, we have to use the same delimiter on all statements, and the // just happens to be one of the options in SQLFiddle.)
mysql> DELIMITER //
mysql> CREATE PROCEDURE foo(IN colname VARCHAR(255), IN id INT, OUT val VARCHAR(255))
-> BEGIN
-> -- handler for "Unknown column" and "No data" exceptions
-> DECLARE EXIT HANDLER FOR 1054, 1329 BEGIN SET val = NULL; END;
-> SET #sql = CONCAT('SELECT ',colname,' INTO #val FROM t WHERE id = ',id,' LIMIT 1');
-> PREPARE stmt FROM #sql;
-> EXECUTE stmt;
-> SET val = #val;
-> END//
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t (id INT, attr VARCHAR(4), ball VARCHAR(4))//
Query OK, 0 rows affected (0.11 sec)
mysql> INSERT INTO t VALUES (1, 'abcd','efgh'),(2,'ijkl','mnop')//
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> CALL foo('attr',1,#attr_1)//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL foo('attr',2,#attr_2)//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL foo('ball',1,#ball_1)//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL foo('ball',2,#ball_2)//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL foo('attr',777,#err_bad_id)//
Query OK, 0 rows affected (0.00 sec)
mysql> CALL foo('badcol',1,#err_badcol)//
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT #attr_1
-> , #attr_2
-> , #ball_1
-> , #ball_2
-> , #err_bad_id
-> , #err_badcol//
+---------+---------+---------+---------+-------------+-------------+
| #attr_1 | #attr_2 | #ball_1 | #ball_2 | #err_bad_id | #err_badcol |
+---------+---------+---------+---------+-------------+-------------+
| abcd | ijkl | efgh | mnop | NULL | NULL |
+---------+---------+---------+---------+-------------+-------------+
1 row in set (0.00 sec)
mysql> DELIMITER ;
you should create a SP and give the column name.
create proc dbo.TestGetData(#DptScn nvarchar(256))
as
begin
set nocount on
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = 'SELECT #DptScn FROM mytable2 WHERE identifiedid = 144'
exec sp_executesql #SQL, N'#DptScn nvarchar(256)', #DptScn =#DptScn
end
Then
exec dbo.TestGetData 'Column1'