I use a temp table in a function with the 'on commit drop' option. My problem is, in certain cases, a more global function can call the first one twice, so the "create temp table" is called twice before the commit - so I have the normal error "relation [my_temp_table] already exists".
I use the temp table at the end of the function to return its rows in the "return query", so I can't manually drop the table before I leave the function.
CREATE OR REPLACE FUNCTION my_function(_value text)
RETURNS setof my_table AS $$
DECLARE
resultCount integer := 0;
BEGIN
create temp table my_temp_table on commit drop as
select *
from my_table
where value = _value ;
select count(*) into resultCount from my_temp_table;
if (resultCount = 0) then
raise exception 'value not found';
end if;
return query
select * from my_temp_table;
END;$$ LANGUAGE plpgsql VOLATILE COST 100;
ALTER FUNCTION my_function(text) OWNER TO postgres
If you wonder why I use a temp table and not my_table in a direct way it's because I need a really fast response and my_table is very big (several dozens of millions rows) so this way I can request it only once instead of three times (search, count and return).
I found a workaround not using temp table and creating a type, but the structure of my_table will change many times, and actually I have dozens of "my table" and the concerned "my function", so this was a way to not write again all my functions each time the structure of my tables will change.
The function has to return the same structure than the table it requests.
How can I can drop the table when leaving the function? Or is there a better workaround?
Using the DROP TABLE command on a temporary table, as with any table, will delete the table and remove all data. In an SQL server, when you create a temporary table, you need to use the # in front of the name of the table when dropping it, as this indicates the temporary table.
Local temporary tables are dropped automatically at the end of the current session or procedure.
It's ok to explicitly include DROP TABLE or let SQL Server handle it for you each time the connection drops. If your stored procedures are already dropping temp tables, that's great. If they're not being dropped, I wouldn't bother spending the time and effort just to drop them.
If the session where the global temporary table was created is closed, the global temporary table will be dropped automatically. Names start with a single “#” hashtag symbol. Names start with a double “##” hashtag symbol. Tables can be accessed only from the session where the table was created.
... return its rows in the "return query", so I can't manually drop the table before I leave the function.
Actually you can. You can use several RETURN QUERY
in your case.
After manual:
When a PL/pgSQL function is declared to return SETOF [...] the individual items to return are specified by a sequence of RETURN NEXT or RETURN QUERY commands, and then a final RETURN command with no argument is used to indicate that the function has finished executing
So you could do:
RETURN QUERY
SELECT * FROM my_temp_table;
DROP TABLE my_temp_table;
RETURN;
You could drop the table just in case:
...
BEGIN
drop table if exists my_temp_table;
create temp table my_temp_table on commit drop as
....
but... in fact you do not need a temporary table. Try this code:
...
return query
select *
from my_table
where value = _value ;
if not found then
raise exception 'value not found';
end if;
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With