postgresql import csv列动态更改

时间:2017-10-26 10:30:09

标签: postgresql function csv plpgsql dynamic-columns

数据库: PostgreSQL

我需要PL / pgSQL中的函数自动将数据从CSV文件加载到表中。 重要信息:必须声明CSV文件的列和目标表的列。

some_function (data_file_name,table_name,columns_from,columns_to)

示例:

CSV文件包含以下列: A B C D

目标表包含以下列:一个两个

some_function(' file.csv',' table1',数组[' A',' B'],数组[&# 39;一个','两个'])

数组定义可以更改,我不知道如何以另一种方式传递列。

create or replace function load_csv_procedure
(
csv_path text,
target_table text,
columns_from text[],
columns_to text[]
)

returns void as $$

declare

target_table text;
col_count integer;
iter integer; 
col text;
col_first text; 

begin
set schema 'public';

create table temp_table ();
col_count := 6; 

-- add just enough number of columns
for iter in 1..col_count
loop
    execute format('alter table temp_table add column col_%s text;', 
iter);
end loop;

-- copy the data from csv file
execute format('copy temp_table from %L with delimiter '','' quote 
''"'' csv ', csv_path);

iter := 1;
col_first := (select col_1 from temp_table limit 1);

for col in execute format('select 
unnest(string_to_array(trim(temp_table::text, ''()''), '','')) from 
temp_table where col_1 = %L', col_first)
loop
    execute format('alter table temp_table rename column col_%s to 
%s', iter, col);
    iter := iter + 1;
end loop;

execute format('delete from temp_table where %s = %L', col_first, 
col_first);

--EXECUTE format('INSERT INTO %I (' || columns_to::text || ' ) VALUES 
( select (' || columns_from::text || ' ) from temp_table);'::text, 
target_table) using columns_to, columns_from;
--
EXECUTE format('INSERT INTO %I (''name'', code ) VALUES (select 
DepartmentName, DepartmentCode from temp_table);'::text, 
target_table); -- using columns_to, columns_from;

drop table temp_table;

end;

$$ language plpgsql;

1 个答案:

答案 0 :(得分:0)

我做到了:)

create or replace function csv_to_table (in target_table text, in 
csv_path text, in col_count integer, in columns_from text[], in 
columns_to text[])

returns void as $$

declare 

iter integer; --dummy integer to iterate with
col text; --dummy variable to iterate with
col_first text; --first column label, e.g., top left corner on a csv 
file or spreadsheet

columns_from_str text;
columns_to_str text;

begin
set schema 'public';

drop table if exists temp_table;

create table temp_table ();

-- add just enough number of columns
for iter in 1..col_count
loop
    execute 'alter table temp_table add column col_' || iter || ' 
varchar;';
end loop;

-- copy the data from csv file
execute 'copy temp_table from ''' || csv_path || ''' with delimiter 
'',''';

iter := 1;
col_first := (select col_1 from temp_table limit 1);

-- update the column names based on the first row which has the 
column names
for col in execute 'select 
unnest(string_to_array(trim(temp_table::text, ''()''), '','')) from 
temp_table where col_1 = ''' || col_first || ''''
loop
    execute 'alter table temp_table rename column col_' || iter || ' 
to ' || col;
    iter := iter + 1;
end loop;

-- delete the columns row
execute 'delete from temp_table where ' || col_first || ' = ''' || 
col_first || '''';

-- make string from all columns 
columns_from_str := array_to_string(columns_from, ', ');
columns_to_str := array_to_string(columns_to, ', ');

execute format('insert into %s(%s) select %s from temp_table;', 
target_table, columns_to_str, columns_from_str);


end;

$$ language plpgsql;