Обсуждение: Postgres CTE issues
This is what I am trying:WITH x AS(INSERT INTO industry (name,abbr,description,cr_date,last_upd)VALUES ('df','','',now(),now()) returning id) insert into sector (name,description,cr_date,last_upd,industry_id) select 's1','',now(),now(),id from x;I get a error:ERROR: insert or update on table "sector" violates foreign key constraint "sector_id_fkey"DETAIL: Key (id)=(394) is not present in table "industry".If I execute the insert individually, I am able to insert a record. Wonder what I am doing wrong.I have been stuck with this issue for over 24 hours. Appreciate any help.
On Tue, May 26, 2015 at 9:00 AM, David G. Johnston <david.g.johnston@gmail.com> wrote:This is what I am trying:WITH x AS(INSERT INTO industry (name,abbr,description,cr_date,last_upd)VALUES ('df','','',now(),now()) returning id) insert into sector (name,description,cr_date,last_upd,industry_id) select 's1','',now(),now(),id from x;I get a error:ERROR: insert or update on table "sector" violates foreign key constraint "sector_id_fkey"DETAIL: Key (id)=(394) is not present in table "industry".If I execute the insert individually, I am able to insert a record. Wonder what I am doing wrong.I have been stuck with this issue for over 24 hours. Appreciate any help.It is not possible to accomplish your goal using a CTE. From the point of view of both tables the data they can see is what was present before the statement began.The more usual way to accomplish this is the write a pl/pgsql function with two statements and passing the ID between them using an intermediate variable.David J.
INSERT INTO industry (name,abbr,description,cr_date,last_upd) VALUES (NEW.industry,'','',now(),now()) returning id into industry_id;
industry_id := (select industry_id from industry where name = 'NEW.industry');
raise notice 'industry id is %', industry_id;
INSERT INTO sector (name,description,cr_date,last_upd,industry_id) VALUES (NEW.sector,'',now(),now(),industry_id) returning id into sector_id;
-- I get a new industry ID but a new row is not inserted. I am guessing this is the case because it takes all the transactions as atomic. As a result, I get a foreign key violation.
> This is what I am trying:
>
> WITH x AS
>
> (INSERT INTO industry (name,abbr,description,cr_date,last_upd)
>
> VALUES ('df','','',now(),now()) returning id) insert into sector (name,description,cr_date,last_upd,industry_id) select 's1','',now(),now(),id from x;
>
> I get a error:
>
> ERROR: insert or update on table "sector" violates foreign key constraint "sector_id_fkey"
>
> DETAIL: Key (id)=(394) is not present in table "industry".
>
> If I execute the insert individually, I am able to insert a record. Wonder what I am doing wrong.
Hello,
Defining your FK as deferrable initially deferred should help here.
regards,
Marc Mamin
create table A (
var1 varchar(40),
var2 varchar(40) );
create table B (
"id" SERIAL PRIMARY KEY,
name varchar(40));
create table C (
"id" SERIAL PRIMARY KEY,
name varchar(40)
, b_id integer references B(id) NOT NULL);
-- Create a trigger function
CREATE OR REPLACE FUNCTION fn_test() RETURNS trigger AS $BODY$
DECLARE
a_id int;
b_id int;
c_id int;
BEGIN
INSERT INTO B (name) VALUES (NEW.var1);
b_id := (select id from B where name = 'NEW.var1');
INSERT INTO C (name, b_id) VALUES (NEW.var2, b_id);
return NEW;
END;
$BODY$ LANGUAGE plpgsql;
-- Create trigger
CREATE TRIGGER tr_test
BEFORE insert or UPDATE
ON A
FOR EACH ROW
EXECUTE PROCEDURE fn_test();
insert into A (var1, var2) values ('Hello', 'World');
ERROR: null value in column "b_id" violates not-null constraint
DETAIL: Failing row contains (1, World, null).
CONTEXT: SQL statement "INSERT INTO C (name, b_id) VALUES (NEW.var2, b_id)"
PL/pgSQL function fn_test() line 17 at SQL statement
re-including the listOn Tue, May 26, 2015 at 9:00 AM, David G. Johnston <david.g.johnston@gmail.com> wrote:This is what I am trying:WITH x AS(INSERT INTO industry (name,abbr,description,cr_date,last_upd)VALUES ('df','','',now(),now()) returning id) insert into sector (name,description,cr_date,last_upd,industry_id) select 's1','',now(),now(),id from x;I get a error:ERROR: insert or update on table "sector" violates foreign key constraint "sector_id_fkey"DETAIL: Key (id)=(394) is not present in table "industry".If I execute the insert individually, I am able to insert a record. Wonder what I am doing wrong.I have been stuck with this issue for over 24 hours. Appreciate any help.It is not possible to accomplish your goal using a CTE. From the point of view of both tables the data they can see is what was present before the statement began.The more usual way to accomplish this is the write a pl/pgsql function with two statements and passing the ID between them using an intermediate variable.David J.>>>>>>>>>>>>>>>>>>>I have tried that as well.INSERT INTO industry (name,abbr,description,cr_date,last_upd) VALUES (NEW.industry,'','',now(),now()) returning id into industry_id;
industry_id := (select industry_id from industry where name = 'NEW.industry');
raise notice 'industry id is %', industry_id;
INSERT INTO sector (name,description,cr_date,last_upd,industry_id) VALUES (NEW.sector,'',now(),now(),industry_id) returning id into sector_id;
-- I get a new industry ID but a new row is not inserted. I am guessing this is the case because it takes all the transactions as atomic. As a result, I get a foreign key violation.
>>>>>>>>>>>>>>>>>>If you are using a trigger you should also provide the relevant CREATE TRIGGER statement...In fact, you really you supply a self-contained example.Also, please do not top-post.David J.
create table C (
"id" SERIAL PRIMARY KEY,
name varchar(40)
, b_id integer references B(id) DEFERRABLE INITIALLY DEFERRED NOT NULL);
I still get the same error:
insert into A (var1, var2) values ('Hello1', 'World1');
ERROR: null value in column "b_id" violates not-null constraint
DETAIL: Failing row contains (2, World1, null).
CONTEXT: SQL statement "INSERT INTO C (name, b_id) VALUES (NEW.var2, b_id)"
PL/pgSQL function fn_test() line 17 at SQL statement
Marc,I have changed the table C:create table C (
"id" SERIAL PRIMARY KEY,
name varchar(40)
, b_id integer references B(id) DEFERRABLE INITIALLY DEFERRED NOT NULL);
I still get the same error:
insert into A (var1, var2) values ('Hello1', 'World1');
ERROR: null value in column "b_id" violates not-null constraint
DETAIL: Failing row contains (2, World1, null).
CONTEXT: SQL statement "INSERT INTO C (name, b_id) VALUES (NEW.var2, b_id)"
PL/pgSQL function fn_test() line 17 at SQL statement
I changed the not null constraint but I dont insert the FK id (it is null)
drop table C;
DROP TABLE
s=> create table C (
"id" SERIAL PRIMARY KEY,
name varchar(40)
, b_id integer references B(id)DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE
s=> insert into A (var1, var2) values ('Hello1', 'World1');
INSERT 0 1
s=> select * from C;
1 | World1 |
On Tue, May 26, 2015 at 10:40 AM, Shekar Tippur <ctippur@gmail.com> wrote:Marc,I have changed the table C:create table C (
"id" SERIAL PRIMARY KEY,
name varchar(40)
, b_id integer references B(id) DEFERRABLE INITIALLY DEFERRED NOT NULL);
I still get the same error:
insert into A (var1, var2) values ('Hello1', 'World1');
ERROR: null value in column "b_id" violates not-null constraint
DETAIL: Failing row contains (2, World1, null).
CONTEXT: SQL statement "INSERT INTO C (name, b_id) VALUES (NEW.var2, b_id)"
PL/pgSQL function fn_test() line 17 at SQL statement
Because you cannot defer a NOT NULL constraint.David J.
Hi,
Here is a small snippet on how I got to the error. I am creating a trigger function that returns a trigger.As you can see, I get a error at the end. Appreciate any help in this regard.-- Create table Acreate table A (
var1 varchar(40),
var2 varchar(40) );
-- Create table Bcreate table B (
"id" SERIAL PRIMARY KEY,
name varchar(40));
-- Create table Ccreate table C (
"id" SERIAL PRIMARY KEY,
name varchar(40)
, b_id integer references B(id) NOT NULL);
-- Create a trigger function
CREATE OR REPLACE FUNCTION fn_test() RETURNS trigger AS $BODY$
DECLARE
a_id int;
b_id int;
c_id int;
BEGIN
INSERT INTO B (name) VALUES (NEW.var1);
b_id := (select id from B where name = 'NEW.var1');
INSERT INTO C (name, b_id) VALUES (NEW.var2, b_id);
return NEW;
END;
$BODY$ LANGUAGE plpgsql;
-- Create trigger
CREATE TRIGGER tr_test
BEFORE insert or UPDATE
ON A
FOR EACH ROW
EXECUTE PROCEDURE fn_test();
insert into A (var1, var2) values ('Hello', 'World');
ERROR: null value in column "b_id" violates not-null constraint
DETAIL: Failing row contains (1, World, null).
CONTEXT: SQL statement "INSERT INTO C (name, b_id) VALUES (NEW.var2, b_id)"
PL/pgSQL function fn_test() line 17 at SQL statement
On Tue, May 26, 2015 at 9:14 AM, David G. Johnston <david.g.johnston@gmail.com> wrote:re-including the listOn Tue, May 26, 2015 at 9:00 AM, David G. Johnston <david.g.johnston@gmail.com> wrote:This is what I am trying:WITH x AS(INSERT INTO industry (name,abbr,description,cr_date,last_upd)VALUES ('df','','',now(),now()) returning id) insert into sector (name,description,cr_date,last_upd,industry_id) select 's1','',now(),now(),id from x;I get a error:ERROR: insert or update on table "sector" violates foreign key constraint "sector_id_fkey"DETAIL: Key (id)=(394) is not present in table "industry".If I execute the insert individually, I am able to insert a record. Wonder what I am doing wrong.I have been stuck with this issue for over 24 hours. Appreciate any help.It is not possible to accomplish your goal using a CTE. From the point of view of both tables the data they can see is what was present before the statement began.The more usual way to accomplish this is the write a pl/pgsql function with two statements and passing the ID between them using an intermediate variable.David J.>>>>>>>>>>>>>>>>>>>I have tried that as well.INSERT INTO industry (name,abbr,description,cr_date,last_upd) VALUES (NEW.industry,'','',now(),now()) returning id into industry_id;
industry_id := (select industry_id from industry where name = 'NEW.industry');
raise notice 'industry id is %', industry_id;
INSERT INTO sector (name,description,cr_date,last_upd,industry_id) VALUES (NEW.sector,'',now(),now(),industry_id) returning id into sector_id;
-- I get a new industry ID but a new row is not inserted. I am guessing this is the case because it takes all the transactions as atomic. As a result, I get a foreign key violation.
>>>>>>>>>>>>>>>>>>If you are using a trigger you should also provide the relevant CREATE TRIGGER statement...In fact, you really you supply a self-contained example.Also, please do not top-post.David J.