MySQL 从存储过程中检索 last_insert_id
Posted
技术标签:
【中文标题】MySQL 从存储过程中检索 last_insert_id【英文标题】:MySQL retrieve last_insert_id from stored procedure 【发布时间】:2020-05-20 09:40:46 【问题描述】:我正在使用 NodeJS 和 mysql 通过 post_tag 保存帖子及其标签:
DROP TABLE IF EXISTS post_tag;
DROP TABLE IF EXISTS post;
DROP TABLE IF EXISTS tag;
DROP PROCEDURE IF EXISTS select_all_posts;
DROP PROCEDURE IF EXISTS insert_post;
CREATE TABLE post (
id INT NOT NULL AUTO_INCREMENT,
title VARCHAR(45) NULL,
body TEXT NULL,
PRIMARY KEY (id));
CREATE TABLE tag (
id INT NOT NULL AUTO_INCREMENT,
tag VARCHAR(45) NULL,
PRIMARY KEY (id));
CREATE TABLE post_tag (
post_id INT NOT NULL,
tag_id INT NOT NULL,
PRIMARY KEY (post_id, tag_id),
INDEX fk_post_tag_tag1_idx (tag_id ASC),
INDEX fk_post_tag_post_idx (post_id ASC),
CONSTRAINT fk_post_tag_post
FOREIGN KEY (post_id)
REFERENCES post (id),
CONSTRAINT fk_post_tag_tag1
FOREIGN KEY (tag_id)
REFERENCES tag (id));
INSERT INTO post (id, title, body) VALUES (1, 'post 1', "Post body");
INSERT INTO post (id, title, body) VALUES (2, 'post 2', "Post body");
INSERT INTO tag (id, tag) VALUES (1, 'tag 1');
INSERT INTO tag (id, tag) VALUES (2, 'tag 2');
INSERT INTO post_tag (post_id, tag_id) VALUES (1, 1);
INSERT INTO post_tag (post_id, tag_id) VALUES (1, 2);
INSERT INTO post_tag (post_id, tag_id) VALUES (2, 1);
我创建了一个存储过程来插入新帖子:
-- Stored procedure to insert post and tags
DELIMITER $$
CREATE PROCEDURE insert_post(
IN title VARCHAR(45),
IN body TEXT
)
BEGIN
INSERT INTO post (title, body) VALUES (title, body);
END $$
DELIMITER ;
所以在节点中我可以做到:
var mysql = require("mysql2");
var connection = mysql.createConnection(
host: "127.0.0.1",
user: "test_database",
password: "test_database",
database: "test_database",
);
connection.connect();
const postTitle = JSON.stringify("Post 3");
const postBody = JSON.stringify("This is post 3 body");
const insertPostQuery = "CALL insert_post(" + postTitle + "," + postBody + " )";
connection.query(insertPostQuery, (error, results) =>
console.log(JSON.stringify(results, null, 4));
);
connection.end();
这会返回:
"fieldCount": 0,
"affectedRows": 1,
"insertId": 0,
"info": "",
"serverStatus": 2,
"warningStatus": 0
现在我想从存储过程中检索最后插入的id,所以我修改我的存储过程添加一个OUT last_inserted_id INT
参数,然后在INSERT之后赋值:
-- Stored procedure to insert post and tags
DELIMITER $$
CREATE PROCEDURE insert_post(
IN title VARCHAR(45),
IN body TEXT,
OUT last_inserted_id INT
)
BEGIN
INSERT INTO post (title, body) VALUES (title, body);
SET last_inserted_id = LAST_INSERT_ID();
END $$
DELIMITER ;
但是在节点中执行查询时,这将返回 undefined
而不是带有 last_inserted_id
值的 json。
我做错了什么?
【问题讨论】:
在我看来,将标量值作为函数返回的代码更符合逻辑... 嗨@Akina,谢谢。你能举个例子吗?只是一个草图,以了解您的意思。 您的 out 参数是第三个参数,但您使用两个参数调用该过程。将原始值直接注入 SQL 字符串也感觉不对。 感谢@ÁlvaroGonzález;儿子 ejemplos lo más sencillos posible。 Quiero ver si tengo opciones de volver a MySQL o si tengo que quedarme con los ORM。 【参考方案1】:你能举个例子吗?
CREATE FUNCTION insert_post_fn(
in_title VARCHAR(45),
in_body TEXT
)
RETURNS BIGINT
MODIFIES SQL DATA
BEGIN
INSERT INTO post (title, body) VALUES (in_title, in_body);
RETURN LAST_INSERT_ID();
END
使用方法:
SELECT insert_post_fn('Post title', 'This is post body') AS `LAST_INSERT_ID`;
CREATE PROCEDURE insert_post_proc(
IN in_title VARCHAR(45),
IN in_body TEXT,
OUT out_id BIGINT
)
BEGIN
INSERT INTO post (title, body) VALUES (in_title, in_body);
SET out_id = LAST_INSERT_ID();
END
使用方法:
CALL insert_post_proc('Post title', 'This is post body', @id);
SELECT @id AS `LAST_INSERT_ID`;
-- PS. Variable name used is random
-- PPS. Both statements must be executed
-- in the same connection and without reconnect
CREATE PROCEDURE insert_post_proc(
IN in_title VARCHAR(45),
IN in_body TEXT
)
BEGIN
INSERT INTO post (title, body) VALUES (in_title, in_body);
SELECT LAST_INSERT_ID() AS `LAST_INSERT_ID`;
END
使用方法:
CALL insert_post_proc('Post title', 'This is post body');
fiddle
【讨论】:
以上是关于MySQL 从存储过程中检索 last_insert_id的主要内容,如果未能解决你的问题,请参考以下文章