使用 RETURNING 子句直接从 INSERT 返回值

cha*_*ni2 2 postgresql parameter plpgsql functions

我有一个以以下结尾的函数:

    INSERT INTO configuration_dates (
      cols...
    ) VALUES (
      values...
    ) RETURNING id INTO ret_id;
    RETURN ret_id;
Run Code Online (Sandbox Code Playgroud)

我想删除该INTO ret_id部分,而是执行以下操作:

RETURN (INSERT INTO configuration_dates (
  weekly_date_configuration_id,
  "from",
  "to",
  price,
  activity_configuration_id
) VALUES (
  wdc_id,
  from_ts,
  from_ts + wdc.duration,
  wdc.price,
  wdc.activity_configuration_id
) RETURNING id);
Run Code Online (Sandbox Code Playgroud)

但我还没有找到如何实现这一点。

编辑:添加整个功能

CREATE FUNCTION make_date_from_configuration(wdc_id UUID, from_date DATE)
  RETURNS INTEGER AS $$
DECLARE
  from_dow INT := EXTRACT(isodow FROM from_date); -- day of the week (1 - 7)
  wdc weekly_date_configurations;
  from_ts TIMESTAMP;
  ret_id INTEGER;
BEGIN
  SELECT * INTO wdc
  FROM weekly_date_configurations wdc
  WHERE id = wdc_id;

  IF FOUND
    AND wdc.valid_through @> from_date             -- starts in the date range
    AND get_bit(wdc.weekdays, from_dow - 1) = 1    -- valid day of the week
  THEN
    from_ts := from_date || ' ' || wdc.start_time;

    INSERT INTO configuration_dates (
      weekly_date_configuration_id,
      "from",
      "to",
      price,
      activity_configuration_id
    ) VALUES (
      wdc_id,
      from_ts,
      from_ts + wdc.duration,
      wdc.price,
      wdc.activity_configuration_id
    ) RETURNING id INTO ret_id;
    RETURN ret_id;
  ELSE
    RETURN NULL;
  END IF;
END;
$$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 7

您可以简化整个函数并使用OUT参数,因此该值会在函数结束时自动返回:

CREATE OR REPLACE FUNCTION make_date_from_configuration(
          wdc_id uuid
        , from_date date
        , OUT ret_id int) AS
$func$
BEGIN
   INSERT INTO configuration_dates (
          weekly_date_configuration_id, "from", "to", price, activity_configuration_id)
   SELECT wdc_id
       , (from_date || ' ' || wdc.start_time)::timestamptz
       , (from_date || ' ' || wdc.start_time)::timestamptz + wdc.duration
       , wdc.price, wdc.activity_configuration_id
   FROM  weekly_date_configurations wdc
   WHERE wdc.id = wdc_id
   AND   wdc.valid_through @> from_date                        -- starts in the date range
   AND   get_bit(wdc.weekdays
               , EXTRACT(isodow FROM from_date)::int - 1) = 1  -- valid day of the week
   RETURNING id
   INTO  ret_id;  -- returned at the end automatically
END
$func$  LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

所有的变量、赋值和条件表达式都只是不必要的噪音。可以是单个 SQL 命令:更短、更快。

但是,您仍然需要该INTO条款。(我不明白你为什么要避免这种情况。)

或者您可以改用普通的 SQL 函数,直接返回值:

CREATE OR REPLACE FUNCTION make_date_from_configuration(wdc_id uuid, from_date date)
  RETURNS int AS
$func$
   INSERT INTO configuration_dates (
               weekly_date_configuration_id, "from", "to", price, activity_configuration_id )
   SELECT wdc_id
       , (from_date || ' ' || wdc.start_time)::timestamptz
       , (from_date || ' ' || wdc.start_time)::timestamptz + wdc.duration
       , wdc.price, wdc.activity_configuration_id
   FROM  weekly_date_configurations wdc
   WHERE wdc.id = wdc_id
   AND   wdc.valid_through @> from_date                      -- starts in the date range
   AND   get_bit(wdc.weekdays
               , EXTRACT(isodow FROM from_date)::int- 1) = 1 -- valid day of the week
   RETURNING id  -- return directly
$func$  LANGUAGE sql;
Run Code Online (Sandbox Code Playgroud)


Cra*_*ger 5

RETURN QUERY

RETURN QUERY ...

或者,如果您要返回单行,而不是在 aRETURNS TABLERETURNS SETOF ...函数中,我认为您可以将结果存储到一个记录值变量中并返回它。未经测试:

DECLARE
    my_result record;
BEGIN
    INSERT INTO ...
    RETURNING ...
    INTO my_result;

    RETURN my_result;
END;
Run Code Online (Sandbox Code Playgroud)

  • @chamini2 好吧,如果你展示了你的函数定义,它会有所帮助...... (3认同)