plpgsql函数不按预期插入数据

时间:2017-12-21 14:46:17

标签: postgresql sql-insert plpgsql

我已成功编译以下函数。当我执行select schema.funtion_name();时,函数会被执行,但表schema.table_insert中没有插入行:

CREATE OR REPLACE FUNCTION schema.function_name()
RETURNS void AS
$BODY$
DECLARE cur_1 CURSOR FOR
    Select col1 from schema.table1
    union
    select col1 from schema.table2
    union
    select col1 from schema.table3
    union
    select col1 from schema.table4; 

BEGIN
    FOR rec_i in cur_1 LOOP
        insert into schema.table_insert (col1,col2,col3) 
        select col1,col2,col3 
        from schema.view 
        where col1=rec_i.col1

        commit;
    END LOOP;     
END;
$BODY$
LANGUAGE plpgsql STABLE

光标cur_1中的选择返回超过900 000条记录。当我单独对单个记录使用insert语句时,记录将被插入表中。

1 个答案:

答案 0 :(得分:1)

  

我已成功编译以下函数。

不,你没有。

对于初学者来说,plpgsql函数不是"编译"。在创建时,只进行表面语法检查,然后按原样存储函数体。没有编译。后期绑定。嵌套的SQL语句被视为预准备语句。

除此之外,您显示的功能根本无法创建。这是句法上的无稽之谈。 INSERT后缺少分号。 COMMIT没有意义,不允许在plpgsql中使用。你不需要光标。也不循环。使用简单的SQL语句:

INSERT INTO schema.table_insert (col1, col2, col3) 
SELECT v.col1, v.col2, v.col3 
FROM   schema.view v
JOIN  (
   SELECT col1 FROM schema.table1
   UNION
   SELECT col1 FROM schema.table2
   UNION
   SELECT col1 FROM schema.table3
   UNION
   SELECT col1 FROM schema.table4; 
   ) sub USING (col1);

等效,可能更快:

INSERT INTO schema.table_insert (col1, col2, col3) 
SELECT v.col1, v.col2, v.col3 
FROM   schema.view v
WHERE  EXISTS (SELECT 1 schema.table1 WHERE col1 = v.col1)
OR     EXISTS (SELECT 1 schema.table2 WHERE col1 = v.col1)
OR     EXISTS (SELECT 1 schema.table3 WHERE col1 = v.col1)
OR     EXISTS (SELECT 1 schema.table4 WHERE col1 = v.col1);

可以包含在一个函数中,但是plpgsql是矫枉过正的。对于包含STABLE的函数,INSERT会出错。我建议使用普通的SQL函数,VOLATILE是默认的,也是正确的。

CREATE OR REPLACE FUNCTION schema.function_name()
  RETURNS void AS
$func$
INSERT ...
$func$  LANGUAGE sql;