Postgresql Syntax Error in Trigger Function - sql

I want to create the following trigger function in my Postgresql DB :
CREATE FUNCTION attribute_edit_history()
RETURNS TRIGGER AS
$BODY$
BEGIN
Select
CASE
WHEN NOT EXISTS
(SELECT * FROM public."TB02_MDD_KEY" where "ENCODED_ID" =ENCODE(CONVERT_TO(NEW."ATTRIBUTE_NAME", 'UTF-8'), 'base64'))
THEN
CASE
WHEN OLD."ATTRIBUTE_NAME" is distinct from NEW."ATTRIBUTE_NAME"
THEN
INSERT INTO public."TB08_ATTRIBUTE_EDIT_HISTORY"(
"ENCODED_ID_OLD","ENCODED_ID_NEW" , "VERSION", "ATTRIBUTE_OLD", "ATTRIBUTE_NEW", "ATTRIBUTE_NEW_ID")
VALUES ( OLD."ENCODED_ID", NEW."ENCODED_ID", NEW."VERSION", OLD."ATTRIBUTE_NAME", NEW."ATTRIBUTE_NAME", ENCODE(CONVERT_TO(NEW."ATTRIBUTE_NAME", 'UTF-8'), 'base64'));
END;
END;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;
CREATE TRIGGER "attribute_edit_history" BEFORE UPDATE ON "TB02_MDD_KEY"
FOR EACH ROW EXECUTE PROCEDURE attribute_edit_history();
I am getting the following syntax error :
ERROR: syntax error at or near "INTO"
LINE 13: INSERT INTO public."TB08_ATTRIBUTE_EDIT_HISTORY"(
^
SQL state: 42601
Character: 352
I dont know where I am going wrong.
Thanks in advance!

Most likely, you want a simple IF statement rather than nested CASE expressions:
CREATE FUNCTION attribute_edit_history()
RETURNS TRIGGER AS
$BODY$
BEGIN
IF
NOT EXISTS(
SELECT 1
FROM public.TB02_MDD_KEY
WHERE ENCODED_ID = ENCODE(CONVERT_TO(NEW.ATTRIBUTE_NAME, 'UTF-8'), 'base64')
)
AND OLD.ATTRIBUTE_NAME IS DISTINCT FROM NEW.ATTRIBUTE_NAME
THEN
INSERT INTO public.TB08_ATTRIBUTE_EDIT_HISTORY(
ENCODED_ID_OLD,
ENCODED_ID_NEW ,
VERSION,
ATTRIBUTE_OLD,
ATTRIBUTE_NEW,
ATTRIBUTE_NEW_ID
) VALUES (
OLD.ENCODED_ID,
NEW.ENCODED_ID,
NEW.VERSION,
OLD.ATTRIBUTE_NAME,
NEW.ATTRIBUTE_NAME,
ENCODE(CONVERT_TO(NEW.ATTRIBUTE_NAME, 'UTF-8'), 'base64')
);
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;
Note that I removed the double quotes around the tables and columns identifiers; you don't need those (unless you have case-sensitive identifiers, which does not seem to be the case here).

Related

Update columns for the first user inserted

I'm trying to create a trigger and a function to update some columns (roles and is_verified) for the first user created. Here is my function :
CREATE OR REPLACE FUNCTION public.first_user()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
DECLARE
begin
if(select count(*) from public.user = 1) then
update new set new.is_verified = true and new.roles = ["ROLE_USER", "ROLE_ADMIN"]
end if;
return new;
end;
$function$
;
and my trigger :
create trigger first_user
before insert
on
public.user for each row execute function first_user()
I'm working on Dbeaver and Dbeaver won't persist my function because of a syntax error near the "=". Any idea ?
Quite a few things are wrong in your trigger function. Here it is revised w/o changing your business logic.
However this will affect the second user, not the first. Probably you shall compare the count to 0. Then the condition shall be if not exists (select from public.user) then
CREATE OR REPLACE FUNCTION public.first_user()
RETURNS trigger LANGUAGE plpgsql AS
$function$
begin
if ((select count(*) from public.user) = 1) then
-- probably if not exists (select from public.user) then
new.is_verified := true;
new.roles := array['ROLE_USER', 'ROLE_ADMIN'];
end if;
return new;
end;
$function$;

SQL Error [42601]: ERROR: syntax error at or near "ALTER" [duplicate]

This is my function:
CREATE OR REPLACE FUNCTION addData (x INT,y INT)
RETURNS void AS $$
BEGIN
INSERT INTO TABLE temp(id,name,pass) VALUES(y,"ABC","XYZ");
END;
$$ LANGUAGE SQL;
but the output is
$$ LANGUAGE SQL
ERROR: syntax error at or near "INSERT"
LINE 4: INSERT INTO TABLE temp(id,name,pass)
I tried by changing data type, double quotes to single quotes, please help me with this. I am currently using pSQL
INSERT INTO TABLE... no need TABLE keyword
VALUES(y,"ABC","XYZ")... You need single quotes instead of double
Since you use BEGIN..END, you need plpgsql language
CREATE OR REPLACE FUNCTION addData (x INT,y INT)
RETURNS void AS $$
BEGIN
INSERT INTO temp(id,name,pass) VALUES(y,'ABC','XYZ');
END;
$$ LANGUAGE plpgSQL;

I need help regarding dynamic SQL and dynamically setting the table name in a function

So, i need to create a function that returns the count of the lines in a table, the table name must be specified by the user. This is the code i have:
CREATE OR REPLACE FUNCTION datiInTab( table regclass )
RETURNS NUMERIC(5) AS
$$
DECLARE
num NUMERIC(5);
cmd VARCHAR(1000):='SELECT COUNT(*) FROM ';
BEGIN
EXECUTE cmd || table;
RETURN num;
END;
$$
LANGUAGE plpgsql;
SELECT * FROM datiInTab(corsi);
And this is the error that returns after i execute:
ERROR: ERRORE: la colonna "corsi" non esiste
LINE 1: SELECT * FROM datiInTab(corsi); ^ SQL state: 42703 Character: 25
Meaning that the column "corsi" doesn't exist.
I debugged as much as i could and the only conclusion is that i don't really know what i need to do in order to make use of this dynamic call.
edit: regclass was a last minute addition, after trying with a simple varchar, that returned the same exact error
You can't name a variable table. it is a reserved word
and you have to pass a string else postgres thinks you want to pass a column
CREATE OR REPLACE FUNCTION datiInTab( table1 regclass )
RETURNS NUMERIC(5) AS
$$
DECLARE
num NUMERIC(5);
cmd VARCHAR(1000):='SELECT COUNT(*) FROM ';
BEGIN
EXECUTE cmd || table1;
RETURN num;
END;
$$
LANGUAGE plpgsql;
✓
SELECT * FROM datiInTab('corsi');
ERROR: relation "corsi" does not exist
LINE 1: SELECT * FROM datiInTab('corsi');
^
db<>fiddle here

syntax error at or near create when creating a function

So I am creating a function in PostgreSQL for the first time and I am having a problem with the syntax
CREATE OR REPLACE FUNCTION uni() RETURNS INTEGER AS $$
DECLARE
mviews RECORD;
BEGIN
FOR mviews IN SELECT id,universite_adi FROM proaca.a LOOP
INSERT INTO proaca.universite (id,ad,ulke_id)
VALUES (mviews.id,mviews.universite_adi,1)
END LOOP;
RETURN 1;
END;
$$ LANGUAGE plpgsql;
ERROR: syntax error at or near "create"
Line 2: $BODY$CREATE OR REPLACE FUNCTION uni() RETURNS INTEGER AS $$
The syntax error was solved by a_horse in the comments:
missing a ; to terminate the INSERT statement.
You don't need that loop. Just plain sql
create or replace function uni()
returns integer as $$
insert into proaca.universite (id, ad, ulke_id)
select id, universite_adi, 1
from proaca.a
returning 1
;
$$ language sql;

Function with SQL query has no destination for result data

I am trying to create a function that returns a SELECTed resultset.
When I call my postgres function like this select * from tst_dates_func() I get an error as shown below:
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgSQL function "tst_dates_func" line 3 at SQL statement
********** Error **********
ERROR: query has no destination for result data
SQL state: 42601
Hint: If you want to discard the results of a SELECT, use PERFORM instead.
Context: PL/pgSQL function "tst_dates_func" line 3 at SQL statement
Here is the function I created:
CREATE OR REPLACE FUNCTION tst_dates_func()
RETURNS TABLE( date_value date, date_id int, date_desc varchar) as
$BODY$
BEGIN
select a.date_value, a.date_id, a.date_desc from dates_tbl a;
END;
$BODY$
LANGUAGE plpgsql;
I am not sure why I am getting the above error. I would like to run select * from tst_dates_func();
and get data back. Or further join the result set if needed. What is the problem here?
Do it as plain SQL
CREATE OR REPLACE FUNCTION tst_dates_func()
RETURNS TABLE( date_value date, date_id int, date_desc varchar) as
$BODY$
select a.date_value, a.date_id, a.date_desc from dates_tbl a;
$BODY$
LANGUAGE sql;
If you really need plpgsql use return query
CREATE OR REPLACE FUNCTION tst_dates_func()
RETURNS TABLE( date_value date, date_id int, date_desc varchar) as
$BODY$
BEGIN
perform SELECT dblink_connect('remote_db');
return query
select a.date_value, a.date_id, a.date_desc from dates_tbl a;
END;
$BODY$
LANGUAGE plpgsql;
In PLPGSQL - use RETURN QUERY
CREATE OR REPLACE FUNCTION tst_dates_func()
RETURNS TABLE( date_value date, date_id int, date_desc varchar) as
$BODY$
BEGIN
RETURN QUERY (select a.date_value, a.date_id, a.date_desc from dates_tbl a);
END;
$BODY$
LANGUAGE plpgsql;
I couldn't do it as plain SQL as I needed to enter some data into a database for further processing and wanted to create a variable. Or at least I did not figure out the correct syntax for that. And the accepted answer had code I did not need, such as connecting to the database, as I ran this from inside pgAdmin with a connection setup already. I also had to drop the function when I made edits to it.
I was using this for inserting a geometry for intersection. A different use case and example could help someone else. This also shows how to then view this data and use it just like a table.
-- Get a geojson shape inside of postgres for further use
DROP FUNCTION fun();
CREATE OR REPLACE FUNCTION fun()
RETURNS TABLE (geometry geometry) AS
$BODY$
DECLARE geojson TEXT;
BEGIN
geojson := '{
"type":"Polygon",
"coordinates":[[[-90.9516399548092,39.8942337977775],[-90.9513913202472,39.8936939306154],[-90.9522805177147,39.8937108246505],[-90.9549542293894,39.8937616571416],[-90.954948768846,39.8945506794343],[-90.9531755591848,39.894492766522],[-90.9531770788457,39.8942868819087],[-90.9516399548092,39.8942337977775]]],
"crs":{"type":"name","properties":{"name":"EPSG:4326"}},
}';
return query (SELECT ST_GeomFromGeoJSON(geojson) AS geometry);
END;
$BODY$
LANGUAGE plpgsql;
-- View test insert
SELECT * FROM fun()