Can anybody help me to find a mysql corespondent to the following MS SQL syntax?
CREATE PROCEDURE testsp #COLUMN_NAME VARCHAR(20), #COLUMN_VALUE VARCHAR(20)
AS
DECLARE #SQL VARCHAR(40)
SET #SQL = 'UPDATE TableX set ''+#COLUMN_NAME+ ''=''+#COLUMN_VALUE+'' '
PRINT (#SQL)
EXEC (#SQL)
Is it possible to translate this code into Mysql?
Thanks!
CREATE PROCEDURE testsp (COLUMN_NAME VARCHAR(20), COLUMN_VALUE VARCHAR(20))
BEGIN
SET #SQL_COMMAND = CONCAT('UPDATE TableX SET ', COLUMN_NAME, ' = ?');
SELECT #SQL_COMMAND; /* prints the command */
PREPARE SQL_STMT FROM #SQL_COMMAND;
EXECUTE SQL_STMT USING COLUMN_VALUE;
DEALLOCATE SQL_STMT;
END
Related
My problem: I have a few tables in mysql database with column "URL". I want to extract all of URLs to text file or another table.
Is it good way to go?
DELIMITER $$
CREATE or replace PROCEDURE link()
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE tablename varchar(1000) DEFAULT "";
DECLARE link_tables
CURSOR for
SELECT table_name FROM information_schema.columns WHERE table_name like '__baza%' and COLUMN_NAME like 'url';
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
OPEN link_tables;
getTable: LOOP
fetch link_tables into tablename;
IF finished = 1 THEN s
LEAVE getTable;
END IF;
select url from tablename into ... <<<< is it good idea? what to do next?
END LOOP getTable;
close link_tables;
END$$
DELIMITER ;
CALL link();
CREATE PROCEDURE link_urls (prefix VARCHAR(64))
BEGIN
SELECT GROUP_CONCAT( CONCAT( 'SELECT url FROM ', table_name) SEPARATOR ' UNION ')
INTO #sql
FROM information_schema.columns
WHERE table_name like CONCAT(prefix, '%');
SET #sql = CONCAT( 'CREATE TABLE urls ', #sql );
PREPARE stmt FROM #sql;
EXECUTE stmt;
DROP PREPARE stmt;
END
fiddle
I'm creating some stored procedures to manage my DB.
In particular, i want to create a stored procedore to edit a column, of a specific row, but i want to do it dinamically, passing the column name as an argument.
That's what i want to do
CREATE PROCEDURE myDB.edit_myTable(
IN key CHAR(16),
IN col VARCHAR(100),
new_value VARCHAR(200)
)
UPDATE myDB.myTable SET col = new_value
Using the parameter keyi find the specific row in myTablethat i want to edit, and i want to use the parameter col to edit just the column that i want.
I've already tried using CONCATE()or defining local variables, as i read on other topic, but i haven't find a solution.
Any help?
You would need to use dynamic SQL :
DELIMITER //
CREATE PROCEDURE myDB.edit_myTable(
IN key CHAR(16),
IN col VARCHAR(100),
new_value VARCHAR(200)
)
BEGIN
SET #s = CONCAT(
'UPDATE myDB.myTable SET `',
col, '` = ', QUOTE(new_value),
' WHERE key = ', QUOTE(key)
);
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
//
DELIMITER;
Please note that, as commented by Paul Spiegel, using a variable for column name creates a risk of SQL injection. One solution for improve security would be to make sure that the input col does exists in the target table, using MySQL information schema :
DELIMITER //
CREATE PROCEDURE myDB.edit_myTable(
IN key CHAR(16),
IN col VARCHAR(100),
new_value VARCHAR(200)
)
BEGIN
DECLARE col_exists INT;
SELECT COUNT(*) INTO col_exists
FROM information_schema.COLUMNS
WHERE TABLENAME = 'mytable' AND COLUMN_NAME = col;
IF (col_exists != 1) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = CONCAT('Column ', col, ' does not exist in table mytable');
END IF;
SET #s = CONCAT(
'UPDATE myDB.myTable SET `',
col, '` = ', QUOTE(new_value),
' WHERE key = ', QUOTE(key)
);
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
//
DELIMITER;
below is my query:
DELIMITER $$
DROP PROCEDURE IF EXISTS `UpdateDB_Base_Url`$$
CREATE PROCEDURE UpdateDB_Base_Url()
BEGIN
DECLARE #rownum INT DEFAULT 1;
DECLARE #tbname VARCHAR(50);
WHILE #rownum<105 DO
SET #tbname= SELECT CONCAT((SELECT dbname FROM temp_db WHERE rownum=#rownum),'.','core_config_data');
UPDATE #tbname t
SET t.`value` =CONCAT(SUBSTRING(`value`, 1,LOCATE('.' ,`value`)),'magapa.ns-staging.com.au')
WHERE t.`value` LIKE '%staging-php%';
SET #rownum=#rownum+1;
END WHILE;
END$$
DELIMITER ;
temp_db table has db names with row number upto 104 records. here i am trying to update a table by going through all dbs in my server and i am getting following error
Query: CREATE PROCEDURE UpdateDB_Base_Url() begin declare #rownum int default 1; declare #tbname varchar(50); while #rownum<105 do SET ...
Error Code: 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 '#rownum int default 1;
declare #tbname varchar(50);
while #rownum<105 do
SET #' at line 3
Can someone help me with this?
Thanks!
There are few issues with your code.
You need not qualify local variables with '#' symbol. They are for
user/session variables.
You can read output of an expression into a local variable using
select ... into. No explicit set and select are required.
You can't just update a table with table name read from a
variable, directly. You have to use Prepared Statement.
Change your code as below:
DELIMITER $$
DROP PROCEDURE IF EXISTS `UpdateDB_Base_Url` $$
CREATE PROCEDURE UpdateDB_Base_Url()
BEGIN
DECLARE _rownum INT DEFAULT 1;
DECLARE _tbname VARCHAR(50);
SET _rownum := 1;
WHILE _rownum < 105 DO
SELECT CONCAT( dbname, ',', 'core_config_data' )
INTO _tbname
FROM temp_db
WHERE rownum = _rownum;
SET #sql := CONCAT( 'UPDATE ', _tbname, ' t ' );
SET #sql := CONCAT( #sql, ' SET t.`value` = ' );
SET #sql := CONCAT( #sql, ' CONCAT( SUBSTRING( t.`value`, 1, ' );
SET #sql := CONCAT( #sql, ' LOCATE( \'.\', t.`value` ) )' );
SET #sql := CONCAT( #sql, ', \'magapa.ns-staging.com.au\' )';
SET #sql := CONCAT( #sql, ' WHERE t.`value` LIKE \'%staging-php%\'' );
PREPARE stmt FROM #sql;
EXECUTE stmt;
DROP PREPARE stmt;
SET _rownum := _rownum + 1;
END WHILE;
END;
$$
DELIMITER ;
I am creating a stored procedure in MySQL and need to assign the results of a SQL query to a variable. The problem is that in order to create the SELECT statement, I have to use the CONCAT() function because I am passing in parameters.
Well it appears you can't use variables within the CONCAT function. Any ideas on how I can achieve this? The procedure I am trying to write is below:
DELIMITER //
CREATE PROCEDURE `my_proc` (IN tbl VARCHAR(20), IN col VARCHAR(20), IN id INT)
BEGIN
DECLARE #myval VARCHAR(100);
SET #t1 =CONCAT('SELECT ',col,' FROM ',tbl,' INTO #myval WHERE id = ',id );
PREPARE stmt1 FROM #t1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
END //
Executing this gives me a SQL syntax error.
The problem is the following line:
...
-- SET #t1 = CONCAT('SELECT ',col,' FROM ',tbl,' INTO #myval WHERE id = ',id );
SET #t1 = CONCAT('SELECT ', col, ' INTO #myval FROM ', tbl, ' WHERE id = ', id);
...
Check the documentation: 13.2.9.1. SELECT ... INTO Syntax.
Here is a SQL Fiddle with an example.
It is important to indicate the difference between 9.4. User-Defined Variables (#t1 and #myval) and 13.6.4.1. Local Variable Syntax DECLARE (as could be: myval and t1), are different variables, therefore, it is not necessary to declare:
-- DECLARE #myval VARCHAR (100);
I'm sure there's a way to do this but I haven't been able to put the pieces together.
I'd like to:
select table_name from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = 'myschema';
and then....
for each table_name in that list
BEGIN
CREATE table myschemacopy.table_name like myschema.table_name;
INSERT INTO myschemacopy.table_nameSELECT * FROM myschema.table_name;
END LOOP
How can this be done?
If it's on the same server just a different database, you can use
SOLUTION 1 :
CREATE TABLE newdb.mynewtable LIKE olddb.myoldtable;
You can then insert data into the new table from the old using
INSERT newdb.mynewtable SELECT * FROM olddb.myoldtable;
[or]
SOLUTION 2
ALTER table olddb.myoldtable rename newdb.mynewtable
It's a little late but having just had to solve the same problem, here's the stored procedure that I came up with, in case it helps someone else:
CREATE DEFINER=`whoever`#`wherever` PROCEDURE `copy_schema`(
IN in_oldDB varchar(256),
IN in_newDB varchar(256),
IN in_copyData int(1)
)
BEGIN
DECLARE v_finished INTEGER DEFAULT 0;
DECLARE v_tname varchar(100) DEFAULT "";
DECLARE curTable CURSOR FOR
SELECT `table_name`
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = in_oldDB
and TABLE_TYPE='BASE TABLE'
;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1;
set #result=NULL;
# Create new schema if it doesn't exist
SET #sql = CONCAT('CREATE SCHEMA IF NOT EXISTS ',in_newDB,';');
PREPARE create_schema FROM #sql;
EXECUTE create_schema;
DEALLOCATE PREPARE create_schema;
# Loop over tables in old schema
OPEN curTable;
clone_tables: LOOP
# get next table name
FETCH curTable INTO v_tname;
# Quit if we're done
IF v_finished = 1 THEN LEAVE clone_tables; END IF;
# Clone the table
SET #sql = CONCAT("CREATE TABLE `", in_newDB, "`.`", v_tname, "` LIKE `", in_oldDB, "`.`", v_tname, "`;");
PREPARE clone_table FROM #sql;
EXECUTE clone_table;
DEALLOCATE PREPARE clone_table;
# Optionally copy data
#select v_tname; # This just gives some feedback in workbench for long-running copies
IF (in_copyData > 0) THEN
SET #sql = CONCAT("INSERT INTO `", in_newDB, "`.`", v_tname, "` SELECT * FROM `", in_oldDB, "`.`", v_tname, "`;");
PREPARE clone_data FROM #sql;
EXECUTE clone_data;
DEALLOCATE PREPARE clone_data;
END IF;
# Result message
SET #result = IFNULL(CONCAT(#result,',',v_tname),v_tname);
END LOOP clone_tables;
# Close cursor
CLOSE curTable;
# Print result message
SELECT CONCAT("Copied the following tables from ", in_oldDB, " to ", in_newDB, ": ", #result);
END
Just copy the below Query result and Run it, or you could build dynamic Query.
select 'select * into [newschema]. ' + table_name + ' from [myschema].' +table_name
from INFORMATION_SCHEMA.TABLES
where TABLE_SCHEMA = 'myschema'