复制具有动态列名的记录 [英] Copy records with dynamic column names
问题描述
在PostgreSQL 9.3中,我有两个表具有不同的列:
I have two tables with different columns in PostgreSQL 9.3:
CREATE TABLE person1(
NAME TEXT NOT NULL,
AGE INT NOT NULL
);
CREATE TABLE person2(
NAME TEXT NOT NULL,
AGE INT NOT NULL,
ADDRESS CHAR(50),
SALARY REAL
);
INSERT INTO person2 (Name, Age, ADDRESS, SALARY)
VALUES ('Piotr', 20, 'London', 80);
我想将记录从person2
复制到person1
,但是列名可以在程序中更改,因此我想在程序中选择联合列名.因此,我创建了一个包含列名交集的数组.接下来,我使用一个函数:insert into .... select
,但是当我按名称将数组变量传递给函数时,却出现了错误.像这样:
I would like to copy records from person2
to person1
, but column names can change in program, so I would like to select joint column names in program. So I create an array containing the intersection of column names. Next I use a function: insert into .... select
, but I get an error, when I pass the array variable to the function by name. Like this:
select column_name into name1 from information_schema.columns where table_name = 'person1';
select column_name into name2 from information_schema.columns where table_name = 'person2';
select * into cols from ( select * from name1 intersect select * from name2) as tmp;
-- Create array with name of columns
select array (select column_name::text from cols) into cols2;
CREATE OR REPLACE FUNCTION f_insert_these_columns(VARIADIC _cols text[])
RETURNS void AS
$func$
BEGIN
EXECUTE (
SELECT 'INSERT INTO person1 SELECT '
|| string_agg(quote_ident(col), ', ')
|| ' FROM person2'
FROM unnest(_cols) col
);
END
$func$ LANGUAGE plpgsql;
select * from cols2;
array
------------
{name,age}
(1 row)
SELECT f_insert_these_columns(VARIADIC cols2);
ERROR: column "cols2" does not exist
这是怎么了?
推荐答案
答案
您似乎假设SQL中的SELECT INTO
会分配一个变量.但是事实并非如此.
Answer
You seem to assume that SELECT INTO
in SQL would assign a variable. But that is not so.
它会创建一个新的表,并且在Postgres中不鼓励使用它.请改用上级CREATE TABLE AS
.尤其重要,因为plpgsql中SELECT INTO
的含义是不同:
It creates a new table and its use is discouraged in Postgres. Use the superior CREATE TABLE AS
instead. Not least, because the meaning of SELECT INTO
inside plpgsql is different: