PostgreSQL 函数在循环函数中动态重塑和创建表
PostgreSQL Function to dynamically reshape and create tables in loop function
我对 Postgre 还很陌生SQL,所以请多关照。
我很确定我的问题是我混合了普通和动态 SQL。我已经阅读了relevant documentation,但我没有足够的经验来了解我哪里出了问题(希望我的问题不是更根本的问题)。
当前脚本因查询执行错误而失败:
SQL Error [42601]: ERROR: syntax error at or near "CREATE"
我打算使用此功能逆透视 >9,000 个表(用于分析目的);幸运的是所有表都具有相同的结构。
CREATE OR REPLACE FUNCTION all_schemaTables_unpivot(_schemaName text, _tableName text)
RETURNS void AS
$BODY$
DECLARE
_tbl record;
BEGIN
FOR _tbl IN
SELECT
quote_ident(schemaname) || '.' || quote_ident(tablename) AS fName,
quote_ident(tablename) AS tName
FROM pg_tables
WHERE schemaname = _schemaName
AND tablename LIKE _tableName
LOOP
EXECUTE 'CREATE TABLE ' || _tbl.tName || '_up AS
SELECT region_id, key AS sequential_id, value
FROM (SELECT row_to_json(t.*) AS line, region_id
FROM ' || _tbl.tName || ' AS t) AS r
JOIN LATERAL json_each_text(r.line) ON (key <> "region_id")';
END LOOP;
END;
$BODY$ LANGUAGE plpgsql;
提前致谢。
为了让脚本正常工作,我只需要解决两件事:
- 我最初没有在查询连接周围设置适当的空格(感谢@KaushikNayak)
- 我错误地设置了我的动态变量周围的引号值(参见 'quote_ident(_tbl.newTableName)' 添加。比我更精通 PostgreSQL 的人肯定会有更简洁的方法 - 但至少它有效!
故事的寓意,有时修复正盯着你的脸,但你盯着脚本看的时间太长了!放一放,答案就明了。
CREATE OR REPLACE FUNCTION
all_schemaTables_unpivot(_schemaName text, _tableName text)
RETURNS void AS
$BODY$
DECLARE
_tbl record;
BEGIN
FOR _tbl IN
SELECT
quote_ident(schemaname) || '.' || quote_ident(tablename) AS fullNamePath,
quote_ident(tablename) || '_up' AS newTableName
FROM pg_tables
WHERE schemaname = _schemaName
AND tablename LIKE _tableName
LOOP
EXECUTE 'CREATE TABLE '|| quote_ident(_tbl.newTableName) ||' AS
SELECT region_id, key AS sequential_id, value
FROM (SELECT row_to_json(t.*) AS line, region_id
FROM '|| _tbl.fullNamePath ||' AS t) AS r
JOIN LATERAL json_each_text(r.line) ON (key <> "region_id");';
END LOOP;
END;
$BODY$ LANGUAGE plpgsql;
我对 Postgre 还很陌生SQL,所以请多关照。
我很确定我的问题是我混合了普通和动态 SQL。我已经阅读了relevant documentation,但我没有足够的经验来了解我哪里出了问题(希望我的问题不是更根本的问题)。
当前脚本因查询执行错误而失败:
SQL Error [42601]: ERROR: syntax error at or near "CREATE"
我打算使用此功能逆透视 >9,000 个表(用于分析目的);幸运的是所有表都具有相同的结构。
CREATE OR REPLACE FUNCTION all_schemaTables_unpivot(_schemaName text, _tableName text)
RETURNS void AS
$BODY$
DECLARE
_tbl record;
BEGIN
FOR _tbl IN
SELECT
quote_ident(schemaname) || '.' || quote_ident(tablename) AS fName,
quote_ident(tablename) AS tName
FROM pg_tables
WHERE schemaname = _schemaName
AND tablename LIKE _tableName
LOOP
EXECUTE 'CREATE TABLE ' || _tbl.tName || '_up AS
SELECT region_id, key AS sequential_id, value
FROM (SELECT row_to_json(t.*) AS line, region_id
FROM ' || _tbl.tName || ' AS t) AS r
JOIN LATERAL json_each_text(r.line) ON (key <> "region_id")';
END LOOP;
END;
$BODY$ LANGUAGE plpgsql;
提前致谢。
为了让脚本正常工作,我只需要解决两件事:
- 我最初没有在查询连接周围设置适当的空格(感谢@KaushikNayak)
- 我错误地设置了我的动态变量周围的引号值(参见 'quote_ident(_tbl.newTableName)' 添加。比我更精通 PostgreSQL 的人肯定会有更简洁的方法 - 但至少它有效!
故事的寓意,有时修复正盯着你的脸,但你盯着脚本看的时间太长了!放一放,答案就明了。
CREATE OR REPLACE FUNCTION
all_schemaTables_unpivot(_schemaName text, _tableName text)
RETURNS void AS
$BODY$
DECLARE
_tbl record;
BEGIN
FOR _tbl IN
SELECT
quote_ident(schemaname) || '.' || quote_ident(tablename) AS fullNamePath,
quote_ident(tablename) || '_up' AS newTableName
FROM pg_tables
WHERE schemaname = _schemaName
AND tablename LIKE _tableName
LOOP
EXECUTE 'CREATE TABLE '|| quote_ident(_tbl.newTableName) ||' AS
SELECT region_id, key AS sequential_id, value
FROM (SELECT row_to_json(t.*) AS line, region_id
FROM '|| _tbl.fullNamePath ||' AS t) AS r
JOIN LATERAL json_each_text(r.line) ON (key <> "region_id");';
END LOOP;
END;
$BODY$ LANGUAGE plpgsql;