如何创建 SQL 存储过程以插入多个值

Posted

技术标签:

【中文标题】如何创建 SQL 存储过程以插入多个值【英文标题】:How to create an SQL stored procedure to insert multiple values 【发布时间】:2019-01-12 21:55:48 【问题描述】:

我有以下语句,它接受一个值数组并将它们存储在我的 mysql RDS 中:

INSERT INTO items (item_id, item_name, item_description) VALUES ?

我将它与不提供转义机制来防止注入的 AWS Appsync 一起使用,因此我想在我的 RDS 中使用存储过程来防止injection。

该语句将用于创建多个项目,因此将传入一个值数组。

如何创建一个存储过程来将多个值插入一个表中?我在下面的示例中提到了带有单个参数的 select 语句,但我不确定如何将其应用于具有多个参数的更复杂的情况,如上述语句中所示。

CREATE PROCEDURE listPets (IN type_param VARCHAR(200))
  BEGIN
     PREPARE stmt FROM 'SELECT * FROM Pets where type=?';
     SET @type = type_param;
     EXECUTE stmt USING @type;
     DEALLOCATE PREPARE stmt;
  END

【问题讨论】:

【参考方案1】:
CREATE PROCEDURE listPets (IN p_itemid INT, IN p_itemname VARCHAR(200), 
      IN p_itemdesc VARCHAR(200))
BEGIN
    PREPARE stmt FROM 'INSERT INTO items (item_id, item_name, item_description) VALUES (?, ?, ?)';
    SET @id = p_itemid, @name = p_itemname, @description = p_itemdesc;
    EXECUTE stmt USING @id, @name, @description;
    DEALLOCATE PREPARE stmt;
END

请参阅 PREPARE 和 EXECUTE 上的文档。

提示:您可能希望使用这种替代 INSERT 语法:

PREPARE stmt FROM 'INSERT INTO items SET item_id=?, item_name=?, item_description=?';

它是 MySQL 对 SQL 的非标准扩展,可以更轻松地匹配列和 ? 占位符。但它不支持多行插入。

【讨论】:

我需要使用多行插入。只是想知道如何使用上面概述的格式将值数组传递到这个准备语句中 MySQL 没有数组类型。存储过程只能采用一组固定的标量参数。但是我不确定你为什么说 Appsync 不支持参数化 INSERT,我在这个博客上找到了一个例子:aws.amazon.com/blogs/mobile/… 我使用的是来自您的链接的确切变量映射,但与他们的支持代表交谈时,他说这种格式不能防止注入。我主要是前端程序员,不太熟悉。他将我推荐到以下链接:docs.aws.amazon.com/appsync/latest/devguide/… 哇,太令人失望了。 Appsync:设计上不安全。如果是我,这足以让我像烫手山芋一样放弃 Appsync 并使用其他语言或平台。 我当时正在考虑改用像 DynamoDB 这样的 nosql 设计,但考虑到我所有的关系,我认为这会让我倒退很长一段路。他们说这个 Appsync RDS 组合是测试版,所以我希望他们能在未来增加更好的安全性。现在我可能只使用一个 lambda 节点函数来准备我的 sql 语句并传递给 Appsync 解析器。我想它会减慢速度,但可能会降低复杂性【参考方案2】:

如果您打算更新现有记录:

CREATE PROCEDURE LIST_Pets
(
    --These are the Variables/columns you need to enter data into to update
    @item_name VARCHAR(15),
    @item_description VARCHAR(30),

    --These are the variables used to get the correct record which needs update
    @item_id INT
)
AS
BEGIN
UPDATE TABLE type_param
SET item_name = ISNULL(item_name, @item_name)--if the item_name is null it will insert @item_name
SET item_description = ISNULL(item_description, @item_description)
WHERE item_id = @item_id

【讨论】:

以上是关于如何创建 SQL 存储过程以插入多个值的主要内容,如果未能解决你的问题,请参考以下文章

sql server 存储过程传参问题. 一个参数如何可以输入多个参数值

SQL Server 存储过程创建临时表并插入值

如何比较两个表的列并将值插入到基于 SQL Server 中存储过程中的比较的新表中

oracle中的存储过程如何返回查询到的多个值?

如何修复存储过程 Oracle PL/SQL 的错误?

SQL server简单的存储过程问题?