I am getting folowwing error when execute my stored procedure. Does anyone knows how can i solve this issue? The table mentioned in error is always the same and it's the first one from the top of the list from my schema.
This is my error:
relation "t_ser_d2ert" does not exist 42P01
This is my stored procedure:
CREATE OR REPLACE PROCEDURE schem.myprocedure()
LANGUAGE plpgsql
AS $procedure$
declare
sessionPid numeric = pg_backend_pid();
BEGIN
begin
raise notice 'schem.myprocedure()';
insert into myschema.t_tables (tablename, sizemb, rowcounts, created)
SELECT
table_name as tablename,
(pg_relation_size(quote_ident(table_name)) / 1024 /1024) sizemb,
reltuples as rowcounts, NOW() FROM information_schema.tables ist
left join pg_class pc on pc.relname = ist.table_name
WHERE table_schema = 'myschema';
exception
when others then
raise notice ' >> Error for schem.myprocedure()>> % %', sqlerrm, sqlstate;
end ;
END;
$procedure$
;
Related
CREATE or REPLACE PROCEDURE admin.sp_pm_drop_all_scratch_tables (redshift_table_name IN VARCHAR)
LANGUAGE plpgsql
as $$
DECLARE
temp_table_name varchar(100);
row record;
BEGIN
temp_table_name := 'procedure_temp_table';
EXECUTE 'DROP TABLE if exists '||temp_table_name;
EXECUTE 'CREATE TEMP TABLE '||temp_table_name||' as select * from nidhi_test.'||redshift_table_name;
FOR row IN(
select 'DROP TABLE IF EXISTS '|| schemaname || '."'|| tablename|| '" cascade' as sql_name
from pg_tables
where schemaname in ('nidhi_scratch')
and schemaname || '.'|| tablename not in (select schema_name || '.'|| table_name from temp_table_name)
)
LOOP
EXECUTE row.sql_name;
END LOOP;
end;
$$ ;
i am trying to create this procedure but getting this error[42601][500310] Amazon Invalid operation: syntax error at or near "$1";
when i try to run this procedure it gives me the error
[42601][500310] Amazon Invalid operation: syntax error at or near "$1";
basically i want to drop the tables from schema nidhi_scratch and not drop tables which are there in temp_table_name
temp_table_name is getting filled from nidhi_test.‘||redshift_table_name
redshift_table_name is a variable getting filled from airflow
I am new to postgres. I need to create a function that will take a list of all the tables in the database whose names are stored in one table and then delete the records of all the tables that are older than x days and have a certain row_status. Some tables do not have a row_status column.
I get an error when I try to save a written function in dbeaver -> ERROR: syntax error at or near "||"
create function delete_old_records1(day1 int, row_status1 character default null, row_status2 character default null)
returns void
language plpgsql
as $$
declare
c all_tables1%rowtype;
begin
for c in select * from all_tables1 loop
if exists(SELECT column_name FROM information_schema.columns
WHERE table_schema = 'yard_kondor' AND table_name =c.table_name AND column_name = 'row_status') then
execute 'delete from '||c.table_name||' where row_create_datetime>current_date-day1+1 and
row_status in (coalesce(row_status1,''P''), row_status2)';
else
execute 'delete from '||c.table_name||' where row_create_datetime>current_date-day1+1';
raise notice 'Table '||c.table_name||' does not have row_status column';
end if;
end loop;
return;
commit;
end;
$$
Your immediate problem is this line:
raise notice 'Table '||c.table_name||' does not have row_status column';
That should be:
raise notice 'Table % does not have row_status column', c.table_name;
However, your function could be improved a bit. In general it is highly recommended to use format() to generate dynamic SQL to properly deal with identifiers. You also can't commit in a function. If you really need that, use a procedure.
create function delete_old_records1(day1 int, row_status1 character default null, row_status2 character default null)
returns void
language plpgsql
as $$
declare
c all_tables1%rowtype;
begin
for c in select * from all_tables1
loop
if exists (SELECT column_name FROM information_schema.columns
WHERE table_schema = 'yard_kondor'
AND table_name = c.table_name
AND column_name = 'row_status') then
execute format('delete from %I
where row_create_datetime > current_date - %J + 1
and row_status in (coalesce(row_status1,%L), row_status2)', c.table_name, day1, 'P');
else
execute format('delete from %I where row_create_datetime > current_date - day1 + 1', c.table_name);
raise notice 'Table % does not have row_status column', c.table_name;
end if;
end loop;
return;
-- you can't commit in a function
end;
$$
Thank you for answer. Now I'm able to save function, but currently I have a problem with running the function.
I started the function with:
DO $$ BEGIN
PERFORM "delete_old_records1"(31,'P','N');
END $$;
I started script with ALT+X (also tried select delete_old_records1(31,'P','N');) and have this error:
SQL Error [42703]: ERROR: column "day1" does not exist
Where: PL/pgSQL function delete_old_records1(integer,character,character) line 11 at EXECUTE statement
SQL statement "SELECT "delete_old_records1"(31,'P','N')"
PL/pgSQL function inline_code_block line 2 at PERFORM
do
$xyz$
declare
y text;
i record;
begin
y := to_char(current_timestamp, 'YYYYMMDDHHMMSS');
raise notice '%',y;
execute 'CREATE TEMP TABLE someNewTable'
||y
||' AS select * from ( VALUES(0::int,-99999::numeric), (1::int, 100::numeric)) as t (key, value)';
for i in (select * from someNewTable||y) loop
raise notice '%',i.key;
end loop;
end;
$xyz$ language 'plpgsql'
ERROR: syntax error at or near "||"
LINE 13: for i in (select * from someNewTable||y) loop
Im unable to understand why the error is at the PIPE symbol. Please help me. I have been trying in Oracle db too, but same error. Am I doing anything wrong here?
The query in for ... loop statement also has to be dynamic, so you should use execute twice.
Use the format() function which is very convenient in conjunction with execute:
do $xyz$
declare
y text;
i record;
begin
y := to_char(current_timestamp, 'YYYYMMDDHHMMSS');
raise notice '%', y;
execute format($ex$
create temp table somenewtable%s
as select * from (
values
(0::int, -99999::numeric),
(1::int, 100::numeric)
) as t (key, value)
$ex$, y);
for i in
execute format($ex$
select * from somenewtable%s
$ex$, y)
loop
raise notice '%',i.key;
end loop;
end;
$xyz$ language 'plpgsql';
Hello I got 500 tables in public and I try to create triggers for all tables ,by first finding all table names and creating a trigger if not already exists here is the code:
CREATE OR REPLACE FUNCTION get_all_results() RETURNS VOID AS
$BODY$
DECLARE
r RECORD;
BEGIN
IF (SELECT "session_user"() <> 'asdf' THEN
FOR r IN (SELECT 'CREATE TRIGGER ' || tab_name|| '_if_modified_trg AFTER INSERT OR UPDATE OR DELETE ON ' || tab_name|| ' FOR EACH ROW EXECUTE PROCEDURE audit.if_modified_func(); ' AS trigger_creation_query
FROM (
SELECT quote_ident(table_name) as tab_name
FROM information_schema.tables
WHERE table_schema='public'
AND table_type != 'VIEW'
) AS foo WHERE tab_name||'_if_modified_trg' NOT IN (SELECT tgname from pg_trigger where not tgisinternal))
LOOP
-- can do some processing here
EXECUTE r.trigger_creation_query;
END LOOP;
RETURN;
END IF;
END
$BODY$
LANGUAGE plpgsql;
SELECT * FROM get_all_results();
and I get this error :
ERROR: syntax error at or near "_if_modified_trg"
LINE 1: CREATE TRIGGER "position"_if_modified_trg AFTER INSERT OR UP...
I really have table position in one of these 500 and the name is position not "position".
I'm working with topologies in PostGIS and to create a TopoGeometry column, I'm using this loop:
DO $$DECLARE r record;
BEGIN
FOR r IN SELECT * FROM table_uf_11 LOOP
BEGIN
UPDATE table_uf_11 SET tg_geom = toTopoGeom(ST_Force2D(geom),'topology_uf_11', 1, 1)
WHERE gid= r.gid;
EXCEPTION
WHEN OTHERS THEN
RAISE WARNING 'Loading of record % failed: %', r.gid, SQLERRM;
END;
END LOOP;
END$$;
The reason for using this loop is because in some rows the toTopoGeom function displays error, but are just a few cases, for exemplo 38 cases in 24.000.
Using this structure I can identify which cases are problematic in the log and fix them later.
My problem is that I have another 26 tables with their respective topologies, all of them identified by the state code, for exemplo:
table_uf_12 / topology_uf_12
table_uf_13 / topology_uf_13
table_uf_14 / topology_uf_14
...
table_uf_53 / topology_uf_53
The state code are not necessarily sequential, but the names has the same pattern. Column names as geom and tg_geom are equal for all tables.
How can I make a function or another loop structure to replicate this process in all 27 tables and the same time save the log of each table?
I tried to make a function, but in this case the arguments would be the table name and the topology name, and i'm having difficult to elaborate this structure.
Any suggestions?
I think this should do it:
DO $BODY$
DECLARE
t regclass;
gid bigint;
BEGIN
FOR t IN SELECT oid::regclass FROM pg_class WHERE relname ~ '^table_uf_\d+$' LOOP
FOR gid IN EXECUTE 'SELECT gid FROM ' || t::text LOOP
BEGIN
EXECUTE
' UPDATE ' || t::text ||
' SET tg_geom = toTopoGeom(ST_Force2D(geom), $2, 1, 1)'
' WHERE gid = $1'
USING gid, replace(t::text, 'table', 'topology');
EXCEPTION
WHEN OTHERS THEN
RAISE WARNING 'Loading of record % failed: %', gid, SQLERRM;
END;
END LOOP;
END LOOP;
END
$BODY$