2012-08-23 45 views
7

Các ký tự nhiều byte đã khiến tôi rất đau.CHỌN càng nhiều dữ liệu từ CLOB đến VARCHAR2 càng tốt, với các ký tự nhiều byte trong dữ liệu

Bất kỳ đề xuất nào về vấn đề này?

Tôi có một trường CLOB rằng sức chứa một số ký tự nhiều byte, và tôi cần phải lựa chọn trong SQL và chuyển đổi lĩnh vực này thành một chuỗi cho quá trình hạ nguồn, hiện tại tôi đang sử dụng:

SELECT DBMS_LOB.SUBSTR(description, 4000, 1) FROM table 

Nhưng lệnh 4000 ở trên có chiều dài ký tự thay vì byte. Vì vậy, tôi đã phải thay đổi đến 3000 để xử lý bất kỳ ký tự nhiều byte có thể đã len lỏi vào dữ liệu khác kích thước bộ đệm lỗi sẽ xảy ra.

Sự cố này dành cho các bản ghi không chứa ký tự nhiều byte, có thể cắt bớt dữ liệu không cần thiết nhiều hơn mức cần thiết. (. Các 4000 là giới hạn chuỗi, chúng ta có thể/phải sống với điều đó)

Có cách nào để làm điều gì đó trong tương đương với:

SELECT DBMS_LOB.SUBSTR(description, 4000bytes, 1) FROM table 

Bằng cách đó tôi có thể nhận được dữ liệu càng nhiều ra càng tốt.

Lưu ý: Tôi không được phép để tạo bảng temp/quan điểm, không sử dụng PL/SQL, chỉ SQL SELECT ...

Trả lời

4

lẽ cắt ngắn varchar2 kết quả với SUBSTR:

SELECT SUBSTRB(DBMS_LOB.SUBSTR(description, 4000, 1), 1, 4000) FROM table 
+0

nên không có được "... với SUBSTRB"? (SUBSTRB thay vì SUBSTR) –

+1

Không quan tâm: Bạn có biết điều gì xảy ra nếu 3999 ký tự đầu tiên dài một byte và ký tự thứ 4000 là một byte nhiều byte không? Nó sẽ không trả về một nhân vật sai ở vị trí 4000 (vì nó diễn giải byte đầu tiên của char nhiều byte thành char đơn)? –

+2

Không có Jeffery nó sẽ không hoạt động, nếu 'mô tả' chứa các ký tự nhiều byte, thì DBMS_LOB.SUBSTR bên trong đã nhấn một lỗi bộ đệm chuỗi trước khi nó tới SUBSTRB. – alchn

7

suy nghĩ của Jeffrey quá trình là ok, nhưng alchn cũng đúng. Chỉ cần chạy vào cùng một vấn đề này và đây là giải pháp của tôi. Bạn sẽ phải có khả năng để tạo ra một chức năng mặc dù:

Create Or Replace Function clob_substr(p_clob In Clob 
             ,p_offset In Pls_Integer 
             ,p_length In Pls_Integer) Return Varchar2 Is 
Begin 
    Return substrb(dbms_lob.substr(p_clob 
           ,p_length 
           ,p_offset) 
       ,1 
       ,p_length); 
End; 
/

Đây là một bản demo của nó là sử dụng:

Select c 
     ,clob_substr(c 
        ,1 
        ,4000) 
    From (

     Select xmlelement("t", rpad('é', 4000, 'é'), rpad('é', 4000, 'é')).extract('//text()').getclobval() c 
      From dual 

     ); 
+1

Tôi đã tạo một ví dụ toàn diện (tôi hy vọng!) Dựa trên câu trả lời này trong https://bitbucket.org/janihur/orasql-ex/src/tip/clob-2.sql – user272735

+0

Tôi đã kiểm tra và xác nhận rằng việc sử dụng chức năng này hoạt động tốt hơn giải pháp của Jeffrey. Tuy nhiên, tôi không hiểu tại sao. Điều này có thực hiện chính xác điều tương tự, nhưng trong một hàm thay vì nội tuyến? Tại sao điều đó tạo sự khác biệt ở đây? – KStensland

+0

Tôi nghi ngờ sự khác biệt là varchar2 trong PL/SQL có thể lên đến 32.767 byte, trong khi trong SQL (ít nhất là trong 11g và trước đó) tối đa là 4.000 byte. –

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