MySQL 存储过程在参数中传递数字数组

问题描述 投票:0回答:4

我不确定我做错了什么......

我有一个简单的疑问:

SELECT * FROM locations WHERE (ID IN (1, 2, 3, 4, 5));

现在我只是将该查询放入一个带有 LONGTEXT 类型参数的存储过程中

sp_FetchMultipleLocations(IN argLocations LONGTEXT)
BEGIN
    SELECT * FROM locations WHERE (ID IN (argLocations));
END;

然后我调用该参数中具有多个值的存储过程:

CALL sp_FetchMultipleLocations('1, 2, 3, 4, 5');

但是 where 子句中的 IN 语句似乎不起作用,它只显示了第一个(1)位置...为什么会这样?

谢谢

mysql stored-procedures parameters where-clause
4个回答
5
投票

参数是一个单一的整体字符串。仅仅因为您在存储过程内的

IN
子句中使用该参数并不意味着 MySQL 知道它应该将该 csv 字符串拆分为单独的值 - 它不知道 CSV 是什么,也不应该这样做。

你必须使用动态sql,例如在伪代码中:

procedure foo(in args longtext)
begin
    sql = concat('SELECT ... WHERE foo IN (', args, ')')
    execute @sql
end

1
投票

今天在此页面

找到了这个
SET @c = 'xxx,yyy,zzz';
SELECT * from table 
WHERE FIND_IN_SET(columnname,@c);

对我有用。


0
投票

你只需要使用分割函数,用逗号来完成。

你现在传递它的方式是单个字符串。


0
投票

所以这是我已经困扰很长时间的一个问题,能够传入用户 ID、电子邮件或任何其他值数组的数组,并对所有匹配的记录执行数据库操作。

例如:
假设您网站的管理员用户想要对软件的用户进行批量更新,禁用他们的帐户。也许他们会看到一个用户列表,并选中其中一些用户旁边的“禁用”框。现在他们单击“禁用用户”按钮。执行此操作的较慢方法是(在服务器端)迭代每个 userId 并调用某些函数,例如

User.disable(userId)

更有效的方法是将 userId 数组传入数据库,并让它对所有需要的记录立即执行操作。这是如何完成的。

您的存储过程应如下所示:


-- userIds is a json string of an array of integers, e.g. "[1, 2, 3]"
CREATE PROCEDURE `user.disable`(userIds VARCHAR(4000))
BEGIN
    UPDATE user SET enabled = 0 WHERE JSON_CONTAINS(userIds, id);
END

调用此函数的代码可能如下所示(PHP):


class User {
    public static function disableMany(array $userIds): bool
    {
        $strUserIds = json_encode($userIds);
        $query = "CALL `user.disable`($strUserIds)";
        $result = mysqli_query($con, $query);
        return $result !== false;
    }
}

我希望这有帮助,祝你好运。

© www.soinside.com 2019 - 2024. All rights reserved.