insert…SELECT语句的mysql\u insert\u id()
我正在做类似的插入…选择查询insert…SELECT语句的mysql\u insert\u id(),mysql,mysql-connector,Mysql,Mysql Connector,我正在做类似的插入…选择查询 INSERT INTO table (value1, value2) SELECT 'stuff for value1', 'stuff for value2' FROM DUAL WHERE NOT EXISTS (SELECT * FROM table WHERE value1='stuff for value1' AND value2='stuff for value2') LIMIT 1 ,其中表具有自动生成的id 当然,我想知道它是否被
INSERT INTO table (value1, value2)
SELECT 'stuff for value1', 'stuff for value2' FROM DUAL
WHERE NOT EXISTS (SELECT * FROM table
WHERE value1='stuff for value1' AND value2='stuff for value2')
LIMIT 1
,其中表具有自动生成的id
当然,我想知道它是否被插入。我假设这样做的方法是使用mysql\u insert\u id。如果没有发生插入,则返回0,如果发生插入,则返回1。查看更多详细信息
如果插入。。。SELECT语句被执行,并且不会自动执行
生成的值成功插入,mysql\u insert\u id返回
最后插入的行的ID
如果没有成功插入自动生成的ID,它将返回什么?这是文件打字错误吗
更新1
到目前为止,我在C中进行了测试,如果插入没有发生,mysql_insert_id始终返回0,即使最后一次插入成功,并且mysql_insert_id返回非零结果。A上述同一手册中的段落通过以下方式确认了该行为:
如果前面的语句未使用自动增量值,mysql\u insert\u id将返回0
mysql_insert_id的值仅受当前客户端连接中发出的语句的影响。它不受其他客户发表的声明的影响
最后一个\u INSERT \u ID SQL函数将包含成功插入的第一个自动生成值的值。在语句之间不会重置LAST_INSERT_ID,因为该函数的值保留在服务器中
如果你不能在代码中知道你的插入是否有效,那么选择在很多情况下都是无用的。但这与上述说法完全矛盾。有人有过这样的经历吗
更新2
根据MariaDB手册,还建议在未发生插入的情况下,该值应为零:
mysql\u insert\u id函数返回查询生成的id
具有具有自动增量属性或值的列的表
有关last_INSERT_IDexpr的最后用法。如果最后一个查询不是
INSERT或UPDATE语句,或者如果修改的表没有
未找到具有自动增量属性和上次插入ID的列
使用时,此函数将返回零
它看起来将返回上次自动生成的id:
MariaDB [stackoverflow]> desc a;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| a | varchar(20) | YES | | NULL | |
| b | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
MariaDB [stackoverflow]> insert into a(a,b) values('haha', 'haha');
Query OK, 1 row affected (0.03 sec)
MariaDB [stackoverflow]> select LAST_INSERT_ID() from dual;
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 1 |
+------------------+
MariaDB [stackoverflow]> insert into a(a,b) select 'hi', 'hello' from dual;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
MariaDB [stackoverflow]> select LAST_INSERT_ID() from dual;
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
MariaDB [stackoverflow]> insert into a(a,b) select 'hi', 'hello' from dual where not exists (select * from a where a='hi' and b='hello') limit 1;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [stackoverflow]> select LAST_INSERT_ID() from dual;
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
它看起来将返回上次自动生成的id:
MariaDB [stackoverflow]> desc a;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| a | varchar(20) | YES | | NULL | |
| b | varchar(20) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
MariaDB [stackoverflow]> insert into a(a,b) values('haha', 'haha');
Query OK, 1 row affected (0.03 sec)
MariaDB [stackoverflow]> select LAST_INSERT_ID() from dual;
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 1 |
+------------------+
MariaDB [stackoverflow]> insert into a(a,b) select 'hi', 'hello' from dual;
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
MariaDB [stackoverflow]> select LAST_INSERT_ID() from dual;
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
MariaDB [stackoverflow]> insert into a(a,b) select 'hi', 'hello' from dual where not exists (select * from a where a='hi' and b='hello') limit 1;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
MariaDB [stackoverflow]> select LAST_INSERT_ID() from dual;
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
措辞可能更清楚,但它的意思是,如果您的插入导致错误,mysql_INSERT_id或SQL函数last_INSERT_id将根据先前成功的插入继续报告它所做的任何事情 下面是一个演示:
mysql> create table foo( id int auto_increment primary key);
mysql> create table bar( id int primary key);
mysql> insert into bar (id) values (1), (2), (10);
mysql> insert into foo select id from bar;
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 0 |
+------------------+
没有生成新的auto inc值,因为我的INSERT提供了要插入的特定值
让我们生成一些新值:
mysql> insert into foo select null from bar;
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 11 |
+------------------+
这是预期的,因为last_insert_id将报告批插入生成的第一个id。您必须计算出插入了多少行,才能知道其余的id。以这种方式生成的id保证是唯一和连续的
现在,让我们尝试插入一些重复项,这将导致错误:
mysql> insert into foo select id from bar;
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
现在是文档中这句话的要点:上次插入id报告的内容没有变化
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 11 |
+------------------+
mysql> insert into foo select id+20 from bar;
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 11 |
+------------------+
同样,即使插入成功,但不会导致生成任何新的auto inc值,上次插入id报告的内容也不会发生变化
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 11 |
+------------------+
mysql> insert into foo select id+20 from bar;
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 11 |
+------------------+
许多人认为last_insert_id报告了最近插入的主键值,但它没有。它只报告自动inc功能自动生成的值。措辞可能更清楚,但它的意思是,如果插入导致错误,mysql\u INSERT\u id或SQL函数last\u INSERT\u id将根据先前成功的插入继续报告它所做的任何事情 下面是一个演示:
mysql> create table foo( id int auto_increment primary key);
mysql> create table bar( id int primary key);
mysql> insert into bar (id) values (1), (2), (10);
mysql> insert into foo select id from bar;
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 0 |
+------------------+
没有生成新的auto inc值,因为我的INSERT提供了要插入的特定值
让我们生成一些新值:
mysql> insert into foo select null from bar;
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 11 |
+------------------+
这是预期的,因为last_insert_id将报告批插入生成的第一个id。您必须计算出插入了多少行,才能知道其余的id。以这种方式生成的id保证是唯一和连续的
现在,让我们尝试插入一些重复项,这将导致错误:
mysql> insert into foo select id from bar;
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
现在是文档中这句话的要点:上次插入id报告的内容没有变化
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 11 |
+------------------+
mysql> insert into foo select id+20 from bar;
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 11 |
+------------------+
同样,即使插入成功,但不会导致生成任何新的auto inc值,上次插入id报告的内容也不会发生变化
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 11 |
+------------------+
mysql> insert into foo select id+20 from bar;
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
| 11 |
+------------------+
许多人认为last_insert_id报告了最近插入的主键值,但它没有。它只报告自动inc功能自动生成的值。是您的朋友。如果成功插入行,则该值将大于0,除非返回my_ulonglong-1,这表示失败。在本例中,由于最多插入1行,因此
只需检查它是否返回1。是您的朋友。如果成功插入行,则该值将大于0,除非返回my_ulonglong-1,这表示失败。在您的情况下,由于最多插入1行,您只需检查它是否返回1。与读取的内容完全一致。。如果插入失败的原因不是错误-它将获得最后插入的id-最后插入的id可能是昨天、上周插入的。。无论何时仅是先前成功的最后一个插入id。与读取内容完全相同。。如果插入失败的原因不是错误-它将获得最后插入的id-最后插入的id可能是昨天、上周插入的。。无论何时只是先前成功的最后一个插入id。感谢您的提示。所以建议先调用mysql\u受影响的\u行,如果是1,则调用mysql\u insert\u id,对吗?因为如果发生插入,我需要一个id。这似乎是一个选项。但是你知道mysql\u insert\u id for insert…select吗?为什么医生这么困惑?如果MySQL文档是正确的,为什么在MariaDB中没有提到它?我不知道为什么MySQL文档如此混乱,你可以要求他们澄清。受影响的行、最后一个插入id通过MySQL协议发送到客户端,并打包在OK数据包中。在任何update语句上,无论INSERT是否包含SELECT、update或DELETE。我真的建议对insert/select执行与任何更新相同的操作,即检查是否存在任何受影响的行,然后检索您的ID。这是最佳答案,顺便说一句,根据语言/驱动程序,此信息无需任何其他查询即可获得。java示例:int affectedRows=stmt.executeUpdateINSERT INTO select。。。;谢谢你的提示。所以建议先调用mysql\u受影响的\u行,如果是1,则调用mysql\u insert\u id,对吗?因为如果发生插入,我需要一个id。这似乎是一个选项。但是你知道mysql\u insert\u id for insert…select吗?为什么医生这么困惑?如果MySQL文档是正确的,为什么在MariaDB中没有提到它?我不知道为什么MySQL文档如此混乱,你可以要求他们澄清。受影响的行、最后一个插入id通过MySQL协议发送到客户端,并打包在OK数据包中。在任何update语句上,无论INSERT是否包含SELECT、update或DELETE。我真的建议对insert/select执行与任何更新相同的操作,即检查是否存在任何受影响的行,然后检索您的ID。这是最佳答案,顺便说一句,根据语言/驱动程序,此信息无需任何其他查询即可获得。java示例:int affectedRows=stmt.executeUpdateINSERT INTO select。。。;