【问题标题】:Execute multiple SQL strings created in query执行查询中创建的多个 SQL 字符串
【发布时间】:2021-09-12 03:13:19
【问题描述】:

我正在尝试为(几乎)数据库中的所有表动态创建审计表。我可以动态生成适当的 SQL,如下所示:

SELECT                          
    'CREATE TABLE IF NOT EXISTS '
    || tab_name || '_audit(timestamp TIMESTAMPTZ NOT NULL, entity JSONB NOT NULL);'
FROM (
    SELECT                                                                     
        quote_ident(table_schema) || '.' || quote_ident(table_name) as tab_name
    FROM                         
        information_schema.tables
    WHERE                                                       
        table_schema NOT IN ('pg_catalog', 'information_schema')
        AND table_schema NOT LIKE 'pg_toast%'
) tablist;

这给了我一系列表格的行:

CREATE TABLE IF NOT EXISTS public.table1_audit(timestamp TIMESTAMPTZ NOT NULL, entity JSONB NOT NULL);
CREATE TABLE IF NOT EXISTS public.table2_audit(timestamp TIMESTAMPTZ NOT NULL, entity JSONB NOT NULL);

等等。 我正在努力解决的实际上是执行那些动态生成的查询。通过搜索 EXECUTE 似乎是必需的功能,但如果不产生语法错误或什么都不做,我无法让它工作。我希望能指出正确的方向。

【问题讨论】:

  • 这是否回答了您的问题:dynamic sql query in postgres?
  • 并非如此,在 EXECUTE 中包装会产生语法错误
  • 如果您使用的是 psql,请不要使用 ;在 sql 语句的末尾运行 \gexec
  • 就是这样,我实际上是在尝试将其写入 django 手动迁移,而不是通过 psql

标签: sql postgresql plpgsql dynamic-sql


【解决方案1】:

您可以在DO statement 的循环中使用带有EXECUTE 的动态SQL:

DO
$$
DECLARE
   _sql text;
BEGIN
   FOR _sql IN
      SELECT format('CREATE TABLE IF NOT EXISTS %I.%I(timestamp timestamptz NOT NULL, entity jsonb NOT NULL)'
                  , schemaname
                  , tablename || '_audit')
      FROM   pg_catalog.pg_tables  -- only tables and partitioned tables, no toast tables
      WHERE  schemaname NOT IN ('pg_catalog', 'information_schema')
   LOOP
      RAISE NOTICE '%', _sql;
      -- EXECUTE _sql;
   END LOOP;
END
$$;

我先输入了RAISE NOTICE 来检查有效载荷。
取消注释 EXECUTE 行以实际执行。

quote_ident(table_name)之前附加了“_audit”。对于所有实际需要双引号的表名,这将失败。你必须做quote_ident(table_name || 'audit')。但我改用format()。更方便。见:

我也使用pg_catalog.pg_tables 而不是information_schema.tables。更快,正是您所需要的。见:

我取消了子查询 - 不需要。

【讨论】:

  • 谢谢,这正是我所追求的!
猜你喜欢
  • 2012-07-27
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
  • 2011-04-15
  • 2016-04-04
  • 1970-01-01
  • 2016-12-10
  • 2017-03-29
相关资源
最近更新 更多