0

I want to create a function that uses a filter-parameter, that is later applied to a where-clause.

The definition of my function so far looks like:

CREATE OR REPLACE FUNCTION function_to_be_fixed(filter_date date)                   
RETURNS void as  $$
Begin
  CREATE OR REPLACE VIEW view_to_create.randomname AS
  SELECT * from other_table where date_col <= filter_date
End;
$$ LANGUAGE plpgsql;

When calling the function via

 select function_to_be_fixed(filter_date   => '2020-01-01');

I receive the error: column 'filter_date' does not exist.

What do I need to adjust in order to make it run?

7
  • 2
    As I have commented on your other question as well: Why do you want to create thousands of views? Providing a set returning function that returns the desired sub-set of the table looks like a much easier way to do this. Commented Jul 29, 2019 at 13:58
  • @a_horse_with_no_name: I need to pull data from the database using python. The request contains a filterdate, that is variable. Is there another nice way to do this without a function? Commented Jul 30, 2019 at 5:28
  • What's wrong with a function? Surely python can call functions in a SQL statement? select * from get_data('2020-01-01'); Commented Jul 30, 2019 at 5:37
  • 1
    I have added an example to my answer Commented Jul 30, 2019 at 5:50
  • 1
    yes, you can join to the result of such a function. Commented Jul 30, 2019 at 6:00

1 Answer 1

2

You can't use a parameter like that inside the view definition.

Once the view is created the parameter would be "lost".

You need to use dynamic SQL for that, so that the value of the parameter is replace into the SQL string that defines the view:

CREATE OR REPLACE FUNCTION function_to_be_fixed(filter_date date)                   
RETURNS void as  $$
Begin
  execute format('
    CREATE OR REPLACE VIEW view_to_create.randomname AS
    SELECT * from other_table where date_col <= %L', filter_date);
End;
$$ LANGUAGE plpgsql;

A single function that you pass the filter_date to would a better solution:

create or replace function get_some_table_data(filter_date date)
  returns setof some_table
as
$$
  select *
  from some_table
  where date_col <= filter_date;
$$
language sql;
Sign up to request clarification or add additional context in comments.

1 Comment

Many thanks for the comprehensive reply! I just tested your suggestion for my purposes - having two tables - and recalled that one needs to slightly adapt the exaple. Correct me if I'm wrong, but one then has to state the definition of each column: e.g. RETURNS table (col1 as integer, col2 integer) as $$

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.