Script Oracle DDL de manière automatisée


14

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

Je sais DBMS_METADATA.get_ddl(), mais j'ai trouvé que l'exportation n'est pas parfaite. J'ai rencontré des problèmes où la DBMS_METADATADDL exportée n'était pas utilisable sans résoudre au préalable 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_METADATAqui peut s'exécuter sans correctifs manuels, ce serait également une excellente solution.

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

Comment puis je faire ça?


1
Exécutez-vous DBMS_METADATA via SQLplus? Avez-vous une largeur de ligne définie> 80?
David Mann

J'utilise SQLPlus. Existe-t-il un meilleur utilitaire? Voulez-vous dire avec «set linesize 200»? Cela ne fait aucune différence
MatthewToday

2
Il semble que d'autres personnes aient également eu des problèmes. Bogue dans les versions antérieures d'Oracle et difficulté à faire en sorte que DBMS_METADATA fonctionne correctement dans les versions ultérieures. asktom.oracle.com/pls/asktom/… Ma solution n'est pas si bonne pour vous. J'exécute généralement DBMS_METADATA dans un outil graphique (comme Toad), puis je le coupe et le colle dans un document texte. Certainement pas automatisable, mais il semble mieux gérer les fins de ligne avec CLOBs.
David Mann

Hmmm semble que je pourrais continuer avec la méthode manuelle pour le moment alors ... Merci pour l'aide et le lien cependant :)
MatthewToday

1
@David - Vous devez définir la largeur de la colonne de sortie à l'aide de COL, comme indiqué dans cet exemple , et cela fonctionnera.
Nick Chammas

Réponses:


5

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.


2
Notez que cela écrit le fichier dans le système de fichiers du serveur. Quiconque cherche à obtenir le DDL sur la machine cliente, cela ne le fera pas.
Andrew Spencer

6

La raison pour laquelle vous rencontrez des problèmes dbms_metadata.get_ddlest qu'il génère des CLOBs pouvant 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 SETcommandes 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;

0

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 de 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 );
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.