从语言 sql postgresql 的 upsert 过程返回 ID

Returning ID from the upsert procedure in language sql postgresql

我有一个 SQL 更新插入查询,我想 return 插入记录 ID 或更新位置 table 的记录 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 整数值并使用

的函数
INSERT INTO ... RETURNING id

UPDATE ... RETURNING id

表达式。

过程不能 return 值。将过程更改为函数并将其声明为 intbigint as return type:

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;

或者,您可以使用 table 名称作为 return 数据类型 - RETURNS locations -,这将使您能够 return 整个记录 - 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