0

I am writing a postgresql function and my construct is as follows:

   CREATE OR REPLACE FUNCTION function_name (argument_list) RETURNS INTEGER [] 
   AS $$
   DECLARE
      --along with other declarations
      _tablename text;
   BEGIN
      -- dynamically construct the intermediate _tablename which gets 
      -- populated
      -- Now I want to use this _tablename in other queries like :
      -- use it in the select from _tablename loop
      -- construct array by selecting a column from this table
      -- and return that array

   END

How should I do this? I want to reuse the declared variable name in my further queries in the function.

My complete postgres function is as follows:

 DROP FUNCTION get_value_histogram(BIGINT,BIGINT,BIGINT,INTEGER);
 CREATE OR REPLACE FUNCTION get_value_histogram(customer_id BIGINT, 
 start_time BIGINT, end_time BIGINT, bucket_size INTEGER)
 RETURNS INTEGER[] AS 
 $$
 DECLARE 
    _tablename text;
    _curr_timestamp BIGINT;
    _var1 text;
    _min_value INTEGER;
    _max_value INTEGER;
    _return_array  INTEGER[];
  BEGIN
    -- create an intermediate table with the aggregation of the 
    -- required values. These values then will be passed to the 
    -- Histogram function.
    _var1 := EXTRACT (EPOCH FROM now());
    _var1 := replace(_var1, '.','_');
    _tablename := 'thing_data_' || _var1;
    EXECUTE 'CREATE TABLE ' || _tablename || ' (t_stamp BIGINT,  sum_of_values INTEGER)';

    --insert all the values in this intermediate table
    EXECUTE ' INSERT INTO ' || _tablename || ' ( select t_stamp , sum(data)   from thing_data td, collector_tb ct where td.thingname = 
                ct.collector_name and td.t_stamp BETWEEN  ' ||  quote_literal(start_time) || ' AND ' || quote_literal(end_time) || ' and 
                ct.type like ' || quote_literal('%outlet%') ||' AND  customer_id = ' || customer_id || ' GROUP BY t_stamp)' ; 

    EXECUTE 'select width_bucket(sum_of_values,500, 1000 , 100), count(*) as cnt from ' || _tablename || ' GROUP BY 1 ORDER BY 1' ;
    _return_array :=  array (select cnt from (select width_bucket(sum_of_values,500, 1000 , 100), count(*) as cnt from  _tablename  GROUP BY 1 ORDER BY 1));

    EXECUTE 'DROP TABLE ' || _tablename;

    RETURN _return_array;

END $$ LANGUAGE plpgsql;

When I run this, I get an error saying relation "_tablename" does not exist

2 Answers 2

1

just replace :

 _return_array :=  array (select cnt from (select width_bucket(sum_of_values,500, 1000 , 100), count(*) as cnt from  _tablename  GROUP BY 1 ORDER BY 1) a);

by :

 EXECUTE 'select array (select cnt from (select width_bucket(sum_of_values,500, 1000 , 100), count(*) as cnt from  '|| _tablename ||' GROUP BY 1 ORDER BY 1) a)' into _return_array;
Sign up to request clarification or add additional context in comments.

Comments

0

I assume the error is in the last part:

_return_array :=  array (select cnt from (select width_bucket(sum_of_values,500, 1000 , 100), count(*) as cnt
  from  _tablename  GROUP BY 1 ORDER BY 1));

Here you're using _tablename as an actual literal table name and not as a variable.

1 Comment

Yes, I know that the query is wrong and understand that _tablename is not recognized in my query. I am looking for a solution. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.