Viết kịch bản Oracle DDL theo cách tự động


14

Oracle SQL Developer có thể xuất DDL thông qua Tools -> Database Export...Điều này hoạt động rất tốt, nhưng cần có sự can thiệp thủ công.

Tôi biết DBMS_METADATA.get_ddl(), nhưng đã thấy rằng xuất khẩu không hoàn hảo. Tôi gặp phải các vấn đề trong đó DBMS_METADATADDL xuất khẩu không thể sử dụng được mà không khắc phục được các vấn đề như lỗi giữa các từ khóa và tệ hơn. Tuy nhiên, nếu bất cứ ai biết cách xuất DDL thông qua DMBS_METADATAđó có thể chạy mà không cần sửa lỗi thủ công, đó cũng là một giải pháp tuyệt vời.

Về cơ bản, tôi đang tìm kiếm một cách tự động / kịch bản để xuất DDL giống hệt với những gì được xuất qua cách thủ công.

Làm thế nào tôi có thể làm điều đó?


1
Bạn có đang chạy DBMS_METADATA qua SQLplus không? Bạn có chiều rộng dòng của bạn được đặt> 80?
David Mann

Tôi đang sử dụng SQLPlus. Có tiện ích nào tốt hơn không? Bạn có nghĩa là với 'thiết lập kích thước 200'? Điều đó không có gì khác biệt
MatthewToday

2
Có vẻ như những người khác cũng có vấn đề. Lỗi trong các phiên bản trước của Oracle và khó khăn trong việc khiến DBMS_METADATA chơi độc đáo trong các phiên bản sau. Asktom.oracle.com/pls/asktom/ khăn Giải pháp của tôi không tuyệt vời cho bạn. Tôi thường chạy DBMS_METADATA trong một công cụ đồ họa (như Toad) và sau đó cắt và dán vào tài liệu văn bản. Chắc chắn không thể tự động hóa, nhưng nó dường như xử lý các kết thúc dòng với CLOBs đẹp hơn.
David Mann

Hmmm có vẻ như bây giờ tôi có thể gắn bó với cách thủ công ... Cảm ơn vì sự giúp đỡ và liên kết mặc dù :)
MatthewToday

1
@David - Bạn cần đặt độ rộng cột đầu ra bằng cách sử dụng COL, như được hiển thị trong ví dụ này và nó sẽ hoạt động.
Nick Chammas

Câu trả lời:


5

Chà, nếu sqlplus đang vặn đầu ra dbms_metadata.get_ddl của bạn, tại sao không chọn đầu ra trong CLOB và ghi CLOB vào hệ thống tệp.

ví dụ

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

Điều này sẽ giúp bạn sửa DDL, với đầu ra bị rối. Điều duy nhất là tập lệnh sẽ được tạo trên máy chủ DB chứ không phải trên máy khách từ nơi bạn gọi sqlplus.

Tập lệnh được lưu trong thư mục được chỉ ra bởi mục nhập 'DATA_PUPM_DIR' trên Máy chủ DB. I E

select directory_path from all_directories where directory_name like 'DATA_PUMP_DIR';

Hơn nữa, bạn có thể thêm một số loại lặp trên tất cả các bảng / chỉ mục, v.v. của một lược đồ và nhận được DDL của một lược đồ hoàn chỉnh ngay lập tức. Tôi làm nó suốt.


2
Lưu ý, điều này ghi tập tin vào hệ thống tập tin của máy chủ. Bất cứ ai đang tìm kiếm DDL trên máy khách, điều này sẽ không đạt được điều đó.
Andrew Spencer

6

Lý do bạn gặp vấn đề dbms_metadata.get_ddllà nó xuất ra CLOBs có thể có kích thước lên tới 4GB. Theo mặc định, SQL * Plus và Oracle SQL Developer cắt ngắn văn bản dài để họ không bỏ rác ứng dụng khách với số lượng lớn văn bản.

Rất dễ dàng ghi đè hành vi này trong SQL * Plus bằng một vài SETlệnh và nhận DDL sạch.

Kịch bản bạn cần là:

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

Các biến đổi sau đây có thể giúp đỡ. Tôi chưa sử dụng phương thức DBMS_XSLPROCESSOR.CLOB2FILE, nhưng tôi đã sử dụng chúng để di chuyển cơ sở dữ liệu Oracle từ Solaris sang Linux. Tôi không thể sử dụng máy bơm dữ liệu vì phiên bản của Oracle mà họ đang sử dụng và thực tế là họ đã sử dụng các loại dữ liệu XML cho các loại dữ liệu cột.

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 );
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.