Неожиданное значение OUT из хранимой процедуры Postgres

Использование Postgres10.

У меня проблема, когда я вызываю хранимую процедуру и ожидаю определенного значения для моего параметра OUT, но не получаю его. Я вызываю хранимую процедуру Items с приведенным ниже кодом вызова.

ПРОБЛЕМА Я ожидаю, что в первый раз, когда я вызову хранимую процедуру Item, я получу вставку со значением rtn, равным 1, но я получаю 4 ... Это означает, что IF EXISTS находит строку в таблице с тем же именем, но моя таблица пуста .

Я ожидаю, что происходит что-то странное, когда оператор IF EXISTS переоценивается после оператора INSERT и входит в блок, где rtn получает значение 4. Это как-то связано с plpgsql? Он действует так, как будто порядок хранимой процедуры не всегда идет сверху вниз, когда я добавляю команды Raise для проверки значений в определенных точках.

СХЕМА / ТАБЛИЦА

CREATE TABLE aips.Item (
 ItemPk SERIAL PRIMARY KEY,
 Name VARCHAR(100) NOT NULL,
 CONSTRAINT UNI_Item_Name UNIQUE(Name)
);

ХРАНИМАЯ ПРОЦЕДУРА

CREATE OR REPLACE FUNCTION aips.Item(
    INOUT p_ItemPk INT,
    INOUT p_Name VARCHAR(100),
    OUT rtn INT
) AS
$$
DECLARE rowcnt INT;
BEGIN
  -- Insert or Find Path
  IF p_ItemPk IS NULL THEN

    -- Check for Find
    IF EXISTS (SELECT * FROM aips.Item where Name = p_Name) THEN
        SELECT ItemPk, Name
        INTO p_ItemPk, p_Name
        FROM aips.Item
        WHERE Name = p_Name;

        rtn := 4;
        RETURN;
    END IF;

    -- Perform insert
    INSERT INTO aips.Item (Name)
    VALUES (p_Name)
    RETURNING ItemPk INTO p_ItemPk;
    GET DIAGNOSTICS rowcnt = ROW_COUNT;

    IF rowcnt = 1 THEN
      rtn := 1;
    ELSE
      rtn := 0;
      RAISE EXCEPTION 'Expecting to insert a single row and rows returned --> %', rowcnt;
    END IF;

  ELSE -- Update or No Operation Path

    -- Check for no changes
    IF EXISTS (SELECT ItemPk 
               FROM aips.Item 
               WHERE ItemPk = p_ItemPk
               AND Name = p_Name) THEN
        rtn := 5;
        RETURN;
    END IF;

    -- Perform Update
    UPDATE aips.Item 
    SET Name = p_Name
    WHERE ItemPk = p_ItemPk;
    GET DIAGNOSTICS rowcnt = ROW_COUNT;

    IF rowcnt = 1 THEN
      rtn := 2;
    ELSE
      rtn := 0;
      RAISE EXCEPTION 'Expecting to update a single row and rows returned --> %', rowcnt;
    END IF;
  END IF;

  RETURN;
END;
$$ LANGUAGE plpgsql;

ВЫЗОВ

select (aips.Item(NULL, 'Test 1')).*;
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
0
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, как вы вызываете функцию:

select (aips.Item(NULL, 'Test 1')).*; -- WRONG!

потому что он выполняется трижды, по одному разу для каждого выходного столбца. Функцию следует вызывать в предложении FROM:

select * from aips.Item(NULL, 'Test 1');
x.* похож на макрос - он распакован в x.c1, x.c2, ..., и когда x является функцией, функция вычисляется несколько раз.
Pavel Stehule 07.01.2019 05:48

Другие вопросы по теме