I have created the following MySQL SP successfully..
CREATE DEFINER=`root`#`%` PROCEDURE `Common_Proc_Create_NewId`
(
TableName VARCHAR(250),
ColumnName VARCHAR(150),
OUT ReturnId BIGINT
)
BEGIN
DECLARE varb BIGINT;
SET #NewId:= CONCAT('SELECT (IFNULL(MAX(', ColumnName, '), 0) + 1) INTO ', varb, ' FROM ', TableName);
PREPARE Stmnt FROM #NewId;
EXECUTE Stmnt;
DEALLOCATE PREPARE Stmnt;
SET ReturnId = varb;
END$$
But when this was called from another SP I got the following error:
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 'NULL' at line 1
Calling SP
CREATE DEFINER=`root`#`%` PROCEDURE `Masters_Proc_Create_BranchType`(
BranchTypName VARCHAR(100)
)
BEGIN
CALL Common_Proc_Create_NewId('Masters_BranchType', 'BranchTypeId', #Id);
INSERT INTO Masters_BranchType (BranchTypeId, BranchTypeName) VALUES (#Id, BranchTypName);
SELECT #Id;
END$$
In your stored procedure Common_Proc_Create_NewId the part into varb was causing the issue and think it's not allowed that way in a prepared statement (not sure though). Instead the way you are doing, try like below and it works fine (a sample code included)
delimiter //
CREATE PROCEDURE dynamic1(IN tbl VARCHAR(64), IN col VARCHAR(64), OUT ret int)
BEGIN
SET #s = CONCAT('SELECT #i := (IFNULL(MAX(', col, '), 0) + 1) FROM ', tbl);
PREPARE stmt FROM #s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set ret = #i;
END
//
delimiter ;
call dynamic1('test1','col',#id);
select #id;
Related
I am trying to convert a SQL Server stored procedure to Mysql as I am migrating an entire database to Mysql
But I am not able to convert a few of the stored procedures which are using XML interaction. I am not a Mysql guy. So could some one please help me out?
Thanks in advance.
My stored procedure in SQL Server looks like this:
ALTER PROCEDURE [dbo].[usp_MemberToDoList_UpdateForMember]
(
#xml nvarchar(max),
#login varchar(255)
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #doc int;
DECLARE #now datetime = GETUTCDATE();
EXEC [sp_xml_preparedocument] #doc OUTPUT, #xml;
UPDATE
[mtdl]
SET
[taskCompleteDate] = CASE WHEN [isCompleted] = CONVERT(bit, 1) THEN #now ELSE NULL END,
[updatedBy] = #login,
[dateUpdated] = GETUTCDATE()
FROM
[MemberToDoList] [mtdl]
JOIN
OPENXML (#doc, '/todos/todo') WITH
(
[id] int,
[isCompleted] bit
) [x] ON [x].[id] = [mtdl].[memberToDoListId];
EXEC [sp_xml_removedocument] #doc;
END
When I convert to Mysql it looks like
CREATE PROCEDURE `conversion`.`usp_MemberToDoList_UpdateForMember` (xml longtext,
login varchar(255))
BEGIN
DECLARE v_doc int;
DECLARE v_now datetime(3);
set v_now = UTC_TIMESTAMP();
CALL sp_xml_preparedocument(#doc)
PREPARE stmt FROM #stmt_str;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
v_doc OUT, xml;
UPDATE
mtdl
SET
`taskCompleteDate` = CASE WHEN `isCompleted` = CONVERT(1,UNSIGNED) THEN v_now ELSE NULL END
,`updatedBy` = #login,
`dateUpdated` = UTC_TIMESTAMP()
FROM
`MemberToDoList` `mtdl`
JOIN
ExtractValue(#doc, '/todos/todo') WITH
(
`id` int,
`isCompleted` bit
) `x` ON [x].[id] = `mtdl`.`memberToDoListId`;
SET #stmt_str = `sxml_removedocument`;
PREPARE stmt FROM #stmt_str;
EXECUTE stmt;`enter code here`
DEALLOCATE PREPARE stmt; #doc;
END
but keeps me giving error:
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 'END' at line 1
FYI I am using Mysql version 5.6
try this:
your creating nor sql query, if you wants to create the sql procedure you should must add the delimiter in the starting and ending in your query. And ; add the like my query END; as query is following as:
delimiter //
CREATE PROCEDURE `conversion`.`usp_MemberToDoList_UpdateForMember` (xml longtext,
login varchar(255))
BEGIN
DECLARE v_doc int;
DECLARE v_now datetime(3);
set v_now = UTC_TIMESTAMP();
CALL sp_xml_preparedocument(#doc)
PREPARE stmt FROM #stmt_str;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
v_doc OUT, xml;
UPDATE
mtdl
SET
`taskCompleteDate` = CASE WHEN `isCompleted` = CONVERT(1,UNSIGNED) THEN v_now ELSE NULL END
,`updatedBy` = #login,
`dateUpdated` = UTC_TIMESTAMP()
FROM
`MemberToDoList` `mtdl`
JOIN
ExtractValue(#doc, '/todos/todo') WITH
(
`id` int,
`isCompleted` bit
) `x` ON [x].[id] = `mtdl`.`memberToDoListId`;
SET #stmt_str = `sxml_removedocument`;
PREPARE stmt FROM #stmt_str;
EXECUTE stmt;`enter code here`
DEALLOCATE PREPARE stmt; #doc;
END; //
delimiter ;
http://dev.mysql.com/doc/refman/5.0/en/create-procedure.html
I have tried with following code. But it shows error msg like this undeclared variable :nt.
CREATE DEFINER=`root`#`localhost` PROCEDURE `get_ntime`(in tb varchar(50),in d int, out nt varchar(50))
BEGIN
SET #statment = concat('Select ntime into nt from ',tb);
SET #date = CONCAT(' WHERE date = "', d, '"');
SET #statmen = CONCAT(#statment, #date);
PREPARE stmt FROM #statment;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END
When used within single quotes nt will not be treated as variable but a literal.
Use local variable to set value into and assign the same to out param after execution.
Example:
DELIMITER //
CREATE DEFINER=`root`#`localhost`
PROCEDURE `get_ntime`( in tb varchar(50), in d int, out nt varchar(50) )
BEGIN
SET #staetment = concat( 'Select ntime into #nTime from ', tb );
-- SET #date = CONCAT( ' WHERE date = "', d, '"' );
SET #date = CONCAT( ' WHERE date = ?' );
SET #statement = CONCAT( #statement, #date );
SET #dt := d;
PREPARE stmt FROM #statement;
-- EXECUTE stmt;
EXECUTE stmt using #dt;
DEALLOCATE PREPARE stmt;
SET nt := #nTime;
END;
//
DELIMITER ;
Prepared statements have session scope, mysql doesn't know you want to use your prepared statement inside stored procedure only. You deallocate the statement immediately, but it doesn't have to be always like that.
Thats why mysql simply disallows using anything that has less scope inside your prepared statement - as is the case with in and out parameters, which have a scope of stored procedure.
As a workaround mentioned in mysql prepare statement manual you can use user variable inside your prepared statement and then SET your out paremeter to that user variable.
When I didn't use out variable, the stored procedure worked correctly, but when I execute the stored procedure with out variable, this error shows up:
MySQL said: #1327 - Undeclared variable: sp_result
Code:
CREATE DEFINER=`root`#`localhost` PROCEDURE `test3`(OUT `sp_result` INT(11), IN `sp_where_param` VARCHAR(100), IN `sp_where_value` VARCHAR(100), IN `sp_table_name` VARCHAR(100))
NO SQL
BEGIN
DECLARE tbl_id VARCHAR(100);
SET tbl_id = CONCAT(sp_table_name,'_id');
SET #temp1=CONCAT('SELECT count(',tbl_id,') INTO sp_result FROM ',sp_table_name,' WHERE ',sp_where_param,' = \'',sp_where_value,'\'');
PREPARE stmt1 FROM #temp1;
EXECUTE stmt1;
END
Maybe without out variable also doesn't work :(
Try to use user variable -
CREATE DEFINER = 'root'#'localhost'
PROCEDURE test3 (OUT `sp_result` int(11), IN `sp_where_param` varchar(100), IN `sp_where_value` varchar(100), IN `sp_table_name` varchar(100))
NO SQL
BEGIN
DECLARE tbl_id varchar(100);
SET tbl_id = CONCAT(sp_table_name, '_id');
SET #temp1 = CONCAT('SELECT COUNT(', tbl_id, ') INTO #sp_result FROM ', sp_table_name, ' WHERE ', sp_where_param, ' = \'', sp_where_value, '\'');
PREPARE stmt1 FROM #temp1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
set sp_result = #sp_result;
END
...and add DEALLOCATE PREPARE statement.
it should be-
SET tbl_id = CONCAT(sp_table_name,'_id');
SET #temp1=CONCAT('SELECT count(',tbl_id,') INTO
like this
SET #tbl_id:= CONCAT(sp_table_name,'_id');
SET #temp1:=CONCAT('SELECT count(',tbl_id,') INTO
I have a stored procedure that works, but when I pass a value with a hyphen in it, it errors.
I call my procedure with a value like call create('server-v01',555); and I get the following error:
ERROR 1064 (42000): 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 '-v01' at line 1
My procedure is as follows:
DELIMITER $$
CREATE PROCEDURE ct(tname varchar(20), sessionsnum INT(11))
BEGIN
DECLARE maxnum INT;
SET #s = CONCAT('INSERT INTO sessions_poll (server_name,sessions_num) VALUES(''',tname,''',',sessionsnum,')');
PREPARE stm FROM #s;
EXECUTE stm;
SET #s = CONCAT('DROP TABLE IF EXISTS ', tname);
PREPARE stm FROM #s;
EXECUTE stm;
SET #s = CONCAT('CREATE TABLE ', tname, ' (num INT, max INT)');
PREPARE stm FROM #s;
EXECUTE stm;
SELECT #maxnum:=max(sessions_num) INTO maxnum FROM sessions_poll WHERE server_name=tname AND DATE(ts)=CURDATE();
SET #s = CONCAT('INSERT INTO ', tname, ' (num,max) VALUES (', sessionsnum,',',maxnum,')');
PREPARE stm FROM #s;
EXECUTE stm;
END $$
DELIMITER ;
My question is, how can I handle a variable with a hyphen in it?
Your question is not how to handle variable with a dash, but how to handle a table with a dash. Your procedure tries to create a table with a name specified in tname. To create (or drop) a table like this you need to quote it with backticks.
DROP TABLE IF EXISTS `server-01`;
In particular you need to
SET #s = CONCAT('DROP TABLE IF EXISTS `', tname, '`');
and the same for other instances.
Whether this is what you really want to do is a question, though ;-)
I am trying to call a procedure which compiles successfully but on calling I get this error:
Query: call proc5
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 'NULL' at line 1
This is my Stored procedure:
DELIMITER $$
CREATE DEFINER = `root` #`localhost` PROCEDURE `proc5` ()
BEGIN
DECLARE done BOOL DEFAULT FALSE ;
DECLARE tablename VARCHAR (100) ;
DECLARE tracktables CURSOR FOR
SELECT
TABLE_NAME
FROM
information_schema.TABLES
WHERE TABLE_SCHEMA = 'db1' ;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = TRUE ;
OPEN tracktables ;
myloop :
LOOP
FETCH tracktables INTO tablename ;
IF done
THEN CLOSE tracktables ;
LEAVE myloop ;
END IF ;
SET #s = CONCAT(
'INSERT INTO db2.test1 SELECT * FROM ',
#tablename
) ;
PREPARE stmt1 FROM #s ;
EXECUTE stmt1 ;
DEALLOCATE PREPARE stmt1 ;
END LOOP ;
END $$
DELIMITER ;
Actually, I want to select all the tables from a database and insert those tables into one table which is in another database using MySQL Cursors. And when I call this stored procedure I get the above error.
The problem is that you are mixing declared variables and impromtu #vars.
var -> tablename does not equal var -> #tablename.
Change the set line to:
SET #s = CONCAT(
'INSERT INTO db2.test1 SELECT * FROM `'
,tablename
,'`'
) ;
Now it should work.
The backticks ` should not be needed, but are there just in case.