0

I have a procedure that queries schema and table. I want this to not overwrite the variable instead append, because the result I want to create view.

DECLARE    
    rec record;
    sqlPlaceholder text;
BEGIN
 
 FOR rec IN SELECT table_schema, table_name
            FROM information_schema.tables                
 LOOP
     sqlPlaceholder := sqlPlaceholder || 'SELECT ogc_fid, wkb_geometry FROM ' || 
               rec.table_schema || '.' || rec.table_name || ' UNION ';
 END LOOP;
  
strSQL := 'SELECT  * FROM (' || sqlPlaceholder || ')';

RAISE INFO 'sample output %' , strSQL;

The variable sqlPlaceholder only holds the last assignment from the loop. as it's overwritten by each loop.

I need to figure out how add them all in loop.

call create_view()

Value of string inside loop SELECT *  FROM public._data_202101 UNION 
Value of string inside loop SELECT *  FROM public._data_202102 UNION 
Value of string inside loop SELECT *  FROM public._data_202103 UNION 
Value of string inside loop SELECT *  FROM public._data_202104 UNION 
Value of string inside loop SELECT *  FROM public._data_202105 UNION 
Value of string inside loop SELECT *  FROM public._data_202106 UNION 
Value of string inside loop SELECT *  FROM public._data_202107 UNION 
Value of string inside loop SELECT *  FROM public._data_202108 UNION 
Value of string inside loop SELECT *  FROM public._data_202109 UNION 
Value of string inside loop SELECT *  FROM public._data_202110 UNION 
Value of string inside loop SELECT *  FROM public._data_202111 UNION 
Value of string inside loop SELECT *  FROM public._data_202112 UNION 
Value of string outside ==> create table public._data_all as (SELECT *  FROM public._data_202112 union)
a_horse_with_no_name
  • 497,550
  • 91
  • 775
  • 843
hi4ppl
  • 465
  • 1
  • 6
  • 21

1 Answers1

3

The core problem in your PL/pgSQL code is that sqlPlaceholder starts out as NULL. Read the manual here.

NULL || anything is always NULL. Initialize the variable with an empty string ('') instead to fix that:

DECLARE    
    sqlPlaceholder text := '';
...

There's more, but don't bother. Here is a superior set-based solution:

SELECT string_agg(format('SELECT ogc_fid, wkb_geometry FROM %I.%I', table_schema, table_name), E'\nUNION ')
FROM   information_schema.tables;

Redshift is pretty limited, I don't think it has format(). So:

SELECT string_agg('SELECT ogc_fid, wkb_geometry FROM ' || quote_ident(table_schema) || '.' || quote_ident(table_name), '\nUNION ')
FROM   information_schema.tables;

Produces something like:

SELECT ogc_fid, wkb_geometry FROM public.tbl1
UNION SELECT ogc_fid, wkb_geometry FROM public.tbl2
UNION SELECT ogc_fid, wkb_geometry FROM public.tbl3
...

You want to quote identifiers properly to defend against SQL injection in any case! See:

Also, you probably want some filter and UNION ALL instead of UNION.

Related:

Erwin Brandstetter
  • 539,169
  • 125
  • 977
  • 1,137