用于生成SQL脚本的SQL脚本

时间:2015-11-04 10:18:20

标签: sql oracle plsql

假设DBA_TAB_COLUMNS如下所示: enter image description here

我想写一个SQL或PL / SQL脚本来生成以下文本:

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

要求是:

  1. 如果任何SMHIST%模式下的表没有该列,则为该列插入默认的NULL别名。

  2. 列列表按字母顺序排列。

  3. 所以有人能告诉我如何编写这个脚本吗?

1 个答案:

答案 0 :(得分:2)

编辑:添加了更好的别名和明确的CROSS JOIN。添加了XMLAGG版本。

NB: LISTAGG存在于Oracle版本 11.2 之后,并返回VARCHAR2。如果输出字符串大于4000K,或者如果使用的是先前版本,则可以使用XMLAGG,这对于使用eg. http://psoug.org/definition/xmlagg.htm)来说有点麻烦。

使用LISTAGG(返回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))

使用XMLAGG(通过添加CLOB返回.getclobval (),请注意:RTRIM在此处有效,因为表名不能包含','' '(空间)):

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)))