sql - 执行查询中创建的多个 SQL 字符串
问题描述
我正在尝试为数据库中的(几乎)所有表动态创建审计表。我可以动态生成适当的 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
似乎是必需的功能,但如果不产生语法错误或什么都不做,我就无法让它工作。我会欣赏正确方向的观点。
解决方案
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
. 更快,正是您所需要的。看:
我取消了子查询 - 不需要。
推荐阅读
- node.js - NPX create-react-app 终端告诉我节点未安装,但它是
- windows - 如何从命令提示符禁用驱动程序的电源管理?
- vim - vglobal 函数中带有参数,将文本文件过滤到临时文件中
- sql-server - 我从一个类似的查询中得到多个类似的结果,我该如何组合结果?
- javascript - 打印反应原生发票
- excel - Excel 2019:非连续命名范围的偏移量不起作用
- wordpress - 如何使用 Elementor 表单隐藏电子邮件中的空表单字段标签?
- python - 如何将 PIL ImageDraw 转换为 Image
- docker - 从内部和外部访问容器的相同 IP
- zurb-foundation - Zurb Foundation Equalizer 仅适用于一个断点