postgresql insert dynamic query result into table in cursor - postgresql

i have the following function, that generates dynamic query and at the end i want to insert result of dynamic query into table, but the error i get is `
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 report_get_result(integer) line 46 at SQL statement
SQL statement "SELECT report_get_result(20150131)"
PL/pgSQL function inline_code_block line 2 at PERFORM
********** Error **********'
body of the function is:
CREATE OR REPLACE FUNCTION report_get_result (
datekey integer
) returns setof logic_result_rcd
AS
$body$
DECLARE
LogicID integer;
SheetName text;
Row_ID text;
Column_ID text;
FromTable text;
Operation text;
Amount text;
CriteriaType_1 text;
Function_1 text;
Criteria_1 text;
CriteriaType_2 text;
Function_2 text;
Criteria_2 text;
CriteriaType_3 text;
Function_3 text;
Criteria_3 text;
sql text;
INC Integer;
begin
DROP TABLE IF EXISTS loans;
create temp table loans as
select * from loan.vfact_state_principal where "DateKey" = datekey;
DECLARE cursor_logic REFCURSOR;
BEGIN
OPEN cursor_logic for execute ('SELECT "LogicID" FROM logic_table_rcd');
LOOP
FETCH cursor_logic INTO INC;
if not found then exit;
end if;
BEGIN
SELECT LogicID = "LogicID"
,SheetName = "SheetName"
,Row_ID = "Row_ID"::text
,Column_ID = "Column_ID"::text
,FromTable = "FromTable"
,Operation = "Operation"
,Amount = "Amount"
,CriteriaType_1 = CASE WHEN "CriteriaType_1" <> '' THEN ('WHERE
' || "CriteriaType_1") ELSE '' END
,Function_1 = CASE WHEN "Function_1" is null THEN 'Empty' ELSE
"Function_1" END
,Criteria_1 = CASE WHEN "Criteria_1" is null THEN 'Empty' ELSE
"Criteria_1" END
,CriteriaType_2 = CASE WHEN "CriteriaType_2" <> '' THEN ' AND '
|| "CriteriaType_2" ELSE '' END
,Function_2 = CASE WHEN "Function_2" is null THEN 'Empty' ELSE
"Function_2" END
,Criteria_2 = CASE WHEN "Criteria_2" is null THEN 'Empty' ELSE
"Criteria_2" END
,CriteriaType_3 = CASE WHEN "CriteriaType_3" <> '' THEN ' AND '
|| "CriteriaType_3" ELSE '' END
,Function_3 = CASE WHEN "Function_3" is null THEN 'Empty' ELSE
"Function_3" END
,Criteria_3 = CASE WHEN "Criteria_3" is null THEN 'Empty' ELSE
"Criteria_3" END
FROM public.logic_table_rcd WHERE "LogicID" = INC;
sql:= 'INSERT INTO public.logic_result_rcd SELECT ' || INC::text || ', 1, '
|| EntityID::text || ', ' || DateKey::text || ', ' || 'RCD' || ', ' ||
SheetName::text || ', ' || Row_ID::text || ', ' || Column_ID::text || ', '
|| Operation || '(' || Amount || ')' || ' FROM ' || FromTable
|| CriteriaType_1 || ' ' || Function_1 || ' ' || Criteria_1
|| CriteriaType_2 || ' ' || Function_2 || ' ' || Criteria_2
|| CriteriaType_3 || ' ' || Function_3 || ' ' || Criteria_3;
RETURN QUERY EXECUTE sql;
END;
END LOOP;
CLOSE cursor_logic;
END;
END;
$body$
LANGUAGE plpgsql;

assign value with VAR_NAME := ''; construct, here is an example:
t=# create function f(_i int) returns table (a int) as $$
declare sql text;
begin
sql := format('select %s',_i);
return query execute sql;
end;
$$
language plpgsql
;
CREATE FUNCTION
t=# select * From f(3);
a
---
3
(1 row)

Related

concat_ws in plpgsql procedure returning error has no destination for result data

I am new to plpgsql and I am now close to what I want to do :
create or replace function shop_apply_search_filters(
price_min integer default null,
price_max integer default null,
ecom_id integer default null,
cat_1 text default null,
cat_2 text default null)
returns text as
$$
BEGIN
IF cat_1 = '' THEN
cat_1 = null;
END IF;
IF cat_2 = '' THEN
cat_2 = null;
END IF;
select concat_ws(
' and ',
'price < ' || price_min,
'price > ' || price_max,
'ecom_id = ' || ecom_id,
'category_1 = ' || cat_1,
'category_2 = ' || cat_2
) AS filters;
END;
$$
LANGUAGE PLPGSQL;
If I call it SELECT shop_apply_search_filters(10,null,null,'',''),I have this error :
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 shop_apply_search_filters(integer,integer,integer,text,text) line 11 at SQL statement
SQL state: 42601
I am not sure what I need to change to make it work
You need to return the result
RETURN
concat_ws(
' and ',
'price < ' || price_min,
'price > ' || price_max,
'ecom_id = ' || ecom_id,
'category_1 = ' || cat_1,
'category_2 = ' || cat_2
);

Postgres 8.3 Query full function definition using a query

Is it possible to be able to retrieve the full function definition (with parameters etc) using a SQL query?
This function or view (doing similar things) works with Postgres 8.3.
CREATE AGGREGATE public.textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
CREATE OR REPLACE FUNCTION public.getfunctionddl(functionOid oid)
RETURNS text AS
$BODY$
DECLARE
funcschema text;
funcname text = NULL;
paranames text;
paramodes text;
paratypes text;
paraintypes text;
function_body text = NULL;
paranames_array text[];
paramodes_array text[];
paratypes_array text[];
params_sql text = '';
type_name text = '';
return_type text;
params_sql_no_name text ='';
grants text;
proc_owner text;
proacl_txt text;
lanname_txt text;
function_sql text;
upper_array int;
in_param_cnt int = 0;
out_param_cnt int = 0;
prosecdef_b bool;
pro_volatile text;
pro_isstrict bool;
BEGIN
SELECT proargtypes, proallargtypes, proargnames, proargmodes, prosrc, ns.nspname, p.proname, prorettype, proacl, lanname, prosecdef, rolname, provolatile, proisstrict
INTO paraintypes, paratypes, paranames, paramodes, function_body, funcschema, funcname, return_type, proacl_txt, lanname_txt, prosecdef_b, proc_owner, pro_volatile, pro_isstrict
FROM pg_proc p
INNER JOIN pg_namespace ns ON ns.oid = p.pronamespace
INNER JOIN pg_language pl ON pl.oid = prolang
INNER JOIN pg_roles rl ON rl.oid = proowner
WHERE p.oid = functionOid
AND lanname <> 'internal';
IF COALESCE(funcname, '') = '' THEN
RETURN NULL;
END IF;
paratypes := REPLACE(COALESCE(paratypes, paraintypes), ',', ' ');
return_type := format_type(return_type::oid,NULL);
return_type := CASE WHEN return_type = 'character varying' THEN 'varchar' ELSE return_type END;
if paranames IS NULL OR paranames = '' THEN
params_sql := '()';
params_sql_no_name := '()';
ELSE
paratypes := REPLACE(REPLACE(paratypes, '{', ''), '}', '');
paranames := REPLACE(REPLACE(paranames, '{', ''), '}', '');
paramodes := REPLACE(REPLACE(paramodes, '{', ''), '}', '');
paratypes_array:=string_to_array(paratypes,' ');
paranames_array:=string_to_array(paranames,',');
paramodes_array:=string_to_array(paramodes,',');
upper_array := array_upper(paratypes_array,1);
params_sql := '(' || CASE WHEN upper_array > 5 THEN '
' ELSE '' END;
params_sql_no_name := '(';
FOR i IN array_lower(paratypes_array,1) .. array_upper(paratypes_array,1)
LOOP
type_name := format_type(paratypes_array[i]::oid, NULL);
type_name := CASE WHEN type_name = 'character varying' THEN 'varchar' ELSE type_name END;
params_sql := params_sql || CASE WHEN paramodes IS NULL OR paramodes = '' THEN '' WHEN paramodes_array[i] = 'o' THEN 'OUT ' ELSE '' END || paranames_array[i] || ' ' || type_name || CASE WHEN i = upper_array THEN ')' WHEN upper_array <= 5 THEN ', ' ELSE ',
' END;
params_sql_no_name := params_sql_no_name || CASE WHEN paramodes IS NULL OR paramodes = '' THEN '' WHEN paramodes_array[i] = 'o' THEN 'OUT ' ELSE '' END || type_name || CASE WHEN i = upper_array THEN ')' ELSE ',' END;
in_param_cnt := in_param_cnt + CASE WHEN paramodes IS NULL OR paramodes = '' THEN 1 WHEN paramodes_array[i] = 'o' THEN 0 ELSE 1 END;
out_param_cnt := out_param_cnt + CASE WHEN paramodes IS NULL OR paramodes = '' THEN 0 WHEN paramodes_array[i] = 'o' THEN 1 ELSE 0 END;
END LOOP;
END IF;
params_sql_no_name := LOWER(quote_ident(funcschema) || '.' || quote_ident(funcname)) || params_sql_no_name || '';
params_sql := quote_ident(funcschema) || '.' || quote_ident(funcname) || params_sql;
SELECT public.textcat_all('GRANT EXECUTE ON FUNCTION ' || params_sql_no_name || ' TO ' || quote_ident(grantee) || ';
') INTO grants
FROM(SELECT
substring(a, 1, position('=X' in a) -1) as grantee
-- , substring(a, position('=X' in a) + 3, char_length(a) - position('=X' in a)) as grantor_name
From regexp_split_to_table(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(proacl_txt, '}', ''), '{', ''), CHR(34) || chr(92), ''), CHR(34), ''), chr(92), ''), ',') a)k
WHERE grantee <> proc_owner
AND grantee <> '';
function_sql := '-- ' || params_sql_no_name || '
' || CASE WHEN in_param_cnt + out_param_cnt > 0 THEN '-- PARAMS ALL: ' || CAST(in_param_cnt + out_param_cnt as char(3)) || ', IN: ' || cast(in_param_cnt as char(3)) || ', OUT ' || CAST(out_param_cnt as char(3)) || '
' ELSE '' END || '
-- DROP FUNCTION IF EXISTS ' || params_sql_no_name || ';
-- DROP FUNCTION IF EXISTS ' || params_sql_no_name || ' CASCADE;
CREATE OR REPLACE FUNCTION ' || params_sql || '
' || 'RETURNS ' || CASE WHEN return_type = 'record' then 'SETOF record' ELSE return_type END || '
LANGUAGE ' || lanname_txt || CASE WHEN pro_volatile = 'i' THEN ' IMMUTABLE' WHEN pro_volatile = 's' THEN ' STABLE' ELSE '' END || CASE WHEN pro_isstrict = true THEN ' RETURNS NULL ON NULL INPUT' ELSE '' END || CASE WHEN prosecdef_b = true THEN ' SECURITY DEFINER' ELSE '' END || '
AS $' || '$' || COALESCE(function_body, '') || '$' || '$;';
function_sql := function_sql || '
-- ALTER FUNCTION ' || params_sql_no_name || ' OWNER TO ' || quote_ident(proc_owner) || ';' || COALESCE('
' || grants, '');
RETURN function_sql;
END $BODY$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION public.getfunctionddl(schema_name_like varchar(256), function_name_like varchar(256), OUT schema_name varchar(256), OUT function_name varchar(256), OUT owner varchar(256), OUT func_lang varchar(256), OUT arg_cnt smallint, OUT func_oid oid, OUT ddl text)
RETURNS SETOF record AS $$
SELECT
CAST(ns.nspname as varchar(256)) as schema_name
, CAST(p.proname as varchar(256)) as proc_name
, cast(rolname as varchar(256)) as owner
, CAST(lanname as varchar(256)) as func_lang
, p.pronargs as arg_cnt
, p.oid as func_oid
, public.getfunctionddl(p.oid) as ddl
FROM pg_proc p
INNER JOIN pg_namespace ns ON ns.oid = p.pronamespace
INNER JOIN pg_language pl ON pl.oid = prolang
INNER JOIN pg_roles rl ON rl.oid = proowner
WHERE ns.nspname ILIKE lower(coalesce($1, '%'))
AND p.proname ILIKE lower(coalesce($2, '%'))
AND lanname <> 'internal'
ORDER BY ns.nspname, p.proname, p.oid;
$$ LANGUAGE SQL;
CREATE OR REPLACE VIEW public.vw_functionddl
AS
SELECT
CAST(ns.nspname as varchar(256)) as schema_name
, CAST(p.proname as varchar(256)) as proc_name
, cast(rolname as varchar(256)) as owner
, CAST(lanname as varchar(256)) as func_lang
, p.pronargs as arg_cnt
, p.oid as func_oid
, public.getfunctionddl(p.oid) as DDL
-- , proargtypes, proallargtypes, proargnames, proargmodes, prosrc, ns.nspname, p.proname, prorettype, proacl, prosecdef, rolname, provolatile, proisstrict
-- , p.*
FROM pg_proc p
INNER JOIN pg_namespace ns ON ns.oid = p.pronamespace
INNER JOIN pg_language pl ON pl.oid = prolang
INNER JOIN pg_roles rl ON rl.oid = proowner
WHERE lanname <> 'internal';
SELECT * FROM public.getfunctionddl('%' /*schema_name_like*/,'test_func' /*function_name_like*/);
SELECT * FROM public.vw_functionddl;

Query privileges for a function

How can I query the access right privileges for a function?
I want to generate a GRANT EXECUTE script for all the functions in the database.
I am using PostgreSQL 8.3.
You can query the system catalogs:
SELECT f.proname AS name,
f.proargtypes AS signature,
f.proacl AS permissions
FROM pg_catalog.pg_proc AS f
JOIN pg_catalog.pg_namespace AS s
ON f.pronamespace = s.oid
WHERE f.proname = 'myfunction'
AND s.nspname = 'myschema';
You know that PUBLIC has the EXECUTE privilege on functions by default, right?
I created a function (function chain exactly) to generate the scripts of function (functrion stub, drop script, create script, owner script, grant rights script). We are using dbeaver (I am not sure about other tools) and from the grid results we can copy paste the function definition. The resulting function can also be used to backup function definitions to a table etc. Let me know if you run into issues to it (we are running postgre 8.3 and this works for our functions).
CREATE AGGREGATE public.textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);
CREATE OR REPLACE FUNCTION public.getfunctionddl(functionOid oid)
RETURNS text AS
$BODY$
DECLARE
funcschema text;
funcname text = NULL;
paranames text;
paramodes text;
paratypes text;
paraintypes text;
function_body text = NULL;
paranames_array text[];
paramodes_array text[];
paratypes_array text[];
params_sql text = '';
type_name text = '';
return_type text;
params_sql_no_name text ='';
grants text;
proc_owner text;
proacl_txt text;
lanname_txt text;
function_sql text;
upper_array int;
in_param_cnt int = 0;
out_param_cnt int = 0;
prosecdef_b bool;
BEGIN
SELECT proargtypes, proallargtypes, proargnames, proargmodes, prosrc, ns.nspname, p.proname, prorettype, proacl, lanname, prosecdef, rolname
INTO paraintypes, paratypes, paranames, paramodes, function_body, funcschema, funcname, return_type, proacl_txt, lanname_txt, prosecdef_b, proc_owner
FROM pg_proc p
INNER JOIN pg_namespace ns ON ns.oid = p.pronamespace
INNER JOIN pg_language pl ON pl.oid = prolang
INNER JOIN pg_roles rl ON rl.oid = proowner
WHERE p.oid = functionOid
AND lanname <> 'internal';
IF COALESCE(funcname, '') = '' THEN
RETURN NULL;
END IF;
paratypes := REPLACE(COALESCE(paratypes, paraintypes), ',', ' ');
return_type := format_type(return_type::oid,NULL);
return_type := CASE WHEN return_type = 'character varying' THEN 'varchar' ELSE return_type END;
if paranames IS NULL OR paranames = '' THEN
params_sql := '()';
params_sql_no_name := '()';
ELSE
paratypes := REPLACE(REPLACE(paratypes, '{', ''), '}', '');
paranames := REPLACE(REPLACE(paranames, '{', ''), '}', '');
paramodes := REPLACE(REPLACE(paramodes, '{', ''), '}', '');
paratypes_array:=string_to_array(paratypes,' ');
paranames_array:=string_to_array(paranames,',');
paramodes_array:=string_to_array(paramodes,',');
upper_array := array_upper(paratypes_array,1);
params_sql := '(' || CASE WHEN upper_array > 5 THEN '
' ELSE '' END;
params_sql_no_name := '(';
FOR i IN array_lower(paratypes_array,1) .. array_upper(paratypes_array,1)
LOOP
type_name := format_type(paratypes_array[i]::oid, NULL);
type_name := CASE WHEN type_name = 'character varying' THEN 'varchar' ELSE type_name END;
params_sql := params_sql || CASE WHEN paramodes IS NULL OR paramodes = '' THEN '' WHEN paramodes_array[i] = 'o' THEN 'OUT ' ELSE '' END || paranames_array[i] || ' ' || type_name || CASE WHEN i = upper_array THEN ')' WHEN upper_array <= 5 THEN ', ' ELSE ',
' END;
params_sql_no_name := params_sql_no_name || CASE WHEN paramodes IS NULL OR paramodes = '' THEN '' WHEN paramodes_array[i] = 'o' THEN 'OUT ' ELSE '' END || type_name || CASE WHEN i = upper_array THEN ')' ELSE ',' END;
in_param_cnt := in_param_cnt + CASE WHEN paramodes IS NULL OR paramodes = '' THEN 1 WHEN paramodes_array[i] = 'o' THEN 0 ELSE 1 END;
out_param_cnt := out_param_cnt + CASE WHEN paramodes IS NULL OR paramodes = '' THEN 0 WHEN paramodes_array[i] = 'o' THEN 1 ELSE 0 END;
END LOOP;
END IF;
params_sql_no_name := LOWER(quote_ident(funcschema) || '.' || quote_ident(funcname)) || params_sql_no_name || '';
params_sql := quote_ident(funcschema) || '.' || quote_ident(funcname) || params_sql;
drop table if exists tmp_grant;
create temporary table tmp_grant
AS
SELECT
substring(a, 1, position('=X' in a) -1) as grantee_name
, substring(a, position('=X' in a) + 3, char_length(a) - position('=X' in a)) as grantor_name
From regexp_split_to_table(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(proacl_txt, '}', ''), '{', ''), CHR(34) || chr(92), ''), CHR(34), ''), chr(92), ''), ',') a;
SELECT public.textcat_all('GRANT EXECUTE ON FUNCTION ' || params_sql_no_name || ' TO ' || quote_ident(grantee_name) || ';
') INTO grants
FROM tmp_grant a
WHERE grantee_name <> ''
AND NOT EXISTS (select * From tmp_grant b where b.grantor_name = a.grantee_name);
function_sql := '-- ' || params_sql_no_name || '
' || CASE WHEN in_param_cnt + out_param_cnt > 0 THEN '-- PARAMS ALL: ' || CAST(in_param_cnt + out_param_cnt as char(3)) || ', IN: ' || cast(in_param_cnt as char(3)) || ', OUT ' || CAST(out_param_cnt as char(3)) || '
' ELSE '' END || '
-- DROP FUNCTION IF EXISTS ' || params_sql_no_name || ';
CREATE OR REPLACE FUNCTION ' || params_sql || '
' || 'RETURNS ' || CASE WHEN return_type = 'record' then 'SETOF record' ELSE return_type END || '
LANGUAGE ' || lanname_txt || CASE WHEN prosecdef_b = true THEN ' SECURITY DEFINER' ELSE '' END || '
AS $' || '$
' || COALESCE(function_body, '') || '
$' || '$;';
function_sql := function_sql || '
-- ALTER FUNCTION ' || params_sql_no_name || ' OWNER TO ' || quote_ident(proc_owner) || ';' || COALESCE('
' || grants, '');
RETURN function_sql;
END $BODY$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION public.getfunctionddl(schema_name_like varchar(256), function_name_like varchar(256), OUT schema_name varchar(256), OUT function_name varchar(256), OUT owner varchar(256), OUT func_oid oid, OUT func_lang varchar(256), OUT ddl text)
RETURNS SETOF record AS $$
SELECT
CAST(ns.nspname as varchar(256)) as schema_name
, CAST(p.proname as varchar(256)) as proc_name
, cast(rolname as varchar(256)) as owner
, p.oid as func_oid
, CAST(lanname as varchar(256)) as func_lang
, public.getfunctionddl(p.oid) as ddl
FROM pg_proc p
INNER JOIN pg_namespace ns ON ns.oid = p.pronamespace
INNER JOIN pg_language pl ON pl.oid = prolang
INNER JOIN pg_roles rl ON rl.oid = proowner
WHERE ns.nspname ILIKE lower(coalesce($1, '%'))
AND p.proname ILIKE lower(coalesce($2, '%'))
AND lanname <> 'internal'
ORDER BY ns.nspname, p.proname, p.oid;
$$ LANGUAGE SQL;
-- HOW TO GET DEFINITION OF THE FUNCTION
SELECT * FROM public.getfunctionddl('%' /*schema_name_like*/,'%' /*function_name_like*/)

Autopartitioning Postgresql for Zabbix

The goal, аutopartitioning for 7 days. And after 14 days to delete the old partitions. In this example, everything works. But, when I try to write data of the form :
insert into history_str (itemid, clock, ns, value) values (40,151,3722, '3.0.3');
I get an error
ERROR: syntax error at or near ".3"
LINE 1: ... istory_str_2018_02_07 values (40,151,3.0.3,3722 ...
                                                    ^
QUERY: INSERT INTO history_str_2018_02_07 values (40,151,3.0.3,3722);
CONTEXT: PL / pgSQL function create_partition_other () line 37 at EXECUTE
Here is the actual code example
CREATE OR REPLACE FUNCTION create_partition() RETURNS trigger AS
$BODY$
DECLARE
partition_name TEXT;
partition_week TEXT;
partitions_names TEXT;
date_search TEXT;
sql_search TEXT;
var_data TEXT;
typeof BOOL;
BEGIN
partition_week := to_char(to_timestamp(NEW.clock),'IW');
RAISE INFO 'Week now: %',partition_week;
partition_name := TG_TABLE_NAME || '_' || to_char(to_timestamp(NEW.clock),'YYYY_MM') || '_' || partition_week;
RAISE INFO 'Master Table: %',TG_TABLE_NAME;
RAISE INFO 'Partit. name: %',partition_name;
IF NOT EXISTS(SELECT relname FROM pg_class WHERE relname = partition_name) THEN
RAISE INFO 'Create table';
EXECUTE 'CREATE TABLE ' || partition_name || ' (check (clock >= ' || quote_literal(NEW.clock) || ' AND clock < ' || quote_literal(NEW.clock + integer '7' * integer '86400') || ')) INHERITS (' || TG_TABLE_NAME || ');';
EXECUTE 'INSERT INTO create_tables_date (name,date) values (' || quote_literal(partition_name) || ',' || quote_literal(to_timestamp(NEW.clock)) || ');';
date_search := quote_literal(date (to_char(to_timestamp(NEW.clock),'YYYY_MM_DD'))-integer '7');
RAISE INFO 'Search data: %',date_search;
sql_search := 'SELECT name FROM create_tables_date WHERE date < ' || date_search || ';';
for partitions_names in EXECUTE sql_search LOOP
IF partitions_names IS NOT NULL THEN
RAISE INFO 'DROP, DELETE: %',partitions_names;
EXECUTE 'DROP TABLE ' || partitions_names || ';';
EXECUTE 'DELETE FROM create_tables_date WHERE name=' || quote_literal(partitions_names) || ';';
END IF;
END LOOP;
END IF;
RAISE INFO 'Value: %',NEW.value;
var_data := 'INSERT INTO ' || partition_name || ' values ' || NEW || ';';
RAISE INFO 'SQL: %',var_data;
EXECUTE var_data;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
I found out that the problem when writing the values of being in NEW.value.And after replacing the characters [(), \] with _, the problem was solved.
That is, I redefine before an insert NEW.value
NEW.value := quote_literal(regexp_replace(NEW.value,'[(),\ ]','_','g'));
But this is the case if I try to write to a table with a column value, and if there is no other table, I have to write many identical functions for each table. What is bad.
Can you know why this situation arises with these symbols?
PostgreSQL 9.5.9
You could try USING and expand row with asterisk:
var_data := 'INSERT INTO ' || partition_name || ' values ($1.*);';
RAISE INFO 'SQL: %',var_data;
EXECUTE var_data using new;

postgresql cannot open INSERT query as cursor

i'm trying to generate dynamic query to insert results of dynamic select into table. my code is the following.
CREATE OR REPLACE FUNCTION public.report_get_result(
datekey integer)
RETURNS setof public.logic_result_rcd
LANGUAGE 'plpgsql'
COST 100
VOLATILE
AS $BODY$
DECLARE
LogicID text;
SheetName text;
Row_ID text;
Column_ID text;
FromTable text;
Operation text;
Amount text;
CriteriaType_1 text;
Function_1 text;
Criteria_1 text;
CriteriaType_2 text;
Function_2 text;
Criteria_2 text;
CriteriaType_3 text;
Function_3 text;
Criteria_3 text;
sql text;
INC Integer;
begin
DROP TABLE IF EXISTS loans;
create temp table loans as
select * from loan.vfact_state_principal where "DateKey" = datekey;
DECLARE cursor_logic REFCURSOR;
BEGIN
OPEN cursor_logic for SELECT "LogicID" FROM logic_table_rcd;
LOOP
FETCH cursor_logic INTO INC;
if not found then exit;
end if;
BEGIN
select into LogicID "LogicID" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into SheetName "SheetName" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into Row_ID "Row_ID" from public.logic_table_rcd WHERE "LogicID"
= 1;
select into Column_ID "Column_ID" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into FromTable "FromTable" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into Operation "Operation" from public.logic_table_rcd WHERE
"LogicID" = 1;
select into Amount "Amount" from public.logic_table_rcd WHERE "LogicID"
= 1;
select into CriteriaType_1 CASE WHEN "CriteriaType_1" <> '' OR
"CriteriaType_1" is not null THEN (' WHERE "' || "CriteriaType_1" || '"')
ELSE '' END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Function_1 CASE WHEN "Function_1" is null THEN '' ELSE
"Function_1" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Criteria_1 CASE WHEN "Criteria_1" is null THEN '' ELSE
"Criteria_1" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into CriteriaType_2 CASE WHEN "CriteriaType_2" <> '' OR
"CriteriaType_2" is not null THEN ' AND "' || "CriteriaType_2" || '"' ELSE
'' END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Function_2 CASE WHEN "Function_2" is null THEN '' ELSE
"Function_2" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Criteria_2 CASE WHEN "Criteria_2" is null THEN '' ELSE
"Criteria_2" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into CriteriaType_3 CASE WHEN "CriteriaType_3" <> '' or
"CriteriaType_3" is not null THEN ' AND "' || "CriteriaType_3" || '"' ELSE
'' END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Function_3 CASE WHEN "Function_3" is null THEN '' ELSE
"Function_3" END from public.logic_table_rcd WHERE "LogicID" = 1;
select into Criteria_3 CASE WHEN "Criteria_3" is null THEN '' ELSE
"Criteria_3" END from public.logic_table_rcd WHERE "LogicID" = 1;
sql:= 'INSERT INTO public.logic_result_rc SELECT ' || INC::text || ', 1, '
|| DateKey::text || ', ''' || 'RCD' || ''', ''' || SheetName::text || ''', '
|| Row_ID::text || ', '
|| Column_ID::text || ', ' || Operation || '("' || Amount || '")' || ' FROM
' || FromTable
|| CriteriaType_1 || ' ' || Function_1 || ' ' || Criteria_1
|| CriteriaType_2 || ' ' || Function_2 || ' ' || Criteria_2
|| CriteriaType_3 || ' ' || Function_3 || ' ' || Criteria_3;
RETURN QUERY EXECUTE sql;
END;
END LOOP;
CLOSE cursor_logic;
END;
END;
$BODY$;
ALTER FUNCTION public.report_get_result(integer)
OWNER TO postgres;
But after execution I get the next error:
cannot open INSERT query as cursor
All variables are assigned correctly. may be insert must be somewhere else outside cursor? does INSERT INTO .... FETCH ALL statement exist?
INSERT by default doesn't return any rows, so there is nothing to fetch. You can fix this by appending your sql string with RETURNING *, with should return contents inserted into public.logic_result_rc.
So it would like this: RETURN QUERY EXECUTE concat(sql, ' RETURNING *');
Basic syntax is:
INSERT INTO table_name ( column_name [, ...] )
VALUES ( ) | query
RETURNING * --or list of columns, same syntax like for SELECT