Using Postgres10.
I'm having an issue where I am calling a stored procedure and expecting a specific value for my OUT param and I am not getting it. I am calling the Items stored procedure with the call code below.
PROBLEM I expect the first time I call the Item stored procedure to get an insert with a rtn value of 1 but I get a 4... This means the IF EXISTS is finding a row in the table with the same name but my table is empty.
I am expecting there is something weird going on where the IF EXISTS statement is being re-evaluated after the INSERT statement and entering the block where rtn gets set to 4. Is this something to do with plpgsql? It's acting as if the order of the stored procedure is not going top to bottom always when I put in Raise commands to test values at certain points.
SCHEMA/TABLE
CREATE TABLE aips.Item (
ItemPk SERIAL PRIMARY KEY,
Name VARCHAR(100) NOT NULL,
CONSTRAINT UNI_Item_Name UNIQUE(Name)
);
STORED PROCEDURE
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;
CALL
select (aips.Item(NULL, 'Test 1')).*;
The problem is the way you call the function:
select (aips.Item(NULL, 'Test 1')).*; -- WRONG!
because it is executed three times, once for each output column. The function should be called in the FROM clause:
select * from aips.Item(NULL, 'Test 1');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.