Неожиданное значение OUT из хранимой процедуры Postgres - PullRequest
0 голосов
/ 06 января 2019

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

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

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

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

SCHEMA / TABLE

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')).*;

1 Ответ

0 голосов
/ 06 января 2019

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

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

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

select * from aips.Item(NULL, 'Test 1');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...