我有一个要求,bash脚本将字符串组成的表名传递给匿名PL/pgSQL块,如果它们存在于Postgr数据库中,该块将处理表.

下面是PL/pgSQL代码,假设given_tables变量具有由bash脚本提供的表名组成的字符串.

do $do$
<<outerblock>>
declare
    tab text;
    given_tables text[] := ARRAY['ocab1.cust_docu_map','ocsbc2.cust_docu_map'];
    table_names  text[] := ARRAY(
                              BEGIN
                                FOREACH tab IN ARRAY given_tables loop
                                    IF EXISTS
                                        ( SELECT 1
                                          FROM pg_class
                                          WHERE oid = tab::regclass
                                        )
                                    THEN
                                          SELECT concat_ws('.',relnamespace::regnamespace::text,relname)
                                          FROM pg_class
                                          WHERE oid = tab::regclass
                                          AND relreplident != 'f';
                                    END IF;
                                END LOOP;
                              END
                            );
begin
  foreach table in array table_names loop
    raise notice 'here is the table - %',outerblock.table;  
  end loop;
end $do$;

代码错误:

ERROR:  mismatched parentheses at or near ";"
LINE 18:             AND relreplident != 'f';
                                            ^

不知道我哪里错了?

推荐答案

DO
$do$
DECLARE
   _given_tbls text[] := '{ocab1.cust_docu_map,ocsbc2.cust_docu_map}';
   _tbl text;
BEGIN
   FOR _tbl IN
      SELECT format('%I.%I', n.nspname, c.relname)         -- properly quoted
      FROM   unnest(_given_tbls) t(tbl)
      JOIN   pg_class     c ON c.oid = to_regclass(t.tbl)  -- does not raise exception
      JOIN   pg_namespace n ON n.oid = c.relnamespace
      WHERE  c.relreplident != 'f'
   LOOP
      RAISE NOTICE 'valid table: %', _tbl;  
      -- or do something here!
   END LOOP;
END
$do$;

to_regclass(_tab)不引发无效表名的异常.参见:

Remember that identifiers stored in catalog tables may need double-quoting. Quote with format() or quote_ident() to defend against syntax errors or even SQL injection attacks.
regclass values are quoted automatically when converted to text, but only schema-qualified when necessary with the current search_path. You seem to want fully qualified names. See:

而且,运行一个查询并在结果中循环要便宜得多(如果你真的需要循环?),比运行另一个查询(甚至两个!)数组中的每个元素.

Sql相关问答推荐

如何根据SQL中的列条件获取下一个时间戳?

不可能在SQL MERGE子句中引发异常

如何将`now()`作为SQL插入语句的一部分?

具有多个条件的SQL否定

在子窗口SQL Presto中使用特定条件执行值计数

SQL按组 Select 最小值,当值不存在时为Null

使用特定的Order By子句随机化SQL输出

无法访问级联删除导致的触发器中已删除的外键记录

存储过程太慢

在 PostgreSQL 中生成时间序列查询

聚合内部的条件在哪里?

在 SQL Server 中查找重复项

如何在sparksql查询中使用日期值?

正则表达式:停在第一个匹配的其中一个字符位置上

正则表达式忽略特定数据部分的分隔符

使用in和and运算符过滤记录的条件

我如何编写一个遍历数组数组并将所有值连接成一个字符串的 postgres 函数

使用SQL中另一个表的查询结果在表中查找记录

PostgreSQL 如何在一组项目及其数量上找到完全相同的订单?

如何使用子查询锁定此查询中的选定行?