I have two tables:
CREATE TABLE main_table
(
id integer NOT NULL,
field character(10) NOT NULL,
CONSTRAINT main_table_pkey PRIMARY KEY (field)
)
WITH (
OIDS=FALSE
);
And
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
)
WITH (
OIDS=FALSE
);
As you can see child_table has foreign key to main_table by child_table.child_field -> main_table.field
I want to have possibility to insert first in child_table then in main_table. For example:
INSERT INTO child_table(id, child_field) VALUES (1, '0123456789');
INSERT INTO main_table(id, field) VALUES(1, '0123456789');
First I thought that transactions help me. But even if I execute 'START TRANSACTION' first INSERT query throws constraint error and transaction fails before commit.
After I tried to add DEFERRABLE instruction to 'START TRANSACTION'. The same result. Then I add to my foreigh key to 'DEFERRABLE INITIALLY DEFERRED' to my foreigh key, so I've got:
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;
After this I've got posibillity to execute my INSERTs by command line even without transaction.
But anyway I could not to do the same with PDO PHP. I tried prepared queries, it didn't work. Even direct queries doesn't work:
$pdo->exec("INSERT INTO child_table(id, child_field) VALUES (1, '0123456789')");
$pdo->exec("INSERT INTO main_table(id, field) VALUES(1, '0123456789')");
Starting transaction don't help too. Query 'SET CONSTRAINTS ALL DEFERRED' doesn't help too. I tried to add 'PDO::ATTR_PERSISTENT => true' to init array. No results. So please tell me, how I can execute these queries in this order by PHP? As I think, I've got to execute these queries by one transaction, but this transaction have not to check constraints until it will be committed. Or I am I wrong?
SOLUTION
The problem was not with PDO and not with transactions. Table main_table was created by another role and seems after commit data did not write into main_table because of owner problem, so child_table throws constraint error. It's bad that main_table did not throws owner error, so problem was not obvious.
Somebody answered me with this solution:
$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();
Man, this was right solution, I'm sorry that I answer you that it doesn't work.