Вернуть INSERT-вывод из функции - PullRequest
0 голосов
/ 05 июня 2019

Когда выполняется INSERT , его выводом является командный тег , например, INSERT 0 1.

Я бы хотел захватить тот же тег команды из функции и вернуть его.

Я думал, что предложение RETURNING поможет мне, тем не менее, оно работает подобно запросу SELECT по вставленным строкам, возвращая набор, похожий на таблицу. Я не хочу этого. Я хочу вернуть простой командный тег (т.е. текст "INSERT 0 1"), который вы получаете при выполнении INSERT.

Вот пример псевдокода того, чего я хочу достичь (конечно, RETURN QUERY не работает в этом случае, так как INSERT входит в функцию не-SETOF

CREATE FUNCTION insert_user_test (
    p_username text)
    RETURNS text
    LANGUAGE plpgsql
    AS $$
BEGIN
    RETURN QUERY INSERT INTO users(username) values(p_username));
END $$;

Как мне добиться того, что мне нужно?

Ответы [ 3 ]

2 голосов
/ 06 июня 2019

Командный тег «INSERT 0 1» не доступен напрямую для среды plpgsql. Вы можете получить ту же информацию в другом формате с помощью команды GET DIAGNOSTICS.

DO $$
  DECLARE _oid oid; _rc bigint;
BEGIN
  INSERT INTO foo VALUES(10);
  GET DIAGNOSTICS _oid = RESULT_OID; -- it is not supported on 12+
  GET DIAGNOSTICS _rc = ROW_COUNT;
  RAISE NOTICE 'INSERT % %', _oid, _rc;
END;
$$;

Если вам нужно больше, вам следует использовать язык, отличный от PLpgSQL - специальным вариантом является язык C, где доступна вся информация.

2 голосов
/ 05 июня 2019

Используйте CTE с INSERT:

WITH i as (
      INSERT INTO users (username)
          VALUES (p_username)
      RETURNING *
     )
SELECT i.*
FROM i;
1 голос
/ 06 июня 2019

Вы не можете перехватить сообщение INSERT 0 1 буквально, поскольку оно не возвращается оператором INSERT, а генерируется инструментом командной строки psql на основе status оператора INSERT.

Итак, если вы хотите увидеть это сообщение, вам нужно сгенерировать его самостоятельно в функции (PL / pgSQL для этого не нужен):

CREATE FUNCTION insert_user_test (p_username text)
    RETURNS text
    LANGUAGE SQL
  AS $$
    with inserted as (
      INSERT INTO users(username) values(p_username))
      returning *
    )
    select concat('INSERT 0 ', count(*))
    from inserted;
  $$;

Если вы не хотели видеть сообщение INSERT 0 1, вы можете просто вместо этого вернуть имя пользователя:

CREATE FUNCTION insert_user_test (p_username text)
    RETURNS text
    LANGUAGE SQL
  AS $$
      INSERT INTO users(username) values(p_username))
      returning username;
  $$;

Или полная строка, включая введенные по умолчанию значения:

CREATE FUNCTION insert_user_test (p_username text)
    RETURNS setof users
    LANGUAGE SQL
  AS $$
      INSERT INTO users(username) values(p_username))
      returning *;
  $$;
...