postgresql - 将查询结果保存到列数未知的临时表中
问题描述
我正在尝试在 plpgsql 中创建以下函数:
CREATE OR REPLACE FUNCTION pg_temp.select_all(query text)
RETURNS VOID AS $$
DECLARE
schemasT RECORD;
BEGIN
FOR schemasT IN (
SELECT schema_name
FROM information_schema.schemata
WHERE schema_name IN (
SELECT login
FROM cdu.nc_tenant
)
) LOOP
SET SEARCH PATH TO schemasT;
EXECUTE query INTO something;
END LOOP;
END; $$
LANGUAGE plpgsql;
这样传入函数的任何查询都会运行到所有可用的模式中并返回查询结果。使用该功能将是这样的:
pg_temp.select_all('SELECT count(1) FROM sku')
将返回:
架构 | 数数 |
---|---|
架构1 | 58 |
模式2 | 42 |
另一个例子是:
pg_temp.select_all('SELECT * FROM cdu.nc_tenant_variables where variable = ''theme''')
将返回:
架构 | 多变的 | 价值 |
---|---|---|
架构1 | 主题 | 黑暗的 |
模式2 | 主题 | 光 |
为什么?
有时我需要跨模式查询事物,我正在寻找一种更好的方法来做到这一点,而不是这样做:
SELECT 'schema1' AS schema, count(1) FROM schema1.sku
UNION ALL
SELECT 'schema2' AS schema, count(1) FROM schema2.sku
UNION ALL
SELECT 'schema3' AS schema, count(1) FROM schema3.sku;
解决方案
我以某种方式使它工作,但它返回一个 JSON 对象而不是普通表:
DROP FUNCTION pg_temp.select_all;
CREATE OR REPLACE FUNCTION pg_temp.select_all(query TEXT, whole int DEFAULT 0)
RETURNS table (j json) AS $$
DECLARE
schemasT RECORD;
counter int := 1;
test RECORD;
BEGIN
DROP TABLE IF EXISTS resultquery;
FOR schemasT IN (
SELECT schema_name
FROM information_schema.schemata
WHERE schema_name IN (
SELECT login
FROM cdu.nc_tenant
)
) LOOP
EXECUTE format('SET SEARCH_PATH TO %I', schemasT.schema_name);
IF counter = 1 THEN
EXECUTE 'CREATE TEMP TABLE resultquery AS '|| query;
ALTER TABLE pg_temp.resultquery ADD COLUMN tenant varchar;
TRUNCATE TABLE resultquery;
END IF;
DROP TABLE IF EXISTS temptemp;
EXECUTE 'CREATE TEMP TABLE temptemp AS '|| query;
ALTER TABLE pg_temp.temptemp ADD COLUMN tenant varchar;
UPDATE pg_temp.temptemp SET tenant = schemasT.schema_name;
EXECUTE 'INSERT INTO pg_temp.resultquery SELECT * FROM pg_temp.temptemp';
counter := counter + 1;
END LOOP;
IF whole = 0 THEN
RETURN QUERY SELECT to_json(a) FROM (SELECT * FROM pg_temp.resultquery) a;
ELSE
RETURN QUERY SELECT json_agg(a) FROM (SELECT * FROM pg_temp.resultquery) a;
END IF;
END; $$
LANGUAGE plpgsql;
使用功能:
SELECT pg_temp.select_all('select count(1) from sku', 1);
返回一个单行 JSON 对象
推荐阅读
- c# - 如何从 Rider 调试 WSL2 中的进程?
- javascript - 处理(P5JS)curveVertex 不连接第 1 和第 2 点,虽然 vertex() 会
- sql-server - 如何将多主 Microsoft SQL Server 数据库部署为 IaaS 或 AWS RDS
- questdb - 通过 SQL 插入记录时遇到错误代码 00000
- c# - 绑定从方法获得的属性,返回对象
- azure - 如何追溯标记 Azure 资源?
- mongodb - 如何在一个 MongoDB 查询中加入两个集合
- reactjs - React js select不将文本显示为值
- sql - 同时选择和更新行
- python - 如何在 Gurobipy 中定义与二维矩阵相乘的目标函数