2015-11-04 122 views
2

假設DBA_TAB_COLUMNS看起來是這樣的: enter image description hereSQL腳本生成SQL腳本

我想寫一個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. 列表按字母順序排列。

所以有人可以告訴我如何寫這個腳本?

回答

2

編輯:添加更好的別名和en顯式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)))