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
Related
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;
I have a procedure call that updates a set of data and then returns the data set for my to render. Everything works fine except that, I cant do both operations at once. If I do the update, then the procedure, won´t return any value and vice versa. I have seen some answers suggesting to use temptables but I could not find how to retrieve the dataset. I appreciate any help even if it comes to improving my query.
CREATE DEFINER=`root`#`localhost` PROCEDURE `prueba`(IN `idUsuario` INT)
MODIFIES SQL DATA
BEGIN
DECLARE flag INT DEFAULT FALSE;
DECLARE done INT DEFAULT FALSE;
DECLARE idNotificacion INT DEFAULT 0;
DECLARE cont INT DEFAULT 0;
DECLARE resultset CURSOR FOR SELECT id FROM notificaciones WHERE involvedA_idUsuario=idUsuario AND active=1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN resultset;
SET #query = "SELECT * FROM notificaciones n WHERE n.id IN('null'";
the_loop: LOOP
FETCH resultset INTO idNotificacion;
IF done THEN
LEAVE the_loop;
END IF;
SET cont = cont + 1;
SET flag = TRUE;
SET #query = CONCAT(#query," , " ,idNotificacion);
UPDATE notificaciones SET active=0 WHERE id=idNotificacion;
END LOOP the_loop;
CLOSE resultset;
IF flag THEN
SET #query = CONCAT(#query, ")");
PREPARE stmt FROM #query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END IF;
END
Do you really need a cursor? An option like this, maybe it can be useful:
/* Procedure structure for procedure `prueba` */
/*!50003 DROP PROCEDURE IF EXISTS `prueba` */;
DELIMITER $$
CREATE PROCEDURE `prueba`(`idusuario` INT)
BEGIN
DECLARE `ids` LONGTEXT DEFAULT NULL;
SELECT GROUP_CONCAT(`id`) INTO `ids`
FROM `notificaciones`
WHERE `involveda_idusuario` = `idusuario` AND `active` = 1;
IF (`ids` IS NOT NULL) THEN
SET #`stmt` := CONCAT('UPDATE `notificaciones`
SET `active` = 0
WHERE `id` IN (', `ids`, ')');
PREPARE `exec` FROM #`stmt`;
EXECUTE `exec`;
SET #`stmt` := CONCAT('SELECT `id`, `involveda_idusuario`, `active`
FROM `notificaciones` `n`
WHERE `n`.`id` IS NULL OR `n`.`id` IN (', `ids`, ')');
PREPARE `exec` FROM #`stmt`;
EXECUTE `exec`;
DEALLOCATE PREPARE `exec`;
END IF;
END$$
DELIMITER ;
You must be careful with GROUP_CONCAT and the system variable group_concat_max_len.
SQL Fiddle demo
The error mysql is throwing is
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
My using phpmyadmin to wreite procedures.
and my stored procedure is
BEGIN
DECLARE page_limit int(100);
DECLARE page_no VARCHAR(100);
DECLARE rstarts int(100) DEFAULT 1;
DECLARE rends int(100) DEFAULT 15;
DECLARE query varchar(255) ;
set query = ' select brandid from brandinfo limit #rstarts,#rends';
PREPARE stmt FROM #query;
set rstarts = 15;
set rends =1;
EXECUTE stmt using #rstarts,#rends;
DEALLOCATE PREPARE stmt;
END
Declared variables and variables beginning with # are two different stories. Read about user defined variables (the ones with #).
DELIMITER $$
CREATE PROCEDURE your_procedure_name()
BEGIN
SET #rstarts = 1;
SET #rends = 15;
set #query = 'select brandid from brandinfo limit ?, ?';
PREPARE stmt FROM #query;
EXECUTE stmt using #rstarts, #rends;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;
Also in your query string you want to use ? as parameters, not the variable names. And you might miss on setting the delimiter to something different than ;
Quick question,
using the code bellow, im able to use a sp to perform a delete from any table, but i dont know how to use concat to delete with the where statement.
CREATE DEFINER = `root`#`%` PROCEDURE `fn_del_t`(in t_name varchar(50), isrv char(50))
BEGIN
set #table_name = t_name;
set #iserver = isrv;
# not working with where.
set #sql_text = concat('delete from ',#table_name, 'where iserver =',#iserver);
# ---- not working with where
prepare stm from #sql_text;
execute stm;
DEALLOCATE prepare stm;
END;
call fn_del_t('the_table','localhost');
The error im receiving is:
[SQL] call fn_del_t('the_table','localhost');
[Err] 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 'iserver =localhost' at line 1
Sorry for my english.
Able to solve with:
CREATE DEFINER = `root`#`%` PROCEDURE `fn_del_t`(in t_name varchar(50), isrv char(50))
BEGIN
set #table_name = t_name;
set #iserver = isrv;
#
set #sql_text = concat("delete from ",#table_name," where iserver ='",#iserver,"'");
prepare stm from #sql_text;
execute stm;
DEALLOCATE prepare stm;
END
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