如何使用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();