Question

I have a table with 52 fields at the moment but it will grow, and I'm trying to write a dynamic INSERT statement that will fill the fields with 0 without having to specify 52 0's.

This is a cut-down version of the table:

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)
)

The INSERT script would be:

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

The DEFAULT NULL on the columns is intentional so I can't simply change that to 0.

I can get a string of enough '0,' repetitions to fill the rest of the insert:

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

but it takes the string_agg all as one field - I need to split those out into individual fields.

This is my attempt:

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')
)

but the output is:

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

instead of

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

I did try to create an array and unnest() it, but the result is multiple rows not multiple columns.

Could someone please suggest a syntax or function that might get this working?

Was it helpful?

Solution

You need dynamic SQL for that. Use EXECUTE in a DO statement or a plpgsql function:

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$;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top