问题
I have a stored procedure that returns a record type. If I ALTER the table this stored procedure returns (let's say I add a column), I have to either disconnect my database session or re-run the CREATE OR REPLACE
. When I don't I will get the error wrong record type supplied in RETURN NEXT
.
Here's a script that fails when I run it in a single psql
session:
CREATE TABLE p1(a INT, b TEXT);
CREATE OR REPLACE FUNCTION authenticate() RETURNS SETOF p1 as '
DECLARE
player_row p1;
BEGIN
-- query is more complicated but always returns zero or one rows
SELECT p.* INTO player_row
FROM p1 p;
IF FOUND THEN
RETURN NEXT player_row;
-- more code in here..
END IF;
RETURN;
END;' LANGUAGE plpgsql ROWS 1;
ALTER TABLE p1 ADD COLUMN c VARCHAR(2);
INSERT INTO p1 VALUES(1,'a', 'c');
SELECT * FROM AUTHENTICATE();
Is there a Postgres command or setting with which I could automate the re-compilation of stored procedures? I tried @vao-tsun's suggestion of running DISCARD PLANS
after the migrations, but unfortunately it did not help.
回答1:
you were looking for this DO
statement:
CREATE TABLE p1(a INT, b TEXT);
CREATE OR REPLACE FUNCTION authenticate() RETURNS SETOF p1 as '
DECLARE
player_row p1;
BEGIN
-- query is more complicated but always returns zero or one rows
SELECT p.* INTO player_row
FROM p1 p;
IF FOUND THEN
RETURN NEXT player_row;
-- more code in here..
END IF;
RETURN;
END;' LANGUAGE plpgsql ROWS 1;
ALTER TABLE p1 ADD COLUMN c VARCHAR(2);
INSERT INTO p1 VALUES(1,'a', 'c');
do $$ begin execute pg_get_functiondef('authenticate'::regproc); end; $$;
SELECT * FROM AUTHENTICATE();
but as a_horse_with_no_name suggests, you can just \c
to reconnect with psql
来源:https://stackoverflow.com/questions/49653371/can-i-recompile-table-returning-functions-after-that-table-is-alter-ed-during