将查询结果保存到列数未知的临时 table
Saving a query result into a temp table with unknown number of columns
我正在尝试在 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;
因此,传递给该函数的任何查询都会 运行 到所有可用的模式中,并 return 查询的结果。使用该函数将是这样的:
pg_temp.select_all('SELECT count(1) FROM sku')
会 return:
Schema
count
Schema1
58
Schema2
42
另一个例子是:
pg_temp.select_all('SELECT * FROM cdu.nc_tenant_variables where variable = ''theme''')
会 return:
Schema
variable
value
Schema1
theme
dark
Schema2
theme
light
为什么?
有时我需要跨模式查询内容,我正在寻找更好的方法来执行此操作而不是执行以下操作:
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;
我以某种方式让它工作,但它 returns 一个 JSON 对象而不是一个普通的 table:
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);
Returns一行JSON对象
我正在尝试在 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;
因此,传递给该函数的任何查询都会 运行 到所有可用的模式中,并 return 查询的结果。使用该函数将是这样的:
pg_temp.select_all('SELECT count(1) FROM sku')
会 return:
Schema | count |
---|---|
Schema1 | 58 |
Schema2 | 42 |
另一个例子是:
pg_temp.select_all('SELECT * FROM cdu.nc_tenant_variables where variable = ''theme''')
会 return:
Schema | variable | value |
---|---|---|
Schema1 | theme | dark |
Schema2 | theme | light |
为什么?
有时我需要跨模式查询内容,我正在寻找更好的方法来执行此操作而不是执行以下操作:
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;
我以某种方式让它工作,但它 returns 一个 JSON 对象而不是一个普通的 table:
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);
Returns一行JSON对象