2015-11-04 2 views
2

Supposons que le DBA_TAB_COLUMNS ressemble à ceci: enter image description herescripts SQL pour générer des scripts SQL

Je voudrais écrire un script SQL ou PL/SQL pour générer du texte suivant:

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 

les exigences sont:

  1. Si la table sous l'un des schémas SMHIST% de ne pas cette colonne, puis insérez un alias NULL par défaut pour que les colonnes.

  2. la liste des colonnes est dans l'ordre alphabétique.

donc quelqu'un peut-il me dire comment écrire ce script?

Répondre

2

EDIT: Ajout de meilleurs noms d'alias et explicites CROSS JOIN. Ajouté la version XMLAGG.

NB:LISTAGG existe depuis la version Oracle 11.2 et les années suivantes et retourne VARCHAR2. Si la chaîne de sortie est supérieure à 4000 Ko ou si vous utilisez une version antérieure, vous pouvez utiliser XMLAGG, ce qui est un peu plus compliqué à utiliser (eg. http://psoug.org/definition/xmlagg.htm).

Avec LISTAGG (retour 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)) 

Avec XMLAGG (retour CLOB en ajoutant .getclobval(), note: RTRIM travaille ici parce que les noms de table ne peut pas inclure ',' et ' ' (espace)):

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