【问题标题】:Returning ID from the upsert procedure in language sql postgresql从语言 sql postgresql 中的 upsert 过程返回 ID
【发布时间】:2021-12-18 06:27:22
【问题描述】:

我有一个 SQL upsert 查询,我想返回位置表的插入记录 ID 或更新记录 ID。我需要在查询中进行哪些更改? (注意:name 列是唯一的)

CREATE OR REPLACE PROCEDURE locations_upsert
(
    _name        TEXT,
    _address     TEXT,
    _postal_code TEXT,
    _country     TEXT
)
LANGUAGE SQL
AS $$
    INSERT INTO locations
    (
        name,
        address,
        postal_code,
        country
    )
    VALUES
    (
        _name,
        _address,
        _postal_code,
        _country
    )
    ON CONFLICT (name)
    DO UPDATE  
    SET 
        address = _address,
        postal_code = _postal_code,
        country = _country
$$;

【问题讨论】:

  • 使用函数returns bigint
  • 在函数中使用RETURNING id。有关更多信息,请参阅 Postgres 文档:postgresql.org/docs/current/sql-insert.html
  • 谢谢你们。问:是不是可以通过程序来实现?

标签: sql postgresql stored-procedures sql-function


【解决方案1】:

将过程定义更改为返回整数值的函数并使用

INSERT INTO ... RETURNING id

UPDATE ... RETURNING id

表达式。

【讨论】:

    【解决方案2】:

    过程不能返回值。将过程更改为函数并将其声明为intbigint 作为返回类型:

    CREATE OR REPLACE FUNCTION locations_upsert(
      _name        TEXT,
      _address     TEXT,
      _postal_code TEXT,
      _country     TEXT
    ) RETURNS bigint
    AS $$ 
      INSERT INTO locations  
        (name, address, postal_code, country) VALUES
        (_name,_address,_postal_code,_country)
       ON CONFLICT (name)
       DO UPDATE SET 
         address = _address,
         postal_code = _postal_code,
         country = _country
       RETURNING id;    
    $$ LANGUAGE sql;
    

    或者,您可以使用表名作为返回数据类型 - RETURNS locations -,这将使您能够返回整个记录 - RETURNING *

    CREATE OR REPLACE FUNCTION locations_upsert(
      _name        TEXT,
      _address     TEXT,
      _postal_code TEXT,
      _country     TEXT
    ) RETURNS locations
    AS $$ 
      INSERT INTO locations  
        (name, address, postal_code, country) VALUES
        (_name,_address,_postal_code,_country)
        ON CONFLICT (name)
        DO UPDATE SET 
          address = _address,
          postal_code = _postal_code,
          country = _country
      RETURNING *;  
    $$ LANGUAGE sql;
    

    演示:db<>fiddle

    延伸阅读:PostgreSQL CREATE PROCEDURE

    【讨论】:

    • 这行得通,谢谢:)。用过程而不是功能不可能吗?
    • @kiran 不,程序不能返回任何值。
    猜你喜欢
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多