Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 开始的替代方案;犯罪因为事务会影响我使用上次插入ID()的能力?_Mysql_Database - Fatal编程技术网

Mysql 开始的替代方案;犯罪因为事务会影响我使用上次插入ID()的能力?

Mysql 开始的替代方案;犯罪因为事务会影响我使用上次插入ID()的能力?,mysql,database,Mysql,Database,我需要为每个条目插入多个表,为了安全起见,我决定将整个语句作为一个事务。但是,我的代码依赖于随着每次插入而更新的LAST_INSERT_ID(),并且似乎LAST_INSERT_ID()只在每次事务中更新。因此,我要么需要一个典型启动事务的替代方案;犯罪格式,或者我需要一个替代上一个_INSERT _ID()的方法来实现相同的目标 person和year和page都有自动递增的主键,这些键是表personinschoolyearbook中的外键 导致我提出这个问题的最初问题是,我有两个带有主键的

我需要为每个条目插入多个表,为了安全起见,我决定将整个语句作为一个事务。但是,我的代码依赖于随着每次插入而更新的LAST_INSERT_ID(),并且似乎LAST_INSERT_ID()只在每次事务中更新。因此,我要么需要一个典型启动事务的替代方案;犯罪格式,或者我需要一个替代上一个_INSERT _ID()的方法来实现相同的目标

personyear和page都有自动递增的主键,这些键是表personinschoolyearbook中的外键

导致我提出这个问题的最初问题是,我有两个带有主键的表和一个引用这两个键的关系表。如何使用一个数据条目同时更新所有三个?我已经研究了级联引用完整性,这将使外键自动更新,但我认为这不起作用,因为我的关系表有一个必须手动插入的非外键值(status)

START TRANSACTION;
INSERT INTO person (firstname, middlename, lastname, maidenname)
VALUES ('Test2fname', NULL, 'Test2lname', NULL);
INSERT INTO personinschoolyearbook (personid, yearandpageid, status)
VALUES (LAST_INSERT_ID(), 0, 'Test2status'); --The zero is a placeholder, to be replaced with the primary key id that will be created in the next INSERT INTO
SELECT @personid := LAST_INSERT_ID();
INSERT INTO yearandpage (yearincluded, page, schoolid, url) --Here is where the LAST_INSERT_ID() should update but doesn't
VALUES (0000, 00, 2, 'Test2url');
UPDATE personinschoolyearbook SET yearandpageid=LAST_INSERT_ID()
WHERE personinschoolyearbook.personid = @personid;
COMMIT;
现在,LAST_INSERT_ID()的值没有改变,在我的关系表PersonsChoolyEarbook中,应该具有取自yearandpage的新ID的列与取自person

LAST_INSERT_ID()的列的ID相同始终报告当前会话中生成的最新auto inc值。这不受交易的限制。您可以启动一个新事务,最后一个\u INSERT\u ID()仍将返回最新的auto inc值

mysql> create table foo (id serial primary key);

mysql> begin;

mysql> insert into foo () values ();
Query OK, 1 row affected (0.01 sec)

mysql> select last_insert_id() into @id1;
Query OK, 1 row affected (0.00 sec)

mysql> insert into foo () values ();
Query OK, 1 row affected (0.00 sec)

mysql> select last_insert_id() into @id2;
Query OK, 1 row affected (0.00 sec)

mysql> select @id1, @id2;
+------+------+
| @id1 | @id2 |
+------+------+
|    1 |    2 |
+------+------+
如果将值插入到具有自动inc的表中,但指定了非零值,因此阻止自动inc生成新id,则它也不会更改上次插入id()返回的值

如果主键不是auto inc,则INSERT不会更改LAST_INSERT_ID()为任何auto inc在当前会话中生成的最新ID返回的值,即使该ID是为另一个表或另一个事务生成的

mysql> create table bar (id bigint primary key); -- not AUTO_INCREMENT

mysql> insert into bar set id = 42;
Query OK, 1 row affected (0.01 sec)

mysql> select last_insert_id();
+------------------+
| last_insert_id() |
+------------------+
|                3 |
+------------------+

正如Bill Karwin的回答所述,LAST_INSERT_ID()不受交易的影响。它没有更新的原因是,当我插入到yearandpage时,如果条目已经存在,则不会输入任何数据,因此最后一次插入的ID()将没有值。Uueerdo提出了这可能是个问题,但由于我在运行代码时不知何故错过了重复输入错误,我认为插入操作可以正常工作

重复条目是我的问题的原因,需要在项目中加以说明,因此为了解决这个问题,我使用了Duplicate KEY UPDATE id=LAST_INSERT_id(id),您可以在

这是我的最终代码:

START TRANSACTION;
INSERT INTO person (firstname, middlename, lastname, maidenname)
VALUES ('Test2fname', NULL, 'Test2lname', NULL);
INSERT INTO personinschoolyearbook (personid, yearandpageid, status)
VALUES (LAST_INSERT_ID(), 0, 'Test2status');
SELECT @personid := LAST_INSERT_ID();
INSERT INTO yearandpage (yearincluded, page, schoolid, url)
VALUES (0000, 00, 2, 'Test2url') 
ON DUPLICATE KEY UPDATE yearandpageid = LAST_INSERT_ID(yearandpageid);
UPDATE personinschoolyearbook SET yearandpageid=LAST_INSERT_ID()
WHERE personinschoolyearbook.personid = @personid;
COMMIT;

您是否已确认前一年的页面插入成功?是的,它工作正常。您是否建议上次的\u insert\u ID()应该已更新,这意味着它与事务无关?因为我不确定是哪种情况。很高兴知道,谢谢。这意味着问题不在于最后一个插入ID(),而在于其他方面。我会继续排除故障。
START TRANSACTION;
INSERT INTO person (firstname, middlename, lastname, maidenname)
VALUES ('Test2fname', NULL, 'Test2lname', NULL);
INSERT INTO personinschoolyearbook (personid, yearandpageid, status)
VALUES (LAST_INSERT_ID(), 0, 'Test2status');
SELECT @personid := LAST_INSERT_ID();
INSERT INTO yearandpage (yearincluded, page, schoolid, url)
VALUES (0000, 00, 2, 'Test2url') 
ON DUPLICATE KEY UPDATE yearandpageid = LAST_INSERT_ID(yearandpageid);
UPDATE personinschoolyearbook SET yearandpageid=LAST_INSERT_ID()
WHERE personinschoolyearbook.personid = @personid;
COMMIT;