postgresql - PL/pgsql 在查询中动态转换 regclass 的正确方法
问题描述
我有一个函数将遍历一个表,然后遍历从外部循环中的每个表继承的所有表。我发现了一个很棒的函数来查找从父表继承的表。我的问题是,如何动态更改表名以查找所有父级?所以'shopmaster.pb'::regclass 会类似于'shopmaster.'||i.tablename::regClass。
CREATE OR REPLACE FUNCTION shopmaster.cascade_filters()
RETURNS jsonb AS $$
DECLARE
i record;
k shopmaster."catalog_filters";
BEGIN
DELETE FROM shopmaster.catalog_filters WHERE isparent=false;
FOR i IN SELECT shopmaster.catalog.catalogid,columnname,columntype,columnnvalues,
tablename FROM shopmaster.catalog_filters INNER JOIN catalog ON
(catalog_filters.catalogid=catalog.catalogid) WHERE isparent=true LOOP
FOR k IN
WITH RECURSIVE inh AS (
SELECT i.inhrelid FROM pg_catalog.pg_inherits i WHERE inhparent=
'shopmaster.pb'::regclass
UNION
SELECT i.inhrelid FROM inh INNER JOIN pg_catalog.pg_inherits i ON
(inh.inhrelid = i.inhparent)
)
SELECT pg_namespace.nspname, pg_class.relname
FROM inh
INNER JOIN pg_catalog.pg_class ON (inh.inhrelid=pg_class.oid)
INNER JOIN pg_catalog.pg_namespace ON
(pg_class.relnamespace=pg_namespace.oid) LOOP
END LOOP;
END LOOP;
END;
$$ LANGUAGE plpgsql;
解决方案
原来有一个简单的方法。执行一个子表达式来连接或获取表标识符,然后将其转换为 ::regclass。例如('shopmaster.'||i.tablename)::regclass
CREATE OR REPLACE FUNCTION shopmaster.cascade_filters()
RETURNS jsonb AS $$
DECLARE
i record;
k record;
BEGIN
DELETE FROM shopmaster.catalog_filters WHERE isparent=false;
FOR i IN SELECT shopmaster.catalog.catalogid,columnname,columntype,
columnnvalues,tablename
FROM shopmaster.catalog_filters INNER JOIN shopmaster.catalog ON
(catalog_filters.catalogid=catalog.catalogid) WHERE isparent=true LOOP
FOR k IN
WITH RECURSIVE inh AS (
SELECT ih.inhrelid FROM pg_catalog.pg_inherits ih WHERE inhparent=
('shopmaster.'||i.tablename)::regclass
UNION
SELECT ih.inhrelid FROM inh INNER JOIN pg_catalog.pg_inherits ih ON
(inh.inhrelid = ih.inhparent)
)
SELECT pg_namespace.nspname, pg_class.relname,
shopmaster.catalog.catalogid
FROM inh
INNER JOIN pg_catalog.pg_class ON (inh.inhrelid=pg_class.oid)
INNER JOIN pg_catalog.pg_namespace ON
(pg_class.relnamespace=pg_namespace.oid)
INNER JOIN shopmaster.catalog ON
(pg_class.relname=shopmaster.catalog.tablename) LOOP
EXECUTE 'INSERT INTO shopmaster.catalog_filters (catalogid,'
||'columnname,columntype,columnnvalues,isparent,owner) '
||'VALUES($1,$2,$3,$4,false,$5)' USING k.catalogid,i.columnname,
i.columntype,i.columnnvalues,i.catalogid;
END LOOP;
END LOOP;
RETURN jsonb_build_object('ok',true);
END;
$$ LANGUAGE plpgsql;
推荐阅读
- r - 通过选择不匹配的数据子集数据集
- express - 为什么收到“/”获取请求后前两个函数不执行?
- jquery - 如何将参数从 jQuery 传递到 laravel 路由
- python - 如何检查一行中的所有列是否都是正数?
- antlr4 - 使用 PDDL 语言的默认 ANTLR4 语法解析错误
- php - 返回值 = 1 时回显
- algorithm - 反向移动到前面变换
- php - 如何使相同的文件包含在位于不同目录中的两个不同文件中以重定向到相同的最终路径?
- node.js - 无法让 websocket 客户端作为子进程运行
- reactjs - React useState Hook setter 没有数组变量的结果