Unable to pass schema name in pg_get_serial_sequence. alerts is my schema name.
do $$
begin
execute format('select setval(pg_get_serial_sequence(''' || alerts.nds_email_message || ''', ''' || nds_email_message_id || '''),
coalesce(max(nds_email_message_id), 0) + 1, false)
from ''' || alerts.nds_email_message || '''');
end $$;
SQL Error [42601]: Unterminated dollar quote started at position 244 in SQL begin
execute format('select setval(pg_get_serial_sequence(''' || alerts.nds_email_message || ''', ''' || nds_email_message_id || '''),
coalesce(max(nds_email_message_id), 0) + 1, false)
from ''' || alerts.nds_email_message || '''');
end $$. Expected terminating $$'
how can I add multiple setval statements inside the block.
DO $$
BEGIN
SELECT setval(pg_get_serial_sequence('alerts.incident_log','incident_log_id'),coale sce(max( incident_log_id),0) +1, false) from alerts.incident_log;
SELECT setval(pg_get_serial_sequence('alerts.nds_email_message','nds_email_message_ id'),coa lesce(max(nds_email_message_id),0) +1, false) from alerts.nds_email_message;
SELECT setval(pg_get_serial_sequence('alerts.nds_fax_message','nds_fax_message_id') ,coalesc e(max(nds_fax_message_id),0) +1, false) from alerts.nds_fax_message;
Error occurred during SQL query execution
Reason:
SQL Error [42601]: ERROR: query has no destination for result data
Hint: If you want to discard the results of a SELECT, use PERFORM instead.
Where: PL/pgSQL function inline_code_block line 4 at SQL statement
As you are already using format() use the %L and %I placeholders:
do $$
begin
execute format('select setval(pg_get_serial_sequence(%L, %L), coalesce(max(%I), 0) + 1, false) from %I.%I',
'alerts.nds_email_message', 'nds_email_message_id', 'nds_email_message_id', 'alerts', 'nds_email_message');
end $$;
The parameters to pg_get_serial_sequence() are strings, so you need to use the %L placeholder. The references to the table and columns inside the actual select are identifiers, so you need to use %I
Related
I modified the function to trim all values in multiple tables based on Trim Spaces inside whole Database as below:
create function trim_all_text()
RETURNS void AS $$
DECLARE QL VARCHAR;
BEGIN
QL ='';
-- stored procedure body
PERFORM QL = QL || 'UPDATE T SET T.'||IC.COLUMN_NAME ||
' = LTRIM(RTRIM(' || IC.COLUMN_NAME||'))
FROM '|| IT.TABLE_SCHEMA || '.[' || IT.TABLE_NAME ||
'] AS T ;' || CHR(13)
FROM INFORMATION_SCHEMA.TABLES IT
JOIN INFORMATION_SCHEMA.COLUMNS IC ON IT.TABLE_NAME = IC.TABLE_NAME
AND IT.TABLE_SCHEMA ='public' and IT.TABLE_SCHEMA = IC.TABLE_SCHEMA AND IT.TABLE_TYPE = 'BASE TABLE'
and IC.DATA_TYPE in( 'varchar','char','nvarchar','nchar', 'text');
END;
$$ LANGUAGE plpgsql;
When I run the function in pgadmin4, I receive the error below:
ERROR: operator does not exist: unknown + information_schema.sql_identifier
LINE 1: SELECT QL += 'UPDATE ' + IT.TABLE_SCHEMA + '.'
^
How can I combine strings in a query?
I am a newbie wrt functions and I am struggling with using the name of a table in the function body. I get an error "SQL Error [42703]: ERROR: column "tname" does not exist" when I call the function using
select "JsonToView"('data_import.import_360xero_report');
My code is below
create or replace
function data_import."JsonToView"(tname text) returns numeric
language plpgsql
as $function$
begin
do
$$
declare
l_keys text;
begin
drop view if exists v_json_view cascade;
select
string_agg(distinct format('import_data ->> %L as %I', jkey, jkey), ', ')
into
l_keys
from
import_360xero_report,
json_object_keys(import_data) as t(jkey);
execute 'create view v_json_view as select ' || l_keys || ' from ' || tname;
end;
$$;
return 0;
end $function$ ;
I have modified the code and the second create view query works with the table name but the first one does not.
Below if my modified code
create or replace
function data_import."JsonToView"(tname text) returns numeric
language plpgsql
as $function$
declare
l_keys text;
begin
drop view if exists v_json_view cascade;
execute $a$select
string_agg(distinct format('import_data ->> %L as %I', jkey, jkey), ', ')
into
l_keys
from $a$ ||
tname || $b$,
json_object_keys(import_data) as t(jkey)$b$;
execute 'create view v_json_view as select ' || l_keys || ' from ' || tname;
return 0;
end $function$ ;
The error I am getting is
SQL Error [0A000]: ERROR: EXECUTE of SELECT ... INTO is not implemented
Hint: You might want to use EXECUTE ... INTO or EXECUTE CREATE TABLE ... AS instead.
Where: PL/pgSQL function "JsonToView"(text) line 10 at EXECUTE
The problem is the superfluous nested DO statement.
The variable tname exists only in the scope of the function, not in the nested DO statement. DO is an SQL statement, not a PL/pgSQL statement, and there are no variables in SQL. Also, DO does not allow parameters.
Get rid of the DO and you will be fine.
I have a two tables, table_version_1 and table_version_2, I am trying to generate a new table based on these two tables. For which I have to write 4 stored procedures,
procedure1, procedure2, procedure3, procedure4
I am triggering procedure1 from my application
select * from procedure1
I am calling procedure2 in procedure1
PERFORM procedure2
and I am calling procedure3 in procedure2
PERFORM procedure3
and calling procedure4 in procedure3
PERFORM procedure3
My stored procedure looks something like below.
CREATE OR REPLACE FUNCTION procedure1(tb_name, compare_tb_name, file_version, compare_file_version)
RETURNS text
LANGUAGE 'plpgsql'
COST 100
VOLATILE
AS $BODY$
DECLARE
createquery text;
fpo_data jsonb;
inddata jsonb;
f_primary_key text;
rowscount INTEGER;
datacount INTEGER;
fcdata1 text;
fid INTEGER;
BEGIN
createquery := 'CREATE TABLE IF NOT EXISTS ' || tb_name || '_' || file_version || '_' || compare_file_version || '_pk(
id serial PRIMARY KEY,
fc_pkey1 VARCHAR (250) NULL,
fc_pkey2 VARCHAR (250) NULL,
fc_pkey3 VARCHAR (250) NULL,
fpo_data TEXT NULL,
fid INTEGER NULL
)';
EXECUTE createquery;
EXECUTE 'SELECT count(*) FROM ' || tb_name || '_' || file_version || '_' || compare_file_version || '_pk' INTO rowscount;
EXECUTE 'SELECT count(*) FROM ' || tb_name INTO datacount;
IF(rowscount <> datacount) THEN
EXECUTE 'SELECT json_agg((fpdata, foseqid))::jsonb
FROM (SELECT fo_data AS fpdata, fo_seq_id as foseqid
FROM '||tb_name||'
LIMIT 1000
) t' INTO fpo_data;
FOR inddata IN SELECT * FROM jsonb_array_elements(fpo_data) LOOP
EXECUTE 'INSERT INTO ' || tb_name || '_' || file_version || '_' || compare_file_version || '_pk(fc_pkey1, fpo_data, fid) VALUES ($1, $2, $3)' USING f_primary_key, inddata, fid;
END LOOP;
ELSE
PERFORM procedure2(tb_name, compare_tb_name, file_version, compare_file_version);
END IF;
return 'Primary Key Generation completed';
END;
$BODY$;
I have not written the complete query. I just written important steps of my query.
My issue is that, in the above query I have create query, insert query and select query and at the end of the stored procedure I have written return statement. If I remove the return all my steps create query, insert query and select query are failing and if I write return then it is not going to procedure2. What is the correct process to run this procedure?
I have a sql function that creates a materialized view:
CREATE FUNCTION reports_mt_views(exclude_ids int[]) RETURNS void AS
$BODY$
BEGIN
EXECUTE 'CREATE MATERIALIZED VIEW tx_materialized AS
SELECT tx.transaccion_id AS tx_transaccion_id,
...
WHERE creation_date > (current_date - interval '' 3 month '')
AND (account_id <> ALL (' || $1 || '))'
RETURN;
END;
$BODY$ LANGUAGE plpgsql STRICT;
I also tried as:
AND account_id NOT IN ' || $1|| ')'
But it does not work. When I execute:
SELECT reports_mt_views(ARRAY [1,2,8,538524]);
I have this error:
ERROR: operator does not exist: text || integer[]
LINE 171: AND (account_id <> ALL (' || $1 || '))'
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
There is not a problem with the array itself I tested it with a FOR loop and works. But into the condition it does not. What I have missed here?
The solution was to concanate the array as a text then it can be readby the clause where not in.
CREATE OR REPLACE FUNCTION pps.reports_mt_views(exclude_ids integer[])
...
DECLARE
in_accounts ALIAS FOR $1;
out_accounts TEXT;
BEGIN
out_accounts := in_accounts;
out_accounts := trim(leading '{' FROM out_accounts);
out_accounts := trim(trailing '}' FROM out_accounts);
And it can be used as:
WHERE (orden.cuenta_id NOT IN (' || out_accounts || '))
I am creating function which return the select query result from it. The details as shown below in the example:
Example:
Create or replace function fun_test(cola text,colb text,rel text)
returns table(columna text,columnb text)as
$Body$
Declare
table_name varchar :='Table_';
Begin
table_name := table_name || rel;
return query select distinct || quote_ident(cola) ||,||quote_ident(colb)|| from || quote_ident(table_name) ;
end;
$Body$
language plpgsql;
Error:
ERROR: syntax error at or near "||"
LINE 10: ...| quote_ident(cola) ||,||quote_ident(colb)|| from || quote_i...
^
You're trying to construct a query dynamically, but you're not using EXECUTE. That won't work. You can't just put arbitrary expressions in place of identifiers, like:
return query select distinct || quote_ident(cola) ||,||quote_ident(colb)|| from || quote_ident(table_name) ;
which is why you're getting the error at:
from ||
^
as that's syntactically invalid nonsense.
Instead I think you want:
RETURN QUERY EXECUTE 'select distinct ' || quote_ident(cola) ||', '||quote_ident(colb)||' from '|| quote_ident(table_name);
which is better written as:
RETURN QUERY EXECUTE format('select distinct %I, %I from %I', cola, colb, table_name);