PostgreSQL 9.3:缺少表的FROM子句条目

时间:2015-03-11 04:55:20

标签: postgresql postgresql-9.3

我有一个有两列的表。

示例:

create table t1
( 
  cola varchar,
  colb varchar
);

现在我想从函数中插入行。

在函数中:我想使用两个varchar类型的参数将值插入上表中。我传递的字符串插入表中。

我将两个字符串作为参数传递给函数:

参数:

cola varchar = 'a,b,c,d';
colb varchar = 'e,f,g,h';

上述参数必须像这样插入表中:

cola       colb
----------------
a           e
b           f
c           g
d           h

我的尝试:

create or replace function fun_t1(cola varchar,colb varchar)
returns void as
$body$
Declare
    v_Count integer;
    v_i integer = 0;
    v_f1 text;
    v_cola varchar;
    v_colb varchar;
    v_query varchar;

Begin

    drop table if exists temp_table;

    create temp table temp_table
    (
        cola varchar,
        colb varchar
    );

    v_Count :=  length(cola) - length(replace(cola, ',', ''));

    raise info '%',v_Count;

    WHILE(v_i<=v_Count) LOOP

        INSERT INTO temp_table
        SELECT  LEFT(cola,CHARINDEX(',',cola||',',0)-1) 
        ,LEFT(colb,CHARINDEX(',',colb||',',0)-1);

        cola := overlay(cola placing '' from 1 for CHARINDEX(',',cola,0));

        colb := overlay(colb placing '' from 1 for CHARINDEX(',',colb,0));

        v_i := v_i + 1;

    END LOOP;

    for v_f1 IN select * from temp_table loop

        v_cola := v_f1.cola;  /* Error occurred here */
        v_colb := v_f1.colb;  

        v_query := 'INSERT INTO t1 values('''||v_cola||''','''||v_colb||''')';

        execute v_query;

    end loop;

end;

$body$

language plpgsql;   

注意:在我根据要求使用temp_table的函数中 我还在我没有在这里展示的功能中用于其他用途。

通话功能:

SELECT fun_t1('a,b,c','d,e,f');     

收到错误:

missing FROM-clause entry for table "v_f1"

3 个答案:

答案 0 :(得分:1)

使用split_part()尝试这种方式: -

create or replace function ins_t1(vala varchar,valb varchar,row_cnt int) returns void as 
$$
BEGIN 
FOR i IN 1..row_cnt LOOP -- row_cnt is the number rows you need to insert (ex. 4 or 5 or whatever it is)
insert into t1 (cola,colb) 
values (
        (select split_part(vala,',',i))
       ,(select split_part(valb,',',i))
       );
END LOOP;
END;
$$
language plpgsql

函数调用:select ins_t1('a,b,c,d','e,f,g,h',4)


正如 mike-sherrill-cat-recall 在他的回答中说regexp_split_to_table

create or replace function fn_t1(vala varchar,valb varchar) returns void
as
$$
insert into t1 (cola, colb)
select col1, col2 from (select 
    trim(regexp_split_to_table(vala, ','))  col1,   
    trim(regexp_split_to_table(valb, ','))  col2)t;
$$
language sql 

函数调用:select fn_t1('a,b,c,d','e,f,g,h')

答案 1 :(得分:1)

如果没有令人信服的理由为此使用函数,您可以使用正则表达式拆分文本。在这里,我将您的参数表达为一个公用表表达式,但这只是为了方便。

with data (col1, col2) as (
  select 'a, b, c, d'::text, 'e, f, g, h'::text
)
select 
    trim(regexp_split_to_table(col1, ',')) as col_a,   
    trim(regexp_split_to_table(col2, ',')) as col_b
from data;
col_a  col_b
--
a      e
b      f
c      g
d      h

如果使用函数的一个令人信服的理由,只需在SELECT语句周围包装一个函数定义。

create function strings_to_table(varchar, varchar) 
returns table (col_a varchar, col_b varchar)
as 
    'select trim(regexp_split_to_table($1, '','')),
            trim(regexp_split_to_table($2, '',''));'
language sql
stable
returns null on null input;

select * from strings_to_table('a,b,c,d', 'e,f, g, h');
col_a  col_b
--
a      e
b      f
c      g
d      h

我个人的偏好是通常来构建这样的函数来返回表而不是插入表中。要插入,我通常会编写一个这样的SQL语句。

insert into foo (col_a, col_b)
select col_a, col_b from strings_to_table('a,b,c,d', 'e,f,g,h');

答案 2 :(得分:1)

最简单的方法就是使用plpython。

create or replace function fill_t1(cola varchar, colb varchar) returns void as $$
for r in zip(cola.split(','), colb.split(',')):
  plpy.execute(plpy.prepare('insert into t1(cola, colb) values ($1, $2)', ['varchar', 'varchar']), [r[0], r[1]])
$$ language plpythonu;

结果:

# create table t1 (cola varchar, colb varchar);
CREATE TABLE
# select fill_t1('1,2,3', '4,5,6');
 fill_t1 
---------

(1 row)

# select * from t1;
 cola | colb 
------+------
 1    | 4
 2    | 5
 3    | 6
(3 rows)

您可以在此处阅读有关Python zip 功能的信息:https://docs.python.org/2/library/functions.html#zip