2

Assume that the DBA_TAB_COLUMNS looks like this: enter image description here

I'd like to write a SQL or PL/SQL script to generate following text:

select 'NULL' as A1, B1, QUERY, RECORD_KEY from SMHIST.probsummarym1
union all
select 'NULL' as A1, 'NULL' as B1, QUERY, RECORD_KEY from SMHIST_EIT200.probsummarym1
union all
select A1, 'NULL' as B1, QUERY, RECORD_KEY from SMHIST_EIT300.probsummarym1

the requirements are:

  1. If the table under any of the SMHIST% schemas do not have that column, then insert a default NULL alias for that columns.

  2. the column list is in alphabetical order.

so can anybody tell me how to write this script?

1 Answer 1

2

EDIT: Added better alias names and en explicit CROSS JOIN. Added XMLAGG version.

NB: LISTAGG exists from Oracle version 11.2 and onwards and returns VARCHAR2. If the output string is larger than 4000K or if on a prior version you can use XMLAGG which is a bit more cumbersome to work with (eg. http://psoug.org/definition/xmlagg.htm).

With LISTAGG (returning VARCHAR2):

SELECT LISTAGG (line,
                CHR (13) || CHR (10) || 'union all' || CHR (13) || CHR (10))
       WITHIN GROUP (ORDER BY sortorder)
          script
  FROM (SELECT line, ROWNUM sortorder
          FROM (  SELECT    'select '
                         || LISTAGG (
                                  CASE
                                     WHEN tc.column_name IS NULL
                                     THEN
                                        '''NULL'' as '
                                  END
                               || col_join.column_name,
                               ', ')
                            WITHIN GROUP (ORDER BY col_join.column_name)
                         || ' from '
                         || col_join.owner
                         || '.'
                         || col_join.table_name
                            line
                    FROM    dba_tab_columns tc
                         RIGHT OUTER JOIN
                            (SELECT DISTINCT
                                    owner, table_name, col_list.column_name
                               FROM    dba_tab_columns
                                    CROSS JOIN
                                       (SELECT DISTINCT column_name
                                          FROM dba_tab_columns
                                         WHERE owner LIKE 'SMHIST%') col_list
                              WHERE owner LIKE 'SMHIST%') col_join
                         ON     tc.owner = col_join.owner
                            AND tc.table_name = col_join.table_name
                            AND tc.column_name = col_join.column_name
                GROUP BY col_join.owner, col_join.table_name
                ORDER BY col_join.owner, col_join.table_name))

With XMLAGG (returning CLOB by adding .getclobval (), note: RTRIM works here because table names cannot include ',' and ' ' (space)):

SELECT REPLACE (SUBSTR (script, 1, LENGTH (script) - 12),
                '&' || 'apos;',
                '''')
  FROM (SELECT XMLAGG (
                  XMLELEMENT (
                     e,
                     line,
                        CHR (13)
                     || CHR (10)
                     || 'union all'
                     || CHR (13)
                     || CHR (10))).EXTRACT ('//text()').getclobval ()
                  script
          FROM (SELECT line, ROWNUM sortorder
                  FROM (  SELECT    'select '
                                 || RTRIM (
                                       REPLACE (
                                          XMLAGG (XMLELEMENT (
                                                     e,
                                                        CASE
                                                           WHEN tc.column_name
                                                                   IS NULL
                                                           THEN
                                                              '''NULL'' as '
                                                        END
                                                     || col_join.column_name,
                                                     ', ') ORDER BY
                                                              col_join.column_name).EXTRACT (
                                             '//text()').getclobval (),
                                          '&' || 'apos;',
                                          ''''),
                                       ', ')
                                 || ' from '
                                 || col_join.owner
                                 || '.'
                                 || col_join.table_name
                                    line
                            FROM    dba_tab_columns tc
                                 RIGHT OUTER JOIN
                                    (SELECT DISTINCT
                                            owner,
                                            table_name,
                                            col_list.column_name
                                       FROM    dba_tab_columns
                                            CROSS JOIN
                                               (SELECT DISTINCT column_name
                                                  FROM dba_tab_columns
                                                 WHERE owner LIKE 'SMHIST%') col_list
                                      WHERE owner LIKE 'SMHIST%') col_join
                                 ON     tc.owner = col_join.owner
                                    AND tc.table_name = col_join.table_name
                                    AND tc.column_name = col_join.column_name
                        GROUP BY col_join.owner, col_join.table_name
                        ORDER BY col_join.owner, col_join.table_name)))
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.