将逗号分隔的字符串拆分为列

时间:2014-03-13 06:25:33

标签: sql postgresql plpgsql dynamic-sql sql-insert

我目前有一个包含52个字段的表,但它会增长,我正在尝试编写一个动态INSERT语句,用0填充字段,而不必指定52 0。

这是表格的简化版本:

CREATE TABLE tbladmin_reportsettings
(
  intreportsettingsid integer NOT NULL,
  strReportGroup character varying (20) NOT NULL,
  ysnExcludePax1 smallint DEFAULT NULL,
  ysnExcludePax3 smallint DEFAULT NULL,
  ysnExcludePax2 smallint DEFAULT NULL,
  ysnExcludePax4 smallint DEFAULT NULL,
  ysnExcludePax5 smallint DEFAULT NULL,
  ysnHideAgentABN smallint DEFAULT NULL,
CONSTRAINT pk_tbladmin_reportsettings PRIMARY KEY (intreportsettingsid)
)

INSERT脚本将是:

INSERT INTO tblAdmin_ReportSettings
VALUES
((select * from getautonumber('ReportSettingsID')),'Base',0,0,0,0,0);

列上的DEFAULT NULL是故意的,所以我不能简单地将其更改为0.

我可以得到一串足够的'0',重复填充插入的其余部分:

select string_agg(0::text,','::text) from information_schema.columns
WHERE table_name = 'tbladmin_reportsettings'
AND column_name NOT IN('intreportsettingsid', 'strreportgroup')

但它将string_agg all作为一个字段 - 我需要将它们分成单个字段。

这是我的尝试:

INSERT INTO tblAdmin_ReportSettings
VALUES
(select (select * from getautonumber('ReportSettingsID')),'Base',
        trim(string_agg('0',','),',')
 from information_schema.columns
 WHERE table_name = 'tbladmin_reportsettings'
 AND column_name NOT IN('intreportsettingsid', 'strreportgroup')
)

但输出是:

column1 | column2 | column3
29 | Base | 0,0,0,0,0

而不是

column1 | column2 | column3 | column4 | column5 | column6 | column7
29 | Base | 0 | 0 | 0 | 0 | 0

我确实尝试创建一个数组并且不需要它(),但结果是多行而不是多列。

有人可以建议一种可能使其正常工作的语法或功能吗?

1 个答案:

答案 0 :(得分:2)

您需要动态SQL。在EXECUTE或plpgsql函数中使用DO statement

DO
$do$
BEGIN

EXECUTE (
SELECT 'INSERT INTO t1 (intreportsettingsid,strReportGroup,'
        || string_agg(column_name, ',') || $$)
VALUES (getautonumber('ReportSettingsID'),'Base',$$
        || string_agg('0', ','::text) || ')'
FROM   information_schema.columns
WHERE  table_name = 'tbladmin_reportsettings'
AND    table_aschema = 'public'          -- table name might not be unique!
AND    column_name NOT IN('intreportsettingsid', 'strreportgroup')
);

END
$do$;