Reputation: 1684
I have created a function that creates a temporary table and inserts into the table. The problem is that I need this to work in a read-only instance as well, but in a read-only instance I can't create a table and/or insert into it. Is there any other way of doing this? Maybe by creating a table variable in a way similar to other SQL languages?
I did some research and there doesn't seem to be a table variable, but maybe an array of records? Any ideas?
UPDATE:
To answer people's questions, I am trying to create a function that returns a list of dates from now until x intervals ago in intervals of y.
So for instance, select * from getDates('3 days', 1 day')
returns:
startdate | enddate
------------+------------
2016-07-20 | 2016-07-21
2016-07-19 | 2016-07-20
2016-07-18 | 2016-07-19
And select * from getDates('3 months', '1 month');
returns:
startdate | enddate
------------+------------
2016-07-01 | 2016-08-01
2016-06-01 | 2016-07-01
2016-05-01 | 2016-06-01
I currently do this by using a while
loop and going back per interval until I hit the time given by the first parameter. I then insert those values into a temp table, and when finished I select everything from the table. I can include the code if necessary.
Upvotes: 4
Views: 11770
Reputation: 97688
You can create a permanent named Composite Type representing the structure of your temporary table, and then use an array variable to manipulate a set of rows inside a function:
-- Define columns outside function
CREATE TYPE t_foo AS
(
id int,
bar text
);
CREATE OR REPLACE FUNCTION test()
RETURNS SETOF t_foo AS
$BODY$
DECLARE
-- Create an empty array of records of the appropriate type
v_foo t_foo[] = ARRAY[]::t_foo[]; -- correction
BEGIN
-- Add some rows to the array
v_foo := v_foo || ( 42, 'test' )::t_foo;
v_foo := v_foo || ( -1, 'nothing' )::t_foo;
-- Convert the array to a resultset as though it was a table
RETURN QUERY SELECT * FROM unnest(v_foo);
END;
$BODY$
LANGUAGE plpgsql;
SELECT * FROM test();
The crucial part here is the variable of type t_foo[]
- that is, an array of records of the pre-defined type t_foo
.
This is not as easy to work with as a temporary table or table variable, because you need to use array functions to get data in and out, but may be useful.
It's worth considering though whether you really need the complex local state, or whether your problem can be re-framed to use a different approach, e.g. sub-queries, CTEs, or a set-returning function with RETURN NEXT
.
Upvotes: 3
Reputation: 5305
Maybe the best way to approach it is to get your administrator to GRANT TEMPORARY ON DATABASE database_name TO
the user account performing your actions. You still will only have read-only access to the database.
Upvotes: 0
Reputation: 125204
Declare the function as retuning table
create function f()
returns table (
a int,
b text
) as $$
select x, y from t;
$$ language sql;
Use it as:
select *
from f()
Upvotes: -1