How can I dynamically create views in Postgres 10 using variables?

All we need is an easy explanation of the problem, so here it is.

I know how to do this in MySQL and MSSQL but I’m struggling to do the same in Postgres 10.12. I have about 200 views to create and the only difference in each one of them is the schema location and the where clause.

For example:

create or replace view SCHEMA1.myview as
    select * from SHAREDSCHEMA.sometable where MYCOL = 'ABC';

So what I need to do is create that view around 200 times with each iteration being:

SCHEMA1.myview 
SCHEMA2.myview
SCHEMA3.myview
etc...

MYCOL = 'ABC'
MYCOL = 'EFG'
MYCOL = 'HIJ'
etc...

Hope that makes sense. Again, the only difference between each iteration is the schema name changes and the where clause changes.

I could probably write some Python script or something to generate the code but I’d rather do it in Postgres if possible.

I know this isn’t valid code, but essentially this is what I am trying to do:

do $$
declare
    myschema varchar(10) := 'SCHEMA1';
    mywhere varchar(3) := 'ABC';
begin
    create or replace view @[email protected] as
        select * from SHAREDSCHEMA.sometable where MYCOL = @[email protected];
end $$;

Then each time I run that, I simply change @myschema and @mywhere.

Any help would be appreciated.

Thanks!

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

You need dynamic SQL for this:

do $$
declare
    myschema varchar(10) := 'SCHEMA1';
    mywhere varchar(3) := 'ABC';
begin
    execute format('
        create or replace view %I.myview as
        select * from SHAREDSCHEMA.sometable where MYCOL = %L', myschema, mywhere);
end $$;

The format() function is highly recommended when creating dynamic SQL to properly deal with identifiers and constant values.

You can also put this into a function (or procedure in newer versions):

create function create_view(p_schema text, p_value text)
   returns void
as
$$
begin
  execute format('
      create or replace view %I.myview as
      select * from SHAREDSCHEMA.sometable where MYCOL = %L', p_schema, p_value);
end 
$$
language plpgsql;

Then you can run:

select create_view('myschema', 'xyz');

If you want, you can use that to create all views in one go:

with data (schema_name, value) as 
  values  
     ('schema1', 'abc'),
     ('schema2', 'def'),
     ('schema3', 'ghi')
)
select create_view(schema_name, value)
from data;

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply