web-dev-qa-db-fra.com

Script Oracle DDL de manière automatisée

Oracle SQL Developer est capable d'exporter DDL via Tools -> Database Export... Cela fonctionne très bien, mais nécessite une intervention manuelle.

Je connais DBMS_METADATA.get_ddl(), mais j'ai trouvé que l'export n'était pas parfait. J'ai rencontré des problèmes où le DDL DBMS_METADATA Exporté n'était pas utilisable sans d'abord résoudre des problèmes tels que des ruptures au milieu d'un mot clé, et pire encore. Cependant, si quelqu'un connaît un moyen d'exporter DDL via DMBS_METADATA Qui peut s'exécuter sans correctifs manuels, ce serait également une excellente solution.

Fondamentalement, je recherche un moyen automatique/scriptable d'exporter DDL identique vers ce qui est exporté par la voie manuelle.

Comment puis je faire ça?

14
MatthewToday

Eh bien, si sqlplus est en train de visser votre sortie dbms_metadata.get_ddl, pourquoi ne pas sélectionner la sortie dans un CLOB et écrire le CLOB dans le système de fichiers.

par exemple.

DECLARE
    data CLOB;
    objType varchar2(30) := 'TABLE';
    objSchema varchar2(30) := 'SCOTT';
    objName varchar2(30) := 'EMP';
    fname varchar2(256) := objType || '_' || objSchema || '_' || objName || '.sql';
BEGIN
    SELECT dbms_metadata.get_ddl(objType,objName,objSchema) into data from dual;
    DBMS_XSLPROCESSOR.CLOB2FILE(data,'DATA_PUMP_DIR',fname);
END;
/

Cela devrait vous permettre de corriger DDL, sans que la sortie ne soit gâchée. La seule chose est que le script sera créé sur le serveur DB et non sur le client à partir duquel vous appelez sqlplus.

Le script est enregistré dans le répertoire indiqué par l'entrée "DATA_PUPM_DIR" sur le serveur DB. c'est à dire.

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

De plus, vous pouvez ajouter une sorte d'itération sur toutes les tables/index, etc. d'un schéma, et obtenir le DDL d'un schéma complet en un rien de temps. Je le fais tout le temps.

5
user5294

La raison pour laquelle vous rencontrez des problèmes avec dbms_metadata.get_ddl signifie qu'il génère CLOBs qui peut atteindre 4 Go. Par défaut, SQL * Plus et Oracle SQL Developer tronquent le texte long afin de ne pas jeter le client avec de gros morceaux de texte.

Il est très facile de remplacer ce comportement dans SQL * Plus avec quelques commandes SET et d'obtenir un DDL propre.

Le script dont vous avez besoin est:

-- Run this script in SQL*Plus.

-- don't print headers or other crap
set heading off;
set echo off;
set pagesize 0;      

-- don't truncate the line output
-- trim the extra space from linesize when spooling
set long 99999;      
set linesize 32767;  
set trimspool on;    

-- don't truncate this specific column's output
col object_ddl format A32000;

spool sys_ddl.sql;

SELECT dbms_metadata.get_ddl(object_type, object_name, owner) || ';' AS object_ddl
FROM DBA_OBJECTS
WHERE 
      OWNER = 'SYS'
  AND OBJECT_TYPE IN (
      'TABLE'
    , 'INDEX'
    , 'SEQUENCE'
    , 'VIEW'
  )
ORDER BY
    OWNER
  , OBJECT_TYPE
  , OBJECT_NAME
;

spool off;
6
Nick Chammas

Les transformations suivantes peuvent aider. Je n'ai pas utilisé la méthode DBMS_XSLPROCESSOR.CLOB2FILE, mais je les ai utilisées pour migrer une base de données Oracle de Solaris vers Linux. Je ne pouvais pas utiliser la pompe à données en raison de la version d'Oracle qu'ils utilisaient et du fait qu'ils utilisaient des types de données XML pour les types de données de colonne.

DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'PRETTY',             TRUE );
DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR',      TRUE );
DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'REF_CONSTRAINTS',    FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'OID',                FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', FALSE);
DBMS_METADATA.SET_TRANSFORM_PARAM( DBMS_METADATA.SESSION_TRANSFORM, 'TABLESPACE',         TRUE );
0
Gandolf989