【问题标题】:MySQL stored procedure that accepts string with multiple parameters接受具有多个参数的字符串的 MySQL 存储过程
【发布时间】:2012-12-07 07:11:24
【问题描述】:

我想创建一个存储过程,它接受 IN 参数中的所有值作为单个字符串。

DELETE FROM object 
WHERE Type NOT IN 
    ('ListGrid',
     'TextField',
     'SpinBox',
     'MenuButton',
     'ListGrid',
     'RadioButton',
     'DropDown',
     'PopUp',
     'Element',
     'Checkbox',
     'TreeDropDown',
     'TblColumn',
     'Button',
     'Link',
     'Filter',
     'TblRow',
     'GridRow',
     'Popup')

这是我尝试过的一个示例,但它不起作用。

DELIMITER //
CREATE PROCEDURE deleteObjectTypes(IN p_type VARCHAR(255))
BEGIN
SET @query = CONCAT ('DELETE FROM object WHERE Type NOT IN (',p_type,')');
PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END //
DELIMITER ;

我收到以下错误:

#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 ''List)' at line 1

运行此查询时:

CALL deleteObjectTypes("'ListGrid1','TextField1','SpinBox1','MenuButton1','ListGrid2','TextField2','SpinBox2','MenuButton2','ListGrid3','TextField3','SpinBox3','MenuButton3','ListGrid4','TextField4','SpinBox4','MenuButton4','ListGrid5','TextField5','SpinBox5','MenuButton5','ListGrid6','TextField6','SpinBox6','MenuButton6'")

【问题讨论】:

  • 您在运行此程序时是否收到错误消息?
  • 发布更新,见编辑。
  • 该错误与您目前提供的代码的任何部分都不匹配。但看起来你可能有一个额外的' 在那里

标签: mysql sql stored-procedures


【解决方案1】:

您需要将 VARCHAR 大小更改为其最大值(或较低的有效值)。

DELIMITER //
CREATE PROCEDURE deleteObjectTypes(IN p_type VARCHAR(65535))
BEGIN
    SET @query = CONCAT ('DELETE FROM object WHERE Type NOT IN (',p_type,')');
    PREPARE stmt FROM @query;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END //
DELIMITER ;

但是,请注意,如果您使用多字节字符集,则限制会更低:

VARCHAR(21844) CHARACTER SET utf8

here所见。

【讨论】:

  • 255个字符后就不行了,有什么办法解决吗?
  • 对于通过字符串而不是直接查询执行 sql 非常有用。我从来不知道如何使用 sql 查询字符串执行。
  • @Lin 是的,如果您需要从数据库中动态构建查询,这将非常实用。
【解决方案2】:

(对不起,我无法添加 cmets 太低的声誉) 您的程序看起来不错,也许问题出在其他地方?请注意,我们已将 varchar 定义为 255 个字符,而您提供的示例超过了这个数字(291 个字符)

【讨论】:

  • 有没有办法解决这个问题?
  • 当你运行存储过程时,它会给你一个关于可变大小的错误吗?我不认为可变大小是问题,但我可能是错的
  • 当我用 255 个字符运行它时,它可以工作,当我用 256 个字符运行它时,它不会。
  • 是的,它很容易像 Francis 写的那样定义更多的 varchar 长度;)
【解决方案3】:

你应该试试这个(缩短的例子):

DELETE 
FROM 
  object 
WHERE 
  NOT FIND_IN_SET( Type, 'ListGrid,TextField,SpinBox,MenuButton,ListGrid' );

和存储过程

DELIMITER //
CREATE PROCEDURE deleteObjectTypes(IN p_type VARCHAR(255))
BEGIN
  DELETE 
  FROM 
    object 
  WHERE 
    NOT FIND_IN_SET( Type, p_type );
END //
DELIMITER ;

CALL deleteObjectTypes( 'ListGrid1,TextField1,SpinBox1,MenuButton1,ListGrid2,TextField2,SpinBox2,MenuButton2,ListGrid3,TextField3,SpinBox3,MenuButton3,ListGrid4,TextField4,SpinBox4,MenuButton4,ListGrid5,TextField5,SpinBox5,MenuButton5,ListGrid6,TextField6,SpinBox6,MenuButton6' );

【讨论】:

  • 他们说问题在于达到了变量限制
  • @Malachi thanx 表示反对,但即使使用演示数据(字符串包含 251 个字符),我的解决方案也不会出错。我给了一个工作简单的injection-safe解决方案
  • 我知道这是一个非常古老的线程,但值得一提的是,虽然它确实有效,但由于 FIND_IN_SET 不使用索引,它非常慢......所以添加这个时要小心在项目的早期,如果您使用此解决方案,它将成为越来越多的瓶颈。
猜你喜欢
  • 2016-11-29
  • 2014-05-24
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多