使用 Postgres10。
我遇到一个问题,我正在调用一个存储过程并期望我的 OUT 参数有一个特定值,但我没有得到它。我正在使用下面的调用代码调用 Items 存储过程。
问题 我希望我第一次调用 Item 存储过程来获取 rtn 值为 1 的插入,但我得到的是 4...这意味着 IF EXISTS 在表中找到同名的行,但我的表是空的.
我期望在 INSERT 语句之后重新评估 IF EXISTS 语句并进入 rtn 设置为 4 的 block 时会发生一些奇怪的事情。这与 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')).*;
最佳答案
问题是你调用函数的方式:
select (aips.Item(NULL, 'Test 1')).*; -- WRONG!
因为执行了三次,每个输出列一次。该函数应在 FROM 子句中调用:
select * from aips.Item(NULL, 'Test 1');
关于sql - 来自 Postgres 存储过程的意外 OUT 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54064438/