假设我在我的一张表中执行 MySQL INSERT
,并且该表的列 item_id
设置为 autoincrement
和 primary key
。
如何让查询在同一个查询中输出新生成的主键 item_id
的值?
目前我正在运行第二个查询来检索 id 但这似乎不是一个好的做法,因为这可能会产生错误的结果......
如果这是不可能的,那么确保我检索到正确 ID 的最佳做法是什么?
INSERT
查询中返回任何内容;为什么你认为它可能会产生错误的结果?
您需要使用 LAST_INSERT_ID()
函数:http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
例如:
INSERT INTO table_name (col1, col2,...) VALUES ('val1', 'val2'...);
SELECT LAST_INSERT_ID();
这将使您返回 您 插入的最后一行的 PRIMARY KEY
值:
生成的 ID 在每个连接的基础上维护在服务器中。这意味着函数返回给给定客户端的值是为影响该客户端的 AUTO_INCREMENT 列的最新语句生成的第一个 AUTO_INCREMENT 值。
因此,LAST_INSERT_ID()
返回的值是针对每个用户的,并且不受可能在服务器上运行的其他查询的影响来自其他用户。
当心!!如果尝试在 PHP 中返回此主键值,则为 LAST_INSERT_ID()
。
我知道这个线程没有标记 PHP,但是对于任何遇到这个答案的人来说,希望使用标准 mysql_query
调用从 PHP 脚本插入返回 MySQL 插入 id - 如果不捕获 SQL 错误,它不会工作并且不明显。
较新的 mysqli
支持多个查询 - LAST_INSERT_ID()
实际上是原始查询的第二个查询。
IMO 用于识别最后一个主键的单独 SELECT
比返回从先前 INSERT
操作生成的 AUTO_INCREMENT ID
的可选 mysql_insert_id()
函数更安全。
LAST_INSERT_ID
是每个连接的 MySQL 函数。如果您查询最后一个插入 ID,则可能有一个单独的连接执行了写入,您将获得错误的 ID。
mysql_insert_id()
也适用于每个连接,但它也会遭受奇怪的行为,如 Cliffordlife 的评论中的 stackoverflow.com/a/897374/1305910 所示——没关系,我们都应该一直在使用 mysqli
来自 LAST_INSERT_ID()
文档:
生成的 ID 在每个连接的基础上维护在服务器中
也就是说,如果您同时对脚本有两个单独的请求,它们不会影响彼此的 LAST_INSERT_ID()
(除非您可能正在使用持久连接)。
这就是你要找的东西!!!
select LAST_INSERT_ID()
这是 SQL Server
中使用的 SCOPE_IDENTITY()
函数的最佳替代方案。
您还需要记住,这仅在您的 Insert
查询之后触发 Last_INSERT_ID()
时才有效。那就是查询返回插入到模式中的 id。您无法获取特定表的最后插入 id。
有关详细信息,请通过链接 The equivalent of SQLServer function SCOPE_IDENTITY() in mySQL?
您将在查询结果中收到这些参数:
"fieldCount": 0,
"affectedRows": 1,
"insertId": 66,
"serverStatus": 2,
"warningCount": 1,
"message": "",
"protocol41": true,
"changedRows": 0
insertId
正是您所需要的。
(NodeJS-mySql)
如果在 python 中使用 pymysql
,则可以从光标使用 cursor.lastrowid
。
它是一个documented extension in PEP-249
DB API 标准,也适用于其他 Python MySQL 实现。
您需要将 LAST_INSERT_ID() 函数与事务一起使用:
START TRANSACTION;
INSERT INTO dog (name, created_by, updated_by) VALUES ('name', 'migration', 'migration');
SELECT LAST_INSERT_ID();
COMMIT;
http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
此函数将返回表中最后插入的主键。
如果在插入行之前需要该值:
CREATE FUNCTION `getAutoincrementalNextVal`(`TableName` VARCHAR(50))
RETURNS BIGINT
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE Value BIGINT;
SELECT
AUTO_INCREMENT INTO Value
FROM
information_schema.tables
WHERE
table_name = TableName AND
table_schema = DATABASE();
RETURN Value;
END
您可以在插入中使用它:
INSERT INTO
document (Code, Title, Body)
VALUES (
sha1( concat (convert ( now() , char), ' ', getAutoincrementalNextval ('document') ) ),
'Title',
'Body'
);
只需使用:
$last_id = mysqli_insert_id($conn);
如果您使用的是 PHP:在 PDO 对象上,您可以在插入后简单地调用 lastInsertId 方法。
否则,使用 LAST_INSERT_ID 您可以获得如下值:SELECT LAST_INSERT_ID();
我将 return $this->db->insert_id();
用于 Codeigniter
做这个:
$idc = DB::table('tb_clients')->insertGetId([
'ide' => $ide,
'nome' => $nome,
'email' => $email
]);
在 $idc 你会得到最后一个 id
我只是想在 PHP 中分享我的方法,你们中的一些人可能会发现它不是一种有效的方法,但这比其他可用选项好 100 倍。
生成一个随机键并将其插入到创建新行的表中。然后您可以使用该键来检索主键。使用更新来添加数据和做其他事情。
这样做有助于保护一行并拥有正确的主键。
我真的不推荐这个,除非你没有其他选择。
PRIMARY KEY
值,因为它是每个连接的 - 每个到服务器的连接都将为此维护它自己的值。我已经更新了答案以澄清这一点。