【问题标题】:How to create a procedure to insert which returns the inserted row如何创建一个插入的过程,该过程返回插入的行
【发布时间】:2018-11-04 13:25:20
【问题描述】:

这是我当前的 SQL:

CREATE PROCEDURE addBlog(@title VARCHAR(255), @body VARCHAR(255), OUT @uuid INT) BEGIN
    INSERT INTO blogs b (b.title, b.detail) VALUES (@title, @body);
    SELECT LAST_INSERT_ID() INTO @uuid;
    SELECT @uuid;
END

抛出此错误的原因(直接来自 SQL 导出):

1064 - 您的 SQL 语法有错误;查看与您的 MariaDB 服务器版本相对应的手册,了解在 '@title VARCHAR(255), @body VARCHAR(255), OUT @uuid INT) BEGIN 附近使用的正确语法 在第 1 行插入博客'

我的数据库在uuid INT (255) 上有一个AUTO_INCREMENT PRIMARY KEY,我想使用此过程返回它。任何帮助都会很棒。

我的桌子是这样的:

CREATE TABLE `blogs` (
  `uuid` int(255) NOT NULL,
  `title` varchar(1024) NOT NULL,
  `detail` varchar(1024) NOT NULL,
  `user_id` int(255) NOT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `blogs`
  ADD PRIMARY KEY (`uuid`),
  ADD KEY `user_id` (`user_id`);

ALTER TABLE `blogs`
  MODIFY `uuid` int(255) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;

ALTER TABLE `blogs`
  ADD CONSTRAINT `blogs_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users` 
(`uuid`) ON DELETE NO ACTION ON UPDATE NO ACTION;

更新的 SQL:

CREATE PROCEDURE addBlog(
    IN in_title VARCHAR(255),
    IN in_body VARCHAR(255), 
    IN in_user INT(255),
    OUT out_uuid INT
) BEGIN
    INSERT INTO `blogs` (`title`, `detail`, `user_id`) VALUES (in_title, in_body, in_user);
    SELECT LAST_INSERT_ID() INTO out_uuid;
    SELECT out_uuid;
END;

【问题讨论】:

  • 你的问题说你想返回插入的行。这将返回该行的uuid。此外,您可以让最后一个 SELECT 说出 SELECT LAST_INSERT_ID() AS out_uuid; 并获得与最后两个 SELECT 相同的结果。此外,int(255) 也不是问题。对 32 位值使用 INT,对 64 位值使用 BIGINT
  • 抱歉,如果更适用,您可以更新问题标题以说出行 ID,我不知道如何措辞 @O.Jones

标签: mysql sql innodb delimiter


【解决方案1】:

您缺少参数类型定义,例如INOUT 等。另外,我认为您不需要在参数定义中使用@

另外,我喜欢确保存储过程/触发器等中的变量/参数的名称与其中使用的任何表/列名称不同。

另外,如果您还没有这样做,您需要将 Delimiter 重新定义为 ; 以外的其他内容(例如,$$);最后重新定义回;

DELIMITER $$ -- define the delimiter

CREATE PROCEDURE addBlog(IN title_in VARCHAR(255), -- added suffix "in" to param name
                         IN body_in VARCHAR(255), 
                         OUT uuid_out INT) BEGIN
...... 

END $$ -- end of stored procedure
DELIMITER ; -- redefine delimiter back to ;

【讨论】:

  • CREATE PROCEDURE addBlog( IN in_title VARCHAR(255), IN in_body VARCHAR(255), IN in_user INT(255), OUT out_uuid INT ) BEGIN INSERT INTO blogs (title, detail, user_id) VALUES (in_title, in_body, in_user) 处仍然出现错误 - 我将其更新为包含in_user,因为我认为它不能为NULL
  • 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 7 - 我将更新问题以显示最新的 SQL
  • 您更新的解决方案有效!我得谷歌DELMITER我不知道那是什么以及它是如何工作的,非常感谢!
  • @Jaquarh 要求 MySQL/Mariadb 解析器不会停止在 ; 并立即读取/编译完整的存储过程定义。
【解决方案2】:

您的语法是来自多个数据库的奇怪混搭。我想你想要:

CREATE PROCEDURE addBlog (
    in_title VARCHAR(255),
    in_body VARCHAR(255),
    OUT out_uuid INT
)
BEGIN
    INSERT INTO blogs (title, detail)
        VALUES (in_title, in_body);
    SELECT LAST_INSERT_ID() INTO out_uuid;
    -- SELECT out_uuid;
END;

Here 是一个 dbfiddle。

【讨论】:

  • 执行此操作返回此错误 :( 1064 - 您的 SQL 语法有错误;请查看与您的 MariaDB 服务器版本相对应的手册,以在第 7 行的 '' 附近使用正确的语法跨度>
  • 是不是因为我没有声明创建博客的用户是谁?我想稍后再执行此操作,也许我必须在该查询中执行此操作?
  • 我尝试添加 in_user INT(255)INSERT INTO blogs (title, detail, user_id) VALUES (in_title, in_body, in_user); 仍然抛出错误
  • @Jaquarh。 . .与预期相反,我测试了链接中显示的代码。
  • 也许你甚至不想要或不需要最终的SELECT out_uuid;
猜你喜欢
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 2012-05-04
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多