it-swarm.asia

نص برنامج Oracle DDL بطريقة آلية

بإمكان Oracle SQL Developer تصدير DDL من خلال Tools -> Database Export... يعمل هذا بشكل جيد جدًا ، ولكنه يتطلب تدخلًا يدويًا.

أعرف DBMS_METADATA.get_ddl() ، لكنني وجدت أن التصدير ليس مثاليًا. لقد واجهت مشكلات حيث كان DBMS_METADATA الذي تم تصديره غير قابل للاستخدام دون إصلاح المشكلات أولاً مثل الفواصل في منتصف الكلمة الرئيسية ، والأسوأ من ذلك. ومع ذلك ، إذا كان أي شخص يعرف طريقة لتصدير DDL من خلال DMBS_METADATA يمكن تشغيله بدون إصلاحات يدوية ، فسيكون هذا حلاً رائعًا أيضًا.

في الأساس ، أنا أبحث عن طريقة تلقائية/نصية لتصدير DDL مطابق لما يتم تصديره من خلال الطريقة اليدوية.

كيف أقوم بذلك؟

14
MatthewToday

حسنًا ، إذا كانت sqlplus تقوم بشد مخرجات dbms_metadata.get_ddl ، فلماذا لا تحدد المخرجات في CLOB وتكتب CLOB إلى نظام الملفات.

على سبيل المثال.

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;
/

من المفترض أن يؤدي ذلك إلى حصولك على DDL الصحيح ، بدون إخراج الإخراج. الشيء الوحيد هو أنه سيتم إنشاء البرنامج النصي على خادم DB وليس على العميل حيث يمكنك استدعاء sqlplus.

يتم حفظ البرنامج النصي في الدليل المشار إليه بواسطة إدخال "DATA_PUPM_DIR" على خادم DB. بمعنى آخر.

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

ما هو أكثر من ذلك ، يمكنك إضافة نوع من التكرار على جميع الجداول/الفهارس وما إلى ذلك من المخطط ، والحصول على DDL مخطط كامل في أي وقت من الأوقات. أفعل ذلك طوال الوقت.

5
user5294

السبب في أن لديك مشاكل مع dbms_metadata.get_ddl هو أنه ينتج CLOBs والتي يمكن أن يصل حجمها إلى 4 جيجابايت. بشكل افتراضي ، يقوم SQL * Plus و Oracle SQL Developer باقتطاع النص الطويل حتى لا يقوموا بتخريب العميل بمجموعات نصية كبيرة.

من السهل جدًا تجاوز هذا السلوك في SQL * Plus مع بعض أوامر SET والحصول على DDL نظيف.

النص الذي تحتاجه هو:

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

قد تساعد التحولات التالية. لم أستخدم طريقة DBMS_XSLPROCESSOR.CLOB2FILE ، لكني استخدمتها لترحيل قاعدة بيانات أوراكل من Solaris إلى Linux. لم أتمكن من استخدام مضخة البيانات بسبب إصدار Oracle الذي كانوا يستخدمونه ولأنهم استخدموا أنواع بيانات XML لأنواع بيانات العمود.

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