如何使用PHP PDO延迟PostgreSQL中的约束?

如何使用PHP PDO延迟PostgreSQL中的约束?,php,postgresql,pdo,transactions,constraints,Php,Postgresql,Pdo,Transactions,Constraints,我有两张桌子: CREATE TABLE main_table ( id integer NOT NULL, field character(10) NOT NULL, CONSTRAINT main_table_pkey PRIMARY KEY (field) ) WITH ( OIDS=FALSE ); 及 正如您所看到的,子表通过child\u table.child\u field->main\u table.field具有主表的外键 我想先在child_表中插入,然后

我有两张桌子:

CREATE TABLE main_table
(
  id integer NOT NULL,
  field character(10) NOT NULL,
  CONSTRAINT main_table_pkey PRIMARY KEY (field)
)
WITH (
  OIDS=FALSE
);

正如您所看到的,子表通过child\u table.child\u field->main\u table.field具有主表的外键

我想先在child_表中插入,然后在main_表中插入。例如:

INSERT INTO child_table(id, child_field) VALUES (1, '0123456789');
INSERT INTO main_table(id, field) VALUES(1, '0123456789');
首先,我认为交易对我有帮助。但即使我先执行“启动事务”,INSERT查询也会抛出约束错误,并且在提交之前事务会失败

在我尝试将可延迟指令添加到“启动事务”之后。同样的结果。然后,我将我的外键添加到我的外键的“Delerable Initial DEFERRED”,因此我得到:

CREATE TABLE child_table
(
  id integer NOT NULL,
  child_field character(10) NOT NULL,
  CONSTRAINT child_table_pkey PRIMARY KEY (id),
  CONSTRAINT main_table_field_fkey FOREIGN KEY (child_field)
      REFERENCES main_table (field) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED
)
WITH (
  OIDS=FALSE
);
ALTER TABLE child_table
  OWNER TO postgres;
在此之后,即使没有事务,我也可以通过命令行执行插入

但是无论如何,我不能用PDO PHP做同样的事情。我尝试了一些预先准备好的查询,但没有成功。即使是直接查询也不起作用:

$pdo->exec("INSERT INTO child_table(id, child_field) VALUES (1, '0123456789')");
$pdo->exec("INSERT INTO main_table(id, field) VALUES(1, '0123456789')");
启动事务也没有帮助。查询“设置所有延迟的约束”也没有帮助。我试图将'PDO::ATTR_PERSISTENT=>true'添加到init数组中。没有结果。所以请告诉我,我如何通过PHP按这个顺序执行这些查询?正如我所想,我必须通过一个事务执行这些查询,但是这个事务在提交之前不必检查约束。还是我错了

解决方案

问题不在于PDO,也不在于事务。表main_Table是由另一个角色创建的,由于所有者问题,提交数据似乎没有写入到main_Table中,所以子_Table抛出约束错误。很糟糕,主表并没有抛出所有者错误,所以问题并不明显

有人用这个解决方案回答我:

$pdo->beginTransaction();
$pdo->exec("INSERT INTO child_table(id, child_field) VALUES (1, '0123456789')");
$pdo->exec("INSERT INTO main_table(id, field) VALUES(1, '0123456789')");
$pdo->commit();

伙计,这是正确的解决方案,很抱歉我回答你,它不起作用。

真正的问题是,为什么你不能颠倒插入顺序?还是改变约束?我的例子只是我问题的简化例子。第一个插入实际上是for循环中的许多插入,而我的约束树更难。首先,所有的警察都已经创造出来了。在我的代码中,我无法对这些插入进行重新排序。主要问题(真正的问题)是为什么我的插入可以在命令行中工作,但不能在PDO中工作。在你链接的文章中,有一个MySQL问题被描述。我不知道,也许MySQL无法做到这一点。但是Postgres可以,因为我是通过命令行执行这些查询的。真正的问题是,为什么不能颠倒插入的顺序呢?还是改变约束?我的例子只是我问题的简化例子。第一个插入实际上是for循环中的许多插入,而我的约束树更难。首先,所有的警察都已经创造出来了。在我的代码中,我无法对这些插入进行重新排序。主要问题(真正的问题)是为什么我的插入可以在命令行中工作,但不能在PDO中工作。在你链接的文章中,有一个MySQL问题被描述。我不知道,也许MySQL无法做到这一点。但是Postgres可以,因为我通过命令行执行这些查询。
$pdo->beginTransaction();
$pdo->exec("INSERT INTO child_table(id, child_field) VALUES (1, '0123456789')");
$pdo->exec("INSERT INTO main_table(id, field) VALUES(1, '0123456789')");
$pdo->commit();