通过postgresql中的循环添加多个列

时间:2014-12-04 16:15:39

标签: postgresql alter-table

我正在尝试在具有多个列的架构中创建一个新表,通过索引命名。

CREATE TABLE rflux (pk SERIAL PRIMARY KEY NOT NULL);

现在我想添加col0 FLOAT,col1,col2,col3,....等新列,直到colN。

我知道我可以做类似

的事情
ALTER TABLE rflux add column col0 FLOAT add column col1 FLOAT ... ;

但我不想输出所有内容,因为我需要创建~4500列。我试图用循环来实现它,但我不能让它工作。有没有人有任何想法?我已经尝试创建一个函数来执行此操作..

create function addColumns()
returns void
as $$
begin
for i in 1..10 loop
alter table rflux add column tmp float;
alter table rflux rename tmp to col||i;
end loop;
return;
end;
$$
language plpgsql;
然后呢     select * from addColumns();

但是在将列重命名为col || i时,或者甚至在我尝试使用时,我都会遇到错误。我甚至不确定这是否是最好的方法。如何添加多个列,我可以使用计数器增加列的名称?

编辑..我知道我不能用4500列做到这一点,但是如果我想为10列做这个问题的解决方案是什么呢?

感谢。

2 个答案:

答案 0 :(得分:0)

您的设计可能更适合数组,hstore或json数据类型。添加4500列是一场等待发生的噩梦。

答案 1 :(得分:0)

如果可以提供帮助:

-- VERSION : POSTGRESQL 9.3

-- FICTIVE TABLE #1

CREATE TABLE table_1 ("YEAR" int, "CODE_SP" text, "TOTAL" int);

INSERT INTO table_1 VALUES
(2035, 'TRUC', 2),
(2035, 'MUCH', 4),
(2036, 'FLIC', 7),
(2036, 'LORD', 2),
(2036, 'TRUC', 8),
(2037, 'MUCH', 2),
(2037, 'FLIC', 2),
(2037, 'FLAC', 5),
(2037, 'MORD', 9),
(2038, 'LOOP', 3),
(2038, 'MUCH', 3);

SELECT * FROM table_1;

-- FICTIVE TABLE #2

CREATE TABLE table_2 ("YEAR" int);

INSERT INTO table_2("YEAR")
SELECT serial
FROM generate_series(2035,2038,1) AS serial;

SELECT * FROM table_2;

-- LOOP FOR ADDING COLUMNS ON TABLE #2 

DO
$do$
    DECLARE colnames TEXT;
BEGIN
FOR colnames IN 
    SELECT "CODE_SP"
    FROM table_1
    GROUP BY "CODE_SP"
    ORDER BY "CODE_SP"
LOOP
    EXECUTE 'ALTER TABLE table_2 ADD COLUMN ' || quote_ident(colnames) || ' INT DEFAULT NULL;'; /* careful: in quoted text, the spaces are important */
END LOOP;
END
$do$;

-- LOOP FOR COMPLETTING CELLS ON TABLE #2 

DO
$do$
    DECLARE id_value TEXT;
BEGIN
FOR id_value IN
    SELECT "CODE_SP"
    FROM table_1
    GROUP BY "CODE_SP"
    ORDER BY "CODE_SP"
LOOP
    EXECUTE 'UPDATE table_2 SET ' || quote_ident(id_value) || ' = table_1."TOTAL" FROM table_1 WHERE table_1."CODE_SP" = ' || quote_literal(id_value) || ' AND table_1."YEAR" = table_2."YEAR";'; /* careful: in quoted text, the spaces are important */
END LOOP;
END
$do$;