簡體   English   中英

來自 Postgres 存儲過程的意外 OUT 值

[英]Unexpected OUT value from Postgres Stored Procedure

使用 Postgres10。

我遇到了一個問題,我正在調用一個存儲過程並期望我的 OUT 參數有一個特定的值,但我沒有得到它。 我正在使用下面的調用代碼調用 Items 存儲過程。

問題我希望我第一次調用 Item 存儲過程來獲取 rtn 值為 1 的插入,但我得到的是 4...這意味着 IF EXISTS 正在表中找到具有相同名稱的行,但我的表是空的。

我期待在 INSERT 語句之后重新評估 IF EXISTS 語句並進入 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')).*;

問題是你調用函數的方式:

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

因為它被執行了 3 次,每個輸出列一次。 該函數應在 FROM 子句中調用:

select * from aips.Item(NULL, 'Test 1');

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM