2013-09-26 63 views
6
Select TO_CLOB(a)|| TO_CLOB(b)|| TO_CLOB(c) || TO_CLOB(d) 
    from table1 

Truy vấn trên không được đặt đúng dữ liệu vào tệp văn bản.L ERI tại dòng 191: ORA-01489: kết quả của chuỗi nối quá dài

trong khi,

Select a||b||c||d 
    from table1. 

được kết thúc để

LỖI tại dòng 191: ORA-01.489: kết quả của chuỗi nối quá dài.

Xin vui lòng trợ giúp !!!

+0

Một số lịch phát sóng. là mẹo tại: http://stackoverflow.com/questions/14864055/listagg-function-and-ora-01489-result-of-string-concatenation-is-too-long – Sampath

Trả lời

0

Làm cách nào để tăng giá trị cho LONG? Bạn có thể phải tăng biến dài thành giá trị cao hơn. Nhấp vào here để biết mô tả chi tiết.

Ví dụ:

SET LONG 100000; 
SPOOL test_clob.txt 
SELECT to_clob(lpad('A',4000,'A')) 
     ||'B' 
     ||to_clob(lpad('C',4000,'C')) 
     ||'D' 
     ||to_clob(lpad('E',4000,'E')) 
     ||'F' 
    FROM dual; 
SPOOL OFF; 

truy vấn thứ hai của bạn trả về lỗi vì, Các concat (||) điều hành trong truy vấn đang cố gắng để trở varchar2, trong đó có giới hạn 4000 ký tự và nhận được vượt quá.

+1

ĐẶT LẠI một tham số rộng của hệ thống hay thực hiện chỉ hoạt động cho truy vấn đang được khởi chạy? –

+1

@DavideInglima Từ tài liệu: * "Câu lệnh SET gán giá trị cho các loại biến khác nhau ảnh hưởng đến hoạt động của máy chủ hoặc ứng dụng khách của bạn." * –

-1

Mã vạch SQL * Plus có mã vạch 81 khi hiển thị CLOB, dường như không có cách nào xung quanh nó. Vì vậy, nếu bạn muốn tạo một tệp csv để được tải vào cơ sở dữ liệu khác, bạn sẽ có vấn đề phân tích cú pháp các dòng mới bổ sung này.

Giải pháp cuối cùng là sử dụng PL/SQL. Ví dụ, để genarate một dấu phẩy phân cách tập tin csv từ bảng "xyz", sử dụng đoạn mã sau:

set lin 32766 
set serveroutput on size unlimited 

DECLARE 
    TYPE arraytable IS TABLE OF xyz%ROWTYPE; 
    myarray arraytable; 
    CURSOR c IS 
    select * from xyz ; 
BEGIN 
    OPEN c; 
    LOOP 
     FETCH c BULK COLLECT INTO myarray LIMIT 10000; 
     FOR i IN 1 .. myarray.COUNT 
      LOOP 
       DBMS_OUTPUT.PUT_LINE(
        myarray(i).col1||','|| 
        myarray(i).col2||','|| 
        myarray(i).col3||','|| 
        myarray(i).col4; 
     END LOOP; 
     EXIT WHEN c%NOTFOUND; 
    END LOOP; 
END; 
/

Một tiền thưởng của phương pháp này là điều này thậm chí làm việc với kiểu dữ liệu DÀI!

+0

Bạn vẫn đang ghép nối VARCHAR> 4000 byte. –

+0

@ Jean-Francois Savard, Không. Đầu ra từ PL/SQL không còn là VARCHAR nữa. Do đó nó sẽ không bị hạn chế bởi giới hạn kích thước 4000. – user3398079

-1

Thử chức năng xmlagg. Điều đó làm việc tốt cho tôi khi tôi gặp phải một vấn đề tương tự.

http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions215.htm

+3

Trong khi liên kết này có thể trả lời câu hỏi, tốt hơn nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở thành không hợp lệ nếu trang được liên kết thay đổi. – OhBeWise

1

VARCHAR2 được giới hạn trong 4000 byte. Nếu bạn nhận được lỗi này

L ERI tại dòng 191: ORA-01489: kết quả của chuỗi nối quá dài.

Sau đó, khá rõ ràng rằng kết nối vượt quá 4000 byte.

Bây giờ phải làm gì?

Giải pháp đầu tiên của bạn để sử dụng CLOB thay thế là chính xác.

select TO_CLOB(a)|| TO_CLOB(b)|| TO_CLOB(c) || TO_CLOB(d) 

Nó có vẻ như vấn đề thực sự của bạn được tiết kiệm để nộp

Trên truy vấn không được spooling dữ liệu đúng vào tập tin văn bản.

Trong khi bạn không đăng cách lưu kết quả vào một tệp, tôi tin rằng bạn không thực hiện đúng cách.Nếu bạn cố gắng lưu vào tập tin giống như cách bạn đang làm với VARCHAR2, bạn đang làm sai.

Trước tiên, bạn cần sử dụng dbms_lob.read để đọc thư viện từ cơ sở dữ liệu, sau đó sử dụng utl_file.put_raw để ghi vào tệp.

DECLARE 
    position NUMBER := 1; 
    byte_length NUMBER := 32760; 
    length NUMBER; 
    vblob BLOB; 
    rawlob RAW(32760); 
    temp NUMBER; 
    output utl_file.file_type; 
BEGIN 
    -- Last parameter is maximum number of bytes returned. 
    -- wb stands for write byte mode 
    output := utl_file.fopen('DIR', 'filename', 'wb', 32760); 

    position := 1; 
    select dbms_lob.getlength(yourLob) 
    into len 
    from somewhere 
    where something; 

    temp := length; 

    select yourLob 
    into vlob 
    from somewhere 
    where something; 

    IF len < 32760 THEN 
     utl_file.put_raw(output, vblob); 
     -- Don't forget to flush 
     utl_file.fflush(output); 
    ELSE -- write part by part 
     WHILE position < len AND byte_length > 0 
     LOOP 
      dbms_lob.read(vblob, byte_length, position, rawlob); 

      utl_file.put_raw(output,rawlob); 

      -- You must admit, you would have forgot to flush. 
      utl_file.fflush(output); 

      position := position + byte_length; 

      -- set the end position if less than 32000 bytes 
      temp := temp - bytelen; 
      IF temp < 32760 THEN 
       byte_length := temp; 
      END IF; 
    END IF; 
END; 
Các vấn đề liên quan