【问题标题】:How to return a newly created id from a Postgres function?如何从 Postgres 函数返回新创建的 id?
【发布时间】:2016-02-17 16:10:34
【问题描述】:

我正在为 Postgres 中的表创建分区并具有以下功能:

CREATE OR REPLACE FUNCTION create_partition_and_insert() RETURNS trigger AS
  $BODY$
    DECLARE
      partition_date TEXT;
      partition TEXT;
    BEGIN
      partition_date := to_char(NEW.date,'YYYY_MM_DD');
      partition := TG_RELNAME || '_' || partition_date;
      IF NOT EXISTS(SELECT relname FROM pg_class WHERE relname=partition) THEN
        RAISE NOTICE 'A partition has been created %',partition;
        EXECUTE 'CREATE TABLE ' || partition || ' (check (date = ''' || NEW.date || ''')) INHERITS (' || TG_RELNAME || ');';
      END IF;
      EXECUTE 'INSERT INTO ' || partition || ' SELECT(' || TG_RELNAME || ' ' || quote_literal(NEW) || ').*;';
      RETURN NULL;
    END;
  $BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

我正在将此函数与触发器一起使用:

CREATE TRIGGER testing_partition_insert_trigger
BEFORE INSERT ON testing_partition
FOR EACH ROW EXECUTE PROCEDURE create_partition_and_insert();

测试用表:

CREATE TABLE testing_partition(patent_id BIGINT, date DATE) WITH ( OIDS=FALSE);

有没有办法从函数中返回专利 ID?现在它返回null。我试图通过以下方式扩展功能:

RETURNING patent_id INTO newid;

Postgres 似乎不支持以这种方式返回值:

ERROR:  syntax error at or near "INTO"
LINE 1: ...rtition '(111,2018-01-11)').* RETURNING patent_id INTO newid...
                                                             ^
QUERY:  INSERT INTO testing_partition_2018_01_11 SELECT(testing_partition '(111,2018-01-11)').* RETURNING patent_id INTO newid;
CONTEXT:  PL/pgSQL function create_partition_and_insert() line 12 at EXECUTE statement

【问题讨论】:

  • 好友看看这个stackoverflow.com/questions/33212417/…。详细解释。
  • INTO 必须是 EXECUTE 语句的一部分,而不是 INSERT 的一部分。将其移到查询字符串之外。
  • 谢谢,尼克,你介意给我举个例子吗?我想我有它的一部分 INSERT

标签: postgresql plpgsql


【解决方案1】:

解决方案是在 INSERT 的 and 处添加不带 INTO 的 RETURNING patent_id,并在发出实际 INSERT 时执行相同的操作。

CREATE OR REPLACE FUNCTION create_partition_and_insert() RETURNS trigger AS
  $BODY$
    DECLARE
      partition_date TEXT;
      partition TEXT;
    BEGIN
      partition_date := to_char(NEW.date,'YYYY_MM_DD');
      partition := TG_RELNAME || '_' || partition_date;
      IF NOT EXISTS(SELECT relname FROM pg_class WHERE relname=partition) THEN
        RAISE NOTICE 'A partition has been created %',partition;
        EXECUTE 'CREATE TABLE ' || partition || ' (check (date = ''' || NEW.date || ''')) INHERITS (' || TG_RELNAME || ');';
      END IF;
      EXECUTE 'INSERT INTO ' || partition || ' SELECT(' || TG_RELNAME || ' ' || quote_literal(NEW) || ').* RETURNING patent_id;';
      RETURN NULL;
    END;
  $BODY$
LANGUAGE plpgsql VOLATILE
COST 100;

使用扩展功能的工作方式如下:

# insert into testing_partition values (1, '2011-01-11') returning patent_id ;
 patent_id
-----------
         1
(1 row)

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-08-03
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多