我试图将表名作为变量与其他一些变量一起传入,并创建一个if else条件。
@getTable1
查询是否为true,删除行='1'update
我的行@getTable2
已删除='1'这是我到目前为止所得到的,但由于我的语法不正确而收到错误。任何帮助将不胜感激。 谢谢。
CREATE DEFINER=`root`@`localhost` PROCEDURE `new_procedure`(
IN tableName VARCHAR(50),
IN cartName VARCHAR(11)
)
BEGIN
SET @getTable1 =
CONCAT("SELECT * FROM ", tableName,
" WHERE cartType='", cartName, "' AND deleted='1'");
PREPARE stmt1 FROM @getTable1;
EXECUTE stmt1;
IF EXISTS @getTable1 (do nothing)
ELSE
BEGIN
SET @getTable2 =
CONCAT("UPDATE deleted FROM ", tableName,
" SET deleted='1'");
PREPARE stmt2 FROM @getTable2;
EXECUTE stmt2;
END
END
答案 0 :(得分:1)
首先,如果您想知道第一个SELECT查询是否返回任何结果,请使用SELECT COUNT(*)
并将其存储在用户定义的变量中。如果您不使用SELECT...INTO,那么它会生成一个结果集,存储过程将返回该结果集。
SET @cartName = cartName;
SET @getTable1 =
CONCAT("SELECT COUNT(*) INTO @deletedCount FROM `",
REPLACE(tableName, '`', '``'),
"` WHERE cartType=? AND deleted='1'");
PREPARE stmt1 FROM @getTable1;
EXECUTE stmt1 USING @cartName;
还尝试避免SQL注入漏洞。对值使用查询参数,并至少使用反引号来分隔表名。转义tableName中的文字反引号字符。
在用户定义的变量中得到此结果后,请检查该变量以查看它是否为零。
查看UPDATE的语法。 UPDATE语句中没有FROM关键字。在SET子句之前,您不能将列命名。如有疑问,请查看手册中的语法:https://dev.mysql.com/doc/refman/5.7/en/update.html
IF @deletedCount = 0 THEN
BEGIN
SET @getTable2 =
CONCAT("UPDATE `",
REPLACE(tableName, '`', '``'),
"` SET deleted='1'"
-- WHERE...?
);
PREPARE stmt2 FROM @getTable2;
EXECUTE stmt2;
END
你的UPDATE中是否应该有cartType
的WHERE子句?似乎应该有,否则您将更新所有购物车类型的所有行。您使用的语法中没有任何内容使更新仅适用于第一个SELECT中的匹配行。每个SQL语句都是无上下文的(MySQL不支持可更新游标)。
答案 1 :(得分:1)
您的IF
语法是关闭的,但是,您甚至不需要它。
只需UPDATE
行,然后检查是否需要该行。
DELIMITER //
CREATE DEFINER=`root`@`localhost` PROCEDURE new_procedure(
IN tableName VARCHAR(50),
IN cartName VARCHAR(11)
)
BEGIN
PREPARE stmt FROM CONCAT('UPDATE deleted FROM ', tableName,
' SET deleted = 1 WHERE cartType=''', cartName,
''' AND deleted <> 1');
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;
如果要检查是否发生了更新,可以执行以下操作:
-- Place this just after the EXECUTE statement:
IF FOUND() THEN
-- do your stuff if updated...
ELSE
-- do your stuff if not updated...
END IF;