I am attempting to create a function that will determine if a record exists for our applications developers to help simplify things.
CREATE FUNCTION records_exist(schema_name VARCHAR(255), table_name VARCHAR(255), field_name VARCHAR(255), field_value VARCHAR(255))
RETURNS BOOLEAN
LANGUAGE plpgsql
AS $$
DECLARE
_schema_name ALIAS FOR $1;
_table_name ALIAS FOR $2;
_field_name ALIAS FOR $3;
_field_value ALIAS FOR $4;
_sql_string VARCHAR(5000);
BEGIN
_sql_string= 'SELECT EXISTS(SELECT 1 FROM ' || _schema_name || '.' || _table_name || ' WHERE ' || _field_name || '=' || _field_value || ');';
RETURN BOOLEAN EXECUTE _sql_string;
--RETURN TABLE EXECUTE _sql_string; doesn't work
END
$$;
The following should work, but I keep getting ERROR: syntax error at or near "EXECUTE"
Please let me know the error of my ways.
also, your dynamic string is bad, better use:
select format('select exists from %I.%I where %I = %L',schema_name,table_name,field_name, field_value) into _sql_string;
also, you realize your _field_value has no check for data type?..
so in short, it could be smth similar to:
db=# CREATE or replace FUNCTION records_exist(schema_name VARCHAR(255), table_name VARCHAR(255), field_name VARCHAR(255), field_value VARCHAR(255))
RETURNS BOOLEAN
LANGUAGE plpgsql
AS $$
DECLARE
_sql text;
_b boolean;
BEGIN
_sql := format('select exists (select null from %I.%I where %I = %L)',schema_name,table_name,field_name, field_value);
execute _sql into _b;
return _b;
END
$$;
CREATE FUNCTION
Time: 10.680 ms
db=# select * from records_exist('pg_catalog','pg_database','datname','postgres'); records_exist
---------------
t
(1 row)
Time: 59.472 ms
Related
create or replace function get_value2(tbl varchar, tbl1 anyelement) RETURNS
refcursor AS
$$
declare
ref_cursor REFCURSOR;
--refcursor declaration
begin
OPEN ref_cursor FOR EXECUTE
'SELECT distinct(file_name) , uploaded_date, ' ||'(SELECT STRING_AGG(column_name, ',')
from information_schema.columns
where table_name =' || quote_literal(tbl) ')' ||
'FROM ' || pg_typeof(tbl1); --table name from parameter
RETURN (ref_cursor);
end;
$$ LANGUAGE plpgsql;
--pg_typeof(tbl1) table name from parameter
any help will be appreciated
I would appreciate it if you could let me know why my code doesn't do anything ? I use PostgreSQL 12.
I want to create a function to change an specific column's value among all tables in a schema.
CREATE OR REPLACE FUNCTION update_cols(_sch text,_col text, _old int, _new int)
RETURNS text AS
$func$
DECLARE
_tbl text;-- table_name
BEGIN
-- Loop over tables
FOR _tbl IN
SELECT quote_ident(table_name)
FROM information_schema.columns
WHERE table_schema = _sch -- name of schema
AND column_name = _col -- name of column
LOOP
RAISE NOTICE '%',
EXECUTE
'UPDATE ' || _tbl || ' SET _col = new_id WHERE _col = old_id';
END LOOP;
RETURN _tbl;
END
$func$ LANGUAGE plpgsql;
-- Call:
SELECT update_cols('','column_name', 10, 13);
It's working now, thanks to the help of #Adrian Klaver's comment.
CREATE OR REPLACE FUNCTION update_cols(_sch text, _old int, _new int)
RETURNS text AS
$func$
DECLARE
_tbl text;-- table_name
BEGIN
-- Loop over tables
FOR _tbl IN
SELECT quote_ident(table_name)
FROM information_schema.columns
WHERE column_name = 'col_name' and TABLE_Schema = _sch
-- name of column
LOOP
EXECUTE format('UPDATE ' ||_tbl|| ' SET col_name = $1 WHERE col_name= $2') USING _new, _old;
END LOOP;
RETURN _tbl;
END
$func$ LANGUAGE plpgsql;
We are creating trigger before inserting in users relation that call below function.
In this function we are selecting from users depends on function argument and insert into a temp table for logging.
But result of execute select is null!
create or REPLACE function auth._role_policy_admin(_role text, _province text, _type user_group, _services json) returns void
LANGUAGE plpgsql
AS $$
DECLARE
_contract_id INTEGER;
_user_id INTEGER;
_test INTEGER;
BEGIN
if _type = 'customer' then
EXECUTE 'SELECT id FROM auth.users WHERE users.username = '' ' || _role || ' '' ' INTO _user_id;
INSERT INTO auth.logs(user_id, role) VALUES (_user_id, _role);
end if;
END;
$$;
I created a table partition that will create a table if it is not yet existing the table names are on a monthly basis. I need this function to return the inserted ID but I'm getting this error of column "partition" does not exist it seems that my schema(partition) is considered column in this code
CREATE OR REPLACE FUNCTION partition.itinerary_partition_function()
RETURNS TRIGGER AS
$BODY$
DECLARE
reflowId bigint;
_tablename text;
_startyear text;
_startmonth text;
_fulltablename text;
BEGIN
--Takes the current inbound "time" value and determines when midnight is for the given date
_startyear := to_char(now(), 'YYYY');
_startmonth := to_char(now(), 'MM');
_tablename := 'itinerary_'||_startyear || '_' || _startmonth;
_fulltablename := 'partition.' || _tablename;
-- Check if the partition needed for the current record exists
PERFORM 1
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind = 'r'
AND c.relname = _tablename
AND n.nspname = 'partition';
-- If the partition needed does not yet exist, then we create it:
-- Note that || is string concatenation (joining two strings to make one)
IF NOT FOUND THEN
EXECUTE 'CREATE TABLE partition.' || quote_ident(_tablename) || '()INHERITS (partition.itinerary)';
-- Table permissions are not inherited from the parent.
-- If permissions change on the master be sure to change them on the child also.
EXECUTE 'ALTER TABLE partition.' || quote_ident(_tablename) || ' OWNER TO postgres';
-- Indexes are defined per child, so we assign a default index that uses the partition columns
EXECUTE 'CREATE INDEX ' || quote_ident(_tablename||'_indx1') || ' ON partition.' || quote_ident(_tablename) || ' (id)';
END IF;
BEGIN
EXECUTE format('INSERT INTO %I SELECT $1.*', "partition." || _tablename)
USING NEW;
RETURN NEW;
END;
END;
$BODY$
LANGUAGE plpgsql;
After this code I am calling it in another insert function
CREATE OR REPLACE FUNCTION partition.insert_data(username text,jsonData jsonb) RETURNS bigint AS
$$
DECLARE reflowId bigint;
BEGIN
INSERT INTO reflow_partition.itinerary(username, data)
VALUES (username, jsonData) RETURNING id;
END;
$$
LANGUAGE plpgsql;
Try changing this:
EXECUTE format('INSERT INTO %I SELECT $1.*', "partition." || _tablename)
to this:
EXECUTE format('INSERT INTO %1$I.%2$I SELECT $1.*', 'partition', _tablename)
I have a query which is assigned to some variable and I want to execute it with setting some values.
Example:
create or replace function funct1(a int)
returns void as
$$
declare
wrclause varchar := '';
sqlq varchar ;
t varchar;
begin
IF (a IS NOT NULL ) THEN
wrclause := 'where C = '|| a ||' AND C IN ('|| a || ')';
END IF;
sqlq := ' t :=select string_agg(''select *, abcd as "D" from '' || table_namess ||, '' Union all '') as namess
from tablescollection2 ud
inner join INFORMATION_SCHEMA.Tables so on ud.table_namess = so.Table_name ' || wrclause;
raise info '%',sqlq;
execute sqlq; /* How to set value to variable f.ex (t varchar output,t output)*/
raise info '%',t;
end;
$$
language plpgsql;
In SQL Server: We can use
exec sp_executesql #sqlq, N'#t nvarchar(max) output', #t OUTPUT;
Note: How can I do in the PostgreSQL?
MyTry:
execute sqlq(t varchar output,t output); /* getting error near varchar */
You can do something like
EXECUTE sqlq INTO target_variable;
for more help plpgsql-statements