2013-06-03 23 views
7

Tôi hiện đang bắt đầu làm việc trên một dự án mà tôi sẽ phải viết mã (pl/sql) để xuất các tệp XML lớn, dựa trên một số bảng trong cơ sở dữ liệu.Tạo các tệp xml lớn từ oracle: Các phương pháp hay nhất

Tệp xuất có thể trở nên khá lớn và có thể chứa tối đa 700.000 khách hàng (với địa chỉ, đơn đặt hàng, số điện thoại, v.v.) của họ.

Tôi đã tự hỏi nếu có ai đó có một số lời khuyên về cách tiếp cận tốt nhất cho việc này. Tôi có thể rõ ràng chỉ cần viết ra các lựa chọn với mất XMLELEMENTS trong đó, nhưng điều đó có nghĩa là toàn bộ tập tin sẽ được tạo ra trong bộ nhớ.

Ngoài ra còn có một lược đồ XML (XSD) có sẵn mà các tệp phải tuân thủ. Tôi cũng tự hỏi liệu có cách nào để "ánh xạ" bảng vào lược đồ XML hay không.

Bất kỳ mẹo nào được đánh giá cao.

+0

phù hợp hơn cho dba.stackexchange.com –

+5

@BurhanKhalid Không đồng ý - đây là nhiệm vụ phát triển chứ không phải quản trị cơ sở dữ liệu. –

+0

Thực hành tốt nhất của nó về các lựa chọn - Tôi không thấy cách nó không liên quan đến dba.se * –

Trả lời

5

XML có một số thiếu sót ... trong lĩnh vực này. Các tệp XML lớn, như bạn lưu ý, có thể hog RAM và UNDO như không có ngày mai.

Tôi không thành thật tin rằng một cái gì đó gọi là "thực hành tốt nhất" tồn tại, tất cả phụ thuộc vào cơ sở dữ liệu, máy chủ và truy vấn của riêng bạn. Tuy nhiên, đây là những gì một đồng nghiệp (tôi không thể yêu cầu tín dụng) chỉ được thực hiện để viết một lượng lớn (4,5GB) XML vào đĩa từ một số lượng lớn (20?) Của các bảng lớn (10-400m hàng) với cực kỳ phức tạp truy vấn phụ.

  • Trên thực tế viết ra tất cả những XMLElements

  • Nếu câu lệnh SELECT của bạn là ở tất cả các phức tạp tạo ra một bảng đầu tiên.

  • Chọn từ bảng, lấy yếu tố hợp lý, hy vọng dựa trên ID của bạn. Ví dụ nếu bạn có cấu trúc sau nó sẽ làm cho tinh thần để chia nó trên <record>

    <someXML> 
        <record ID="1"> 
         <blah> 
          <moreBlah/> 
         </blah> 
        </record> 
        <record ID="2"> 
         <blah> 
          <moreBlah/> 
         </blah> 
        </record> 
    </someXML> 
    
  • Chọn mỗi bản ghi là một CLOB từ cơ sở dữ liệu. Sau đó bạn kết thúc với một loạt các CLOB sẽ tạo nên XML đầu ra của bạn.

  • Viết thẻ mở đầu tiên sau đó cá nhân, hoặc trong khối, viết mỗi CLOB vào đĩa

  • Đảm bảo bạn ghi vào đĩa cục bộ. Nếu nó không thể tránh được ghi vào một mạng chia sẻ, nơi có một cáp chất béo lớn chỉ vào nó. Bạn luôn có thể di chuyển tệp của mình sau đó và điều này sẽ hiệu quả hơn viết trên mạng (hoặc thành phố/quốc gia) theo khối.

  • Song song! Điều này không phải luôn luôn có thể nhưng nếu bạn có thể làm điều đó thì làm như vậy.

  • Hãy cẩn thận khi song song. Bạn không muốn viết XML không đúng định dạng.

Tôi đang thực sự ủng hộ phương pháp tiếp cận của tbone, lưu thay vào đó. Bất cứ điều gì bạn làm tránh đặt toàn bộ điều trong bộ nhớ.

2

Thử sử dụng DBMS_XMLGEN trước. Có cách tiếp cận khác là tốt, thấy Oracle XML DB doc này

DECLARE 
    v_ctx DBMS_XMLGEN.ctxhandle; 
    v_file UTL_FILE.file_type; 
    v_xml CLOB; 
    v_more BOOLEAN := TRUE; 
BEGIN 
    -- Create XML context. 
    v_ctx := DBMS_XMLGEN.newcontext('SELECT table_name, tablespace_name FROM user_tables WHERE rownum < 6'); 

    -- Set parameters to alter default Rowset and Row tag names and default case. 
    DBMS_XMLGEN.setrowsettag(v_ctx, 'USER_TABLES'); 
    DBMS_XMLGEN.setrowtag(v_ctx, 'TABLE'); 
    --DBMS_XMLGEN.settagcase(v_ctx, DBMS_XMLGen.LOWER_CASE); 

    -- Add an IE specfic XSL stylesheet reference so browser can transform the file. 
    --DBMS_XMLGEN.setstylesheetheader(v_ctx, 'C:\Development\XML\IEStyle.xsl', 'text/xsl'); 

    -- Create the XML document. 
    v_xml := DBMS_XMLGEN.getxml(v_ctx); 
    DBMS_XMLGEN.closecontext(v_ctx); 

    -- Output XML document to file. 
    v_file := UTL_FILE.fopen('C:\Development\XML\', 'test1.xml', 'w'); 
    WHILE v_more LOOP 
    UTL_FILE.put(v_file, SUBSTR(v_xml, 1, 32767)); 
    IF LENGTH(v_xml) > 32767 THEN 
     v_xml := SUBSTR(v_xml, 32768); 
    ELSE 
     v_more := FALSE; 
    END IF; 
    END LOOP; 
    UTL_FILE.fclose(v_file); 

    -- test insert into table 
    /* 
    insert into t_clob (clob_col) values (v_xml); 
    commit; 
    */ 
EXCEPTION 
    WHEN OTHERS THEN 
    DBMS_OUTPUT.put_line(Substr(SQLERRM,1,255)); 
    UTL_FILE.fclose(v_file); 
END; 

Lưu ý rằng tôi mượn hầu hết những điều này từ oracle-base trang web tuyệt vời

+0

Xin chào, bạn vui lòng giúp tôi với http://stackoverflow.com/questions/25279365/utl-file-write-error-when-calling-utl-file-put-in-a-loop? – Jaskey

0

Bí quyết khác là viết kết quả vào nhiều tệp XML, tức là nói 10.000 hàng cho mỗi tệp như Table_01_Rows_00001_99999.xml. Sau đó, hợp nhất các tệp XML sau này nếu cần.

Các vấn đề liên quan