Insert into view not returning primary key - postgresql

I've mapped a POCO to a view. When EF does an insert, it generates the following command...
INSERT INTO "public"."vw_place"("Name","Description","Point") VALUES ($1,$2,$3) RETURNING "PlaceId"
But the code, throws the following error...
{"A null store-generated value was returned for a non-nullable member
'PlaceId' of type 'DataAccess.Place'."}
Here is the trigger function that does the insert...
CREATE OR REPLACE FUNCTION vw_place_dml()
RETURNS trigger AS
$BODY$
BEGIN
IF TG_OP = 'INSERT' THEN
INSERT INTO tbl_place
(
"Name",
"Description",
"Point"
)
VALUES
(
NEW."Name",
NEW."Description",
ST_GeomFromWKB(NEW."Point", 4326)
);
RETURN NEW;
ELSIF TG_OP = 'UPDATE' THEN
UPDATE tbl_place SET
"PlaceId" = NEW."PlaceId",
"Name" = NEW."Name",
"Description" = NEW."Description",
"Point" = ST_GeomFromWKB(NEW."Point", 4326)
WHERE
"PlaceId" = OLD."PlaceId";
RETURN NEW;
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION vw_place_dml()
OWNER TO postgres;
If I run this in pgAdmin it returns nothing, which is the problem, but the row is successfully inserted and a PlaceId is generated.
INSERT INTO "public"."vw_place"("Name","Description","Point") VALUES
('ergw','regr','\x0101000000000000009846b2bfe4e068d7ff33a73f')
RETURNING "PlaceId"

After the insert in the trigger function and before RETURN NEW;, I added...
NEW."PlaceId" = currval('"tbl_place_PlaceId_seq"');

Related

PostgreSQL subquery with IF EXISTS in trigger function

I have a PostgreSQL trigger function like so:
CREATE FUNCTION playlists_tld_update_trigger() RETURNS TRIGGER AS
$$
BEGIN
IF EXISTS (SELECT 1 FROM "subjects" WHERE "subjects"."id" = new.subject_id) THEN
new.tld = (SELECT "subjects"."tld" FROM "subjects" WHERE "subjects"."id" = new.subject_id LIMIT 1);
END IF;
RETURN new;
END
$$
LANGUAGE plpgsql;
The trigger function will set the playlist's "tld" column to match the subject's "tld" column, but only if there exists a subject referenced by the subject_id foreign key. How do I use a subquery to combine the 2 queries into 1, or to avoid redundancy?
CREATE FUNCTION playlists_tld_update_trigger()
RETURNS TRIGGER
AS $$
DECLARE
my_tld <data_type_of_tld>;
BEGIN
SELECT subjects.tld
INTO my_tld
FROM subjects
WHERE subjects.id = new.subject_id
LIMIT 1
;
IF FOUND
THEN
new.tld = my_tld;
RETURN NEW;
ELSE
-- do something else
RETURN OLD;
END IF;
END
$$ LANGUAGE plpgsql;

Create Trigger to update a row on same table when insert or update happens using postgresql

I am new to plpgsql and trying the below scenario. It would be helpful if someone could help on this issue.
I have a table named emp_table and whenever an record is inserted, I called a trigger to update a column record_status with 'U' and when insert operation is happened on table, I need to update the record-status column to 'I'
Table :
CREATE TABLE emp_data (
name text,
age integer,
designation text,
salary integer,
last_login TIMESTAMP,
record_status varchar
);
CREATE OR REPLACE FUNCTION em_batch_update()
RETURNS trigger
LANGUAGE PLPGSQL
AS
$$
BEGIN
IF (TG_OP = 'UPDATE') THEN
UPDATE emp_data SET record_status = 'U' WHERE record_status is not null;
RETURN NEW;
ELSIF (TG_OP = 'INSERT') THEN
UPDATE emp_data SET record_status = 'I' WHERE record_status is NULL;
RETURN NEW;
end if;
END;
$$
CREATE TRIGGER em_sem_batch
BEFORE INSERT OR UPDATE ON emp_data
FOR EACH ROW
EXECUTE PROCEDURE em_batch_update();
I have inserted below new record, but the record_status is not getting updated.
insert into emp_data(name,age,designation,salary,last_login) values ('test1234',3,'test1143',1332224,current_timestamp);
I get below error when I either update or insert,
PL/pgSQL function em_batch_update1() line 5 at SQL statement
SQL statement "UPDATE emp_data SET record_status = 'U' WHERE record_status is not null"
PL/pgSQL function em_batch_update1() line 5 at SQL statement
SQL statement "UPDATE emp_data SET record_status = 'I' WHERE record_status is NULL"
PL/pgSQL function em_batch_update1() line 8 at SQL statement
SQL state: 54001
can someone help with this
No need for an UPDATE. In a row-level BEFORE trigger you can simply assign the values:
CREATE OR REPLACE FUNCTION em_batch_update()
RETURNS trigger
LANGUAGE PLPGSQL
AS
$$
BEGIN
IF (TG_OP = 'UPDATE') THEN
new.record_status := 'U';
ELSIF (TG_OP = 'INSERT') THEN
new.record_status := 'I';
end if;
RETURN NEW;
END;
$$
Or even simpler:
CREATE OR REPLACE FUNCTION em_batch_update()
RETURNS trigger
LANGUAGE PLPGSQL
AS
$$
BEGIN
new.record_status := left(TG_OP, 1);
RETURN NEW;
END;
$$

Funcion AS Trigger can`t update

I have a little problem and stack in something easy...
Working with postgis -> in Qgis.
I have Table
CREATE TABLE public."Table"
(
"ID" bigint NOT NULL,
geom geometry NOT NULL,
typ_obudowy text,
PRIMARY KEY ("ID")
)
WITH (
OIDS = FALSE
);
ALTER TABLE public."Table"
OWNER to jcorp_admin;
GRANT ALL ON TABLE public."Table" TO j_admin WITH GRANT OPTION;
GRANT ALL ON TABLE public."Table" TO j_projektant;
GRANT ALL ON TABLE public."Table" TO jcorp_admin WITH GRANT OPTION;
Trigger
CREATE TRIGGER TABLE_t
AFTER INSERT OR UPDATE OR DELETE
ON "schem1"."Table" FOR EACH ROW
EXECUTE PROCEDURE "schem1".Table_f();
and funkction:
CREATE OR REPLACE FUNCTION "schem1".Table_f()
RETURNS trigger AS
$BODY$
DECLARE
BEGIN
CASE TG_OP
WHEN 'INSERT' THEN
UPDATE "schem1"."Table" SET fild1 = 'wpisz tekst' WHERE "schem1"."Table"."id" = '3';
UPDATE "schem1"."Table" SET fild2 = 'wprowadz' WHERE "schem1"."Table"."id" = NEW.id; RETURN NULL; WHEN 'UPDATE' THEN
RETURN NULL;
WHEN 'DELETE' THEN
RETURN NULL;
END CASE;
RETURN NULL; END;
$BODY$
LANGUAGE plpgsql
And still got error.
Nie można zatwierdzić zmian dla warstwy skrzynki_cad
Błędy: BŁĄD: nie dodano 1 obiektu.
Błędy dostawcy:
Błąd PostGIS podczas dodawania obiektów: ERROR: column "fild1" of relation "Table" does not exist
LINE 1: UPDATE "schem1"."Table" SET field1 = 'wpisz tek...
^
QUERY: UPDATE "schem1"."Table" SET field1 = 'wpisz tekst' WHERE "schem1"."Table"."id" = '3'
CONTEXT: PL/pgSQL function schem1.Table_f() line 8 at SQL statement

Postgres update trigger

I've problem with a trigger function in postgresql.
Here my simple code.
CREATE TABLE specie
(specie_id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
nome_comune TEXT UNIQUE,
nome_scientifico TEXT UNIQUE);
CREATE TABLE rilevatore
(rilevatore_id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
nome_cognome TEXT);
CREATE TABLE evento_investimento
(evento_id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
data DATE,
ora TIME WITHOUT TIME ZONE,
rilevatore_id INT REFERENCES rilevatore (rilevatore_id),
specie_id INT REFERENCES specie(specie_id));
CREATE VIEW inserimento_dati_vista AS
SELECT row_number() OVER ()::integer AS gid,
evento_investimento.ora,
evento_investimento.data,
rilevatore.nome_cognome,
specie.nome_comune,
specie.nome_scientifico
FROM evento_investimento
JOIN specie ON evento_investimento.specie_id = specie.specie_id
JOIN rilevatore ON evento_investimento.rilevatore_id = rilevatore.rilevatore_id;
CREATE OR REPLACE FUNCTION inserimento_dati_fun_2() RETURNS trigger AS $$
BEGIN
if not exists(select * from rilevatore where rilevatore.nome_cognome=new.nome_cognome) then
INSERT INTO rilevatore (nome_cognome)
VALUES (NEW.nome_cognome);
end if;
if not exists(select * from specie where specie.nome_comune=new.nome_comune) then
INSERT INTO specie (nome_comune, nome_scientifico)
VALUES (NEW.nome_comune, NEW.nome_scientifico);
end if;
INSERT INTO evento_investimento (data, ora, rilevatore_id, specie_id)
VALUES (NEW.data,NEW.ora,
(SELECT rilevatore_id FROM rilevatore WHERE rilevatore.nome_cognome = NEW.nome_cognome),
(SELECT specie_id FROM specie WHERE specie.nome_comune = NEW.nome_comune));
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
create trigger inserimento_dati_fun_trg
instead of insert on inserimento_dati_vista for each row EXECUTE procedure inserimento_dati_fun_2();
Now, I want to add a function that allow to update all the tables by using the view inserimento_dati_vista.
I've tried with a simple code to update only the data column
CREATE OR REPLACE FUNCTION update_dati_fun_2() RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'UPDATE') THEN
IF old.data is distinct from new.data then
UPDATE evento_investimento
SET data = new.data;
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
create trigger update_dati_fun_2_trg
instead of update on inserimento_dati_vista for each row EXECUTE procedure update_dati_fun_2();
However when I perfomr the query in order to update only a row, the trigger update all the rows in the table. Here some code to fill data.
INSERT INTO inserimento_dati_vista
(data, ora, nome_cognome, nome_comune, nome_scientifico)
VALUES
('2020-01-01', '16:54:00','mario', 'lupo', 'Canis lupus'),
('2020-01-02', '13:54:00','luca', 'lontra', 'Lutra lutra');
UPDATE inserimento_dati_vista
SET data = '2021-01-02' where nome_cognome = 'luca'
Update function is:
CREATE OR REPLACE FUNCTION update_dati_fun_2() RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'UPDATE') THEN
IF old.data is distinct from new.data then
UPDATE evento_investimento e
SET data = new.data
FROM rilevatore r
WHERE nome_cognome = new.nome_cognome AND r.rilevatore_id = e.rilevatore_id;
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

Postgresql : insert record using trigger

CREATE TABLE users
(
id integer NOT NULL DEFAULT nextval('userseq'::regclass)
........
)
CREATE TABLE History
(
userid integer,
createdat timestamp with time zone
)
CREATE OR REPLACE FUNCTION recordcreatetime()
RETURNS trigger AS
$BODY$
BEGIN
NEW.createdAt = NOW();
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
User and History has one-one relationship. How i can insert new record in History table before creating new user.
CREATE OR REPLACE FUNCTION recordcreatetime()
RETURNS trigger
language plpgsql
AS $$
DECLARE
BEGIN
INSERT INTO History values(new.id,NOW() );
RETURN NEW;
END;
$$;
and write trigger statement as
CREATE TRIGGER user_hist
BEFORE INSERT ON users
FOR EACH ROW EXECUTE function recordcreatetime() ;