PL / pgSQL - 插入多行,在结果集中返回id

时间:2013-07-04 15:43:06

标签: postgresql plpgsql

我正在使用PostgreSQL 8.4。我的目标是在PL / pgSQL的帮助下插入多行,并将插入记录的id - s返回到记录集中。

首先,我尝试在一行中使用以下代码执行permission_create(..)函数:

CREATE FUNCTION permission_create(
  IN method   permission.permission_method % TYPE,
  IN resource permission.permission_resource % TYPE
)
  RETURNS TABLE(id permission.permission_id % TYPE)
AS
  $BODY$
  BEGIN
    RETURN QUERY
      WITH inserted_permission AS (
        INSERT INTO permission (permission_id, permission_method, permission_resource) VALUES (DEFAULT, method, resource)
        RETURNING permission_id
      )
      SELECT
        inserted_permission.permission_id AS id
      FROM inserted_permission;
  END;
  $BODY$
LANGUAGE plpgsql VOLATILE;

但是,我收到以下错误消息:

[2013-07-04 17:38:01] [00000] type reference permission.permission_method%TYPE converted to character varying
[2013-07-04 17:38:01] [00000] type reference permission.permission_resource%TYPE converted to character varying
[2013-07-04 17:38:01] [00000] type reference permission.permission_id%TYPE converted to integer
[2013-07-04 17:38:01] [00000] type reference permission.permission_id%TYPE converted to integer
[2013-07-04 17:38:01] [42601] ERROR: syntax error at or near "INSERT"
  Where: SQL statement in PL/PgSQL function "permission_create" near line 9

我该如何解决这个问题?有没有办法在多行中做到这一点?

解决方案:

CREATE FUNCTION permission_create(
  IN method   permission.permission_method % TYPE,
  IN resource permission.permission_resource % TYPE
)
  RETURNS TABLE (id INT)
AS
  $BODY$
  BEGIN
    RETURN QUERY
    INSERT INTO permission (permission_id, permission_method, permission_resource)
      VALUES (DEFAULT, method, resource)
    RETURNING permission_id;
  END;
  $BODY$
LANGUAGE plpgsql VOLATILE;

1 个答案:

答案 0 :(得分:3)

PostgreSQL 9.1支持可更新的CTE。

您不需要使用CTE(在您的情况下)

postgres=# CREATE OR REPLACE FUNCTION fx()
RETURNS SETOF int AS $$
BEGIN
  RETURN QUERY INSERT INTO taba(a) VALUES(1),(2)
    RETURNING *;
  RETURN;
END;
$$ LANGUAGE plpgsql;
CREATE FUNCTION
postgres=# select * from fx();
 fx 
----
  1
  2
(2 rows)