如何使用 postgresql 中的存储过程将数据插入表中

Posted

技术标签:

【中文标题】如何使用 postgresql 中的存储过程将数据插入表中【英文标题】:How to insert data into table using stored procedures in postgresql 【发布时间】:2013-07-09 04:00:48 【问题描述】:
CREATE TABLE app_for_leave
(
  sno integer NOT NULL,
  eid integer,
  ename varchar(20),
  sd date,
  ed date,
  sid integer,
  status boolean DEFAULT false,
  CONSTRAINT pk_snoa PRIMARY KEY (sno)
);

基本插入是 ::

INSERT INTO app_for_leave(sno, eid, sd, ed, sid, status)
 VALUES(1,101,'2013-04-04','2013-04-04',2,'f' );

...

INSERT INTO app_for_leave(sno, eid, sd, ed, sid, status) VALUES (?, ?, ?, ?, ?, ?);

我的需求:: 如何使用存储过程向表中插入数据?

【问题讨论】:

我需要插入数据,通过创建函数或过程将数据插入表 app_for_leave Postgres 没有存储过程,但它确实支持函数.. 所以除了DML语言查询INSERT语句之外没有其他方法可以插入数据..或者有没有其他方法可以解决这个@mike christensen 当然,使用函数.. 我不确定你在这里问什么。您可以编写一个函数来执行我认为的 INSERT。 【参考方案1】:

PostgreSQL didn't support stored procedures 直到 PG11。在此之前,您可以使用函数获得相同的结果。例如:

CREATE FUNCTION MyInsert(_sno integer, _eid integer, _sd date, _ed date, _sid integer, _status boolean)
  RETURNS void AS
  $BODY$
      BEGIN
        INSERT INTO app_for_leave(sno, eid, sd, ed, sid, status)
        VALUES(_sno, _eid, _sd, _ed, _sid, _status);
      END;
  $BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;

你可以这样称呼它:

select * from MyInsert(1,101,'2013-04-04','2013-04-04',2,'f' );

与真正的存储过程相比,Pg 存储函数的主要限制是:

    无法返回多个结果集 不支持自主事务(函数内的 BEGIN、COMMIT 和 ROLLBACK) 不支持 SQL 标准 CALL 语法,但 ODBC 和 JDBC 驱动程序将为您转换调用。

Example

从 PG11 开始,CREATE PROCEDURE 语法为 introduced,它提供对事务的支持。

CREATE PROCEDURE MyInsert(_sno integer, _eid integer, _sd date, _ed date, _sid integer, _status boolean)
LANGUAGE SQL
AS $BODY$
    INSERT INTO app_for_leave(sno, eid, sd, ed, sid, status)
    VALUES(_sno, _eid, _sd, _ed, _sid, _status);   
$BODY$;

可以这样调用:

CALL MyInsert(1,101,'2013-04-04','2013-04-04',2,'f' );

【讨论】:

@user2561626 - 你需要先CREATEFUNCTION。使用我上面的例子,我只是在我自己的服务器上使用 Postgres 9.2 验证了它。 plpgsql 不支持自治事务,但其他语言支持,例如 plperl。您可能可以使用 dblink 和 plproxy 完成相同的操作。 @user2561626 - 我的荣幸! @user2561626 - Postgres 支持各种语言,例如 PL/pgSQL、Perl、C,甚至还有 javascript 扩展。 VOLATILE 表示函数必须每次都运行,结果不能缓存(只有VOLATILE函数可能改变数据库)。这是默认设置,所以我的代码实际上是多余的。 COST 为规划器提供了估计的执行成本。 More Details @lad2025 - 哇,甜!我想念和PG一起工作的人。我现在都是 MS SQL Server,叹息..【参考方案2】:

从 PostgreSQL 11 开始,您可以 create stored procedures 并使用 CALL 调用它们:

CREATE PROCEDURE MyInsert(_sno integer, _eid integer, _sd date,
                          _ed date, _sid integer, _status boolean)
LANGUAGE SQL
AS $$
    INSERT INTO app_for_leave(sno, eid, sd, ed, sid, status)
    VALUES(_sno, _eid, _sd, _ed, _sid, _status);   
$$;

CALL MyInsert(1,101,'2013-04-04','2013-04-04',2,'f' );

另外它允许handle transaction

SQL 存储过程

PostgreSQL 11 引入了 SQL 存储过程,允许用户使用 内嵌事务(即 BEGIN、COMMIT/ROLLBACK) 过程。 可以使用 CREATE PROCEDURE 创建过程 命令并使用 CALL 命令执行。

【讨论】:

Nice @lukasz ...如何返回结果集,即存储过程中的表?【参考方案3】:

PostgreSQL 不支持存储过程,但您可以使用函数获得相同的结果。

无论您要插入表中的什么数据,都会作为参数提供给您正在创建的函数。

CREATE OR REPLACE 表示如果数据库中已经存在同名的函数(您正在使用),那么它将被替换,否则如果没有同名的函数不存在然后将创建一个新函数。

您必须在函数主体内编写插入查询。

CREATE OR REPLACE FUNCTION Insert_into_table(_sno INTEGER, _eid INTEGER, _ename VARCHAR(20), _sd DATE, _ed DATE, _sid INTEGER)
      RETURNS void AS
      $BODY$
          BEGIN
            INSERT INTO app_for_leave(sno, eid, sd, ed, sid)
            VALUES(_sno, _eid, _sd, _ed, _sid);
          END;
      $BODY$
      LANGUAGE 'plpgsql' VOLATILE
      COST 100;

正如您在表格中已经提到的列的默认值 状态现在不需要向该列插入数据

这里是SQLFiddle链接供您理解

【讨论】:

是时候更新这个答案了。 PG11 支持带有事务控制的存储过程,现在已经发布了几个月。【参考方案4】:
CREATE OR REPLACE FUNCTION  new_bolshek(parent_id bigint, _key text, _value text, enabled boolean)
  RETURNS SETOF bolshekter AS
  $BODY$
  DECLARE
    new_id integer;
    returnrec bolshekter;
  BEGIN
        INSERT INTO bolshekter(parent_id, content_key, content_value, enabled)
        VALUES(parent_id, _key, _value, enabled) RETURNING id INTO new_id;
        FOR returnrec IN SELECT * FROM bolshekter where id=new_id LOOP
            RETURN NEXT returnrec;
        END LOOP;
  END;
  $BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;

【讨论】:

以上是关于如何使用 postgresql 中的存储过程将数据插入表中的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 存储过程:如何枚举查询

Sql优化 PostgreSQL存储过程

如何使用 JDBC 调用 PostgreSQL 存储过程

存储过程/存储函数:PostgreSQL 中的 SELECT

Postgresql:从本地到远程数据库的存储函数中的 dblink

错误:Postgresql 中的日期/时间字段值超出范围