Использование 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')).*;