动态表名称在If / Else子句MySQL预处理语句中

时间:2017-09-10 21:02:58

标签: mysql stored-procedures

我试图将表名作为变量与其他一些变量一起传入,并创建一个if else条件。

  • 首先检查@getTable1查询是否为true,删除行='1'
  • 如果为true则不执行任何操作,否则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

2 个答案:

答案 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;