错误:关系“ shemaname.trame”不存在SQL状态:42P01

时间:2019-07-25 20:09:38

标签: sql postgresql plpgsql

我想创建FUNCTION以从表中的所有架构中删除数据+ 6个月

CREATE OR REPLACE FUNCTION deleteTrame01 ()  
RETURNS SETOF TEXT AS $$
declare

    shemaName TEXT;
BEGIN
 For shemaName IN  select schema_name  from information_schema.schemata where schema_name NOT LIKE 'public'
 and schema_name NOT LIKE 'information_schema'
 and schema_name NOT LIKE 'pg_toast'
 and schema_name NOT LIKE 'pg_temp_1'
 and schema_name NOT LIKE 'pg_catalog'
 and schema_name NOT LIKE 'template_schema' 
 and schema_name NOT LIKE 'pg_toast_temp_1' LOOP
delete  from shemaName.trame where shemaName.trame.date < NOW() - INTERVAL '180 days' ;
  RETURN NEXT shemaName ;
END LOOP;
RETURN ;
END;
$$  LANGUAGE plpgsql;

错误=>

ERROR:  relation "shemaname.trame" does not exist
LINE 1: delete  from shemaName.trame where shemaName.trame.date < NO...
                     ^
QUERY:  delete  from shemaName.trame where shemaName.trame.date < NOW() - INTERVAL '180 days'
CONTEXT:  PL/pgSQL function deletetrame01() line 13 at SQL statement

**********错误**********

ERROR: relation "shemaname.trame" does not exist
SQL state: 42P01
Context: PL/pgSQL function deletetrame01() line 13 at SQL statement

1 个答案:

答案 0 :(得分:0)

您不能使用变量作为标识符。您需要为此使用动态SQL。这意味着构建一个字符串,其中包含您通过循环检索的架构名称。推荐的使用标识符构建SQL字符串的方法是使用format()函数,以便正确处理需要带引号的标识符。

“选择循环”的循环变量也需要是一条记录,而不是标量值-即使您只选择一个列。

最后,我将使用information_schema.tables并在表名上包含一个条件,以确保您未包括该表不存在的架构。没有通配符的多个NOT LIKE条件可以用单个NOT IN条件代替。

CREATE OR REPLACE FUNCTION deleteTrame01 ()  
RETURNS SETOF TEXT AS $$
declare
   l_rec record
BEGIN
  For l_rec IN  select schema_name
                from information_schema.tables
                where table_name = 'trame' --<< only include schemas that do have that table
                 and schema_name NOT IN ('public', 
                                         'information_schema', 
                                         'pg_catalog', 
                                         'template_schema' )
                 and schema_name NOT LIKE 'pg_toast%'
                 and schema_name NOT LIKE 'pg_temp%'
  LOOP
    execute format('delete from %I.trame where "date" < NOW() - INTERVAL ''180 days'', l_rec.schema_name) ;
    RETURN NEXT l_rec.shemaName;
  END LOOP;
  RETURN;
END;
$$  LANGUAGE plpgsql;