2009-04-20 75 views
10

Tôi đang làm việc với một cơ sở dữ liệu Oracle lưu trữ HTML dưới dạng một kiểu dữ liệu dài. Tôi muốn truy vấn cơ sở dữ liệu để tìm kiếm một chuỗi cụ thể trong dữ liệu HTML được lưu trữ trong Long.Cách tốt nhất để tìm kiếm kiểu dữ liệu Long trong cơ sở dữ liệu Oracle là gì?

Tôi đã thử, "chọn * từ TABLE nơi COLUMN như '% form%'". Điều này gây ra lỗi Oracle sau vì "like" không được hỗ trợ cho các kiểu dữ liệu dài.

ORA-00932: các kiểu dữ liệu không nhất quán: dự kiến ​​NUMBER đã nhận LONG

Trả lời

9

Bạn không thể tìm kiếm trực tiếp LONG. LONG không thể xuất hiện trong mệnh đề WHERE. Chúng có thể xuất hiện trong danh sách SELECT mặc dù vậy bạn có thể sử dụng nó để thu hẹp số hàng mà bạn phải kiểm tra.

Oracle đã đề xuất chuyển đổi LONG thành CLOB trong ít nhất 2 bản phát hành vừa qua. Có ít hạn chế hơn đối với CLOB.

+9

Tuy nhiên, một mô tả trên ALL_TRIGGERS cho thấy TRIGGER_BODY như một chặng đường dài. Đề xuất và sau đó không tự làm? lẻ ... – xQbert

+0

Tương tự với DBA_IND_EXPRESSIONS. Nếu bạn mô tả nó, COLUMN_EXPRESSION vẫn là loại dài trong 11GR2. – pahariayogi

+0

Tôi muốn Oracle sẽ sửa chữa từ điển LONG cột, nhưng với kích thước và độ phức tạp của từ điển dữ liệu, tôi nghi ngờ việc nâng cấp tất cả LONGs lên CLOB sẽ là một bài tập rất lớn có nguy cơ tham nhũng trong quá trình nâng cấp. nó một mình. –

0

Không sử dụng LONG, sử dụng CLOB thay thế. Bạn có thể lập chỉ mục và tìm kiếm các CLOB như VARCHAR2.

Ngoài ra, việc truy vấn bằng ký tự đại diện hàng đầu (%) sẽ LUÔN là kết quả quét toàn bộ bảng. Thay vào đó, hãy xem số Oracle Text indexes.

7

Ví dụ:

create table longtable(id number,text long); 

insert into longtable values(1,'hello world'); 
insert into longtable values(2,'say hello!'); 

commit; 

create or replace function search_long(r rowid) return varchar2 is 
temporary_varchar varchar2(4000); 
begin 
select text into temporary_varchar from longtable where rowid=r; 
return temporary_varchar; 
end; 
/


SQL> select text from longtable where search_long(rowid) like '%hello%';                    

TEXT 
-------------------------------------------------------------------------------- 
hello world 
say hello! 

Nhưng hãy cẩn thận. Một hàm PL/SQL sẽ chỉ tìm kiếm 32K đầu tiên của LONG.

+0

Nếu bạn muốn xóa các hàng phù hợp, hãy xem câu trả lời này: http://stackoverflow.com/questions/2381203/oracle-delete-where-long-like/2381600#2381600 – Sam

+0

https://forums.oracle.com /forums/thread.jspa?threadID=413669#1418208 –

+0

rowid = r có nghĩa là gì. Tôi có nghĩa là ở đây "chọn văn bản vào tạm thời_varchar từ longtable nơi rowid = r;" – Yashu

0

Cách tốt nhất là chuyển đổi cột dài thành clob miễn là không được dùng nữa. Hoặc viết một khối pl/sql để đọc dữ liệu đó. Xem bên dưới liên kết để giải thích rõ ràng.

Tài liệu tham khảo: http://www.oraclebin.com/2012/12/using-long-data-type-in-where-clause-in.html

+1

Chào mừng bạn đến với Stack Overflow! Xin lưu ý rằng các liên kết trống đến trang web/sản phẩm của bạn không được khuyến khích ở đây vì hai lý do; Đầu tiên, câu trả lời phải được đăng dưới dạng câu trả lời tự chứa, không phải là liên kết đơn thuần tới trang web bên ngoài. Thứ hai, tự quảng cáo có xu hướng bị cau mày khi ở đây và thường bị gắn cờ là spam (đặc biệt là nếu không có tiết lộ nào mà bạn đang liên kết đến trang web/sản phẩm của riêng bạn). –

9

Bạn có thể sử dụng ví dụ này mà không sử dụng bảng temp:

DECLARE 

    l_var VARCHAR2(32767); -- max length 

BEGIN 

FOR rec IN (SELECT ID, LONG_COLUMN FROM TABLE_WITH_LONG_COLUMN) LOOP 
    l_var := rec.LONG_COLUMN; 
    IF l_var LIKE '%350%' THEN -- is there '350' string? 
    dbms_output.put_line('ID:' || rec.ID || ' COLUMN:' || rec.LONG_COLUMN); 
    END IF; 
END LOOP; 

END; 

Tất nhiên có một vấn đề nếu DÀI có hơn 32K ký tự.

1

Đầu chuyển đổi LONG loại cột để CLOB loại sau đó sử dụng LIKE điều kiện, ví dụ:

CREATE TABLE tbl_clob AS 
    SELECT to_lob(long_col) lob_col FROM tbl_long; 

SELECT * FROM tbl_clob WHERE lob_col LIKE '%form%'; 
Các vấn đề liên quan