2008-09-21 40 views
8

trong trình kích hoạt DB2, tôi cần so sánh giá trị của một trường CLOB. Một cái gì đó như:SQL - Làm thế nào để bạn so sánh một CLOB

IF OLD_ROW.CLOB_FIELD != UPDATED_ROW.CLOB_FIELD 

nhưng "! =" Không hoạt động để so sánh CLOB.

Cách so sánh nó là gì?

Edited thêm:

cò của tôi cần phải làm một số hành động nếu trường CLOB được thay đổi trong quá trình cập nhật. Đây là lý do tôi cần so sánh 2 CLOB trong mã kích hoạt. Tôi đang tìm một số thông tin chi tiết về cách thực hiện điều này

+0

Sau đó, có lẽ bạn nên xem xét @ câu trả lời igelkott của. Đó có thể là cách tốt nhất. Bạn tính toán kiểm tra MD5 mới và so sánh nó với cũ, và nếu chúng khác nhau, CLOB đã thay đổi. Có một cơ hội rất nhỏ mà nó đã thay đổi và bạn có cùng một tổng kiểm tra - nhưng đừng lo lắng về nó. –

Trả lời

1

Tôi tin rằng không thể sử dụng các toán tử này trên các trường CLOB, vì cách chúng được lưu trữ.

+0

Đây là lý do tôi đang tìm kiếm. cảm ơn. –

7

Tính hàm băm md5 (hoặc khác) của các nhánh và sau đó so sánh chúng. Tính toán ban đầu sẽ chậm nhưng so sánh nhanh và dễ dàng. Đây có thể là một phương pháp tốt nếu phần lớn dữ liệu của bạn không thay đổi thường xuyên.

Một cách để tính md5 là thông qua câu lệnh java trong trình kích hoạt của bạn. Lưu chúng trong cùng một bảng (nếu có thể) hoặc xây dựng một bảng phụ trợ đơn giản.

6

ý tưởng Iglekott là một tốt nhất, với một caveat:

Hãy cẩn thận với so sánh-by-băm, nếu dữ liệu của bạn có thể bị tấn công. Hiện tại không khả thi tính toán để tạo ra một va chạm băm cho một giá trị MD5 cụ thể, nhưng có thể tạo ra hai đầu vào khác nhau sẽ tạo ra cùng một MD5 (do đó không kích hoạt mã của bạn). Cũng có thể tạo hai chuỗi khác nhau với cùng một tiền tố giá trị băm đó cho cùng một giá trị.

Nếu loại tấn công đó có thể dẫn đến tính toàn vẹn của hệ thống của bạn bị xâm nhập và đó là mối quan tâm, bạn muốn khám phá các tùy chọn khác. Cách đơn giản nhất sẽ đơn giản là chuyển đổi các hàm băm, SHA-2 hiện không có các lỗ hổng đã biết.

Nếu đây không phải là một mối quan tâm - địa ngục, đi với CRC. Bạn sẽ không bảo mật mật mã ở đây. Chỉ cần không đi với một chức năng mã hóa yếu nếu công cụ này được cài đặt trên một smartbomb, 'mkay? :-)

8

Trong Oracle 10g, bạn có thể sử dụng DBMS_LOB.compare() API.

Ví dụ:

select * from table t where dbms_lob.compare(t.clob1, t.clob2) != 0 

Full API:

DBMS_LOB.COMPARE (
    lob_1   IN BLOB, 
    lob_2   IN BLOB, 
    amount   IN INTEGER := 4294967295, 
    offset_1   IN INTEGER := 1, 
    offset_2   IN INTEGER := 1) 
    RETURN INTEGER; 

DBMS_LOB.COMPARE (
    lob_1   IN CLOB CHARACTER SET ANY_CS, 
    lob_2   IN CLOB CHARACTER SET lob_1%CHARSET, 
    amount   IN INTEGER := 4294967295, 
    offset_1   IN INTEGER := 1, 
    offset_2   IN INTEGER := 1) 
    RETURN INTEGER; 

DBMS_LOB.COMPARE (
    lob_1   IN BFILE, 
    lob_2   IN BFILE, 
    amount   IN INTEGER, 
    offset_1   IN INTEGER := 1, 
    offset_2   IN INTEGER := 1) 
    RETURN INTEGER; 
+0

Hãy coi chừng rằng "Các hàm có giá trị đầu vào NULL hoặc không hợp lệ cho các tham số trả về giá trị NULL". Điều này có thể có ý nghĩa trong một số trường hợp. – Vadzim

-1

có sử dụng DB2 != không bình đẳng? Chuẩn ANSI SQL sử dụng <> không bằng.

+0

DB2 cho phép cả <> và! = Thay thế cho nhau. Vấn đề với câu hỏi này không phải là toán tử được sử dụng để so sánh, nhưng thực tế là các kiểu dữ liệu đối tượng lớn (BLOB/CLOB) không cho phép so sánh bình đẳng trong kiểu gốc của chúng. Tuy nhiên, DB2 cho phép các biểu thức SQL đưa phần đầu của BLOB hoặc CLOB vào một kiểu dữ liệu khác, bao gồm các kiểu cho phép các phép so sánh. –

1

Nếu CLOB là 32K trở xuống, bạn có thể truyền chúng thành VARCHAR, cho phép so sánh, LIKE và các hàm chuỗi SQL khác nhau.

Nếu không, bạn có thể muốn xem xét thêm cột để chứa hàm băm của CLOB và thay đổi (các) ứng dụng để giữ cho băm đó được cập nhật bất cứ khi nào CLOB được cập nhật.

2

Ý tưởng md5 có lẽ là tốt nhất, nhưng cách khác là tạo trình kích hoạt đặc biệt chỉ kích hoạt khi trường CLOB của bạn được cập nhật.

Theo syntax diagram, bạn sẽ xác định kích hoạt như:

CREATE TRIGGER trig_name AFTER UPDATE OF CLOB_FIELD 
//trigger body goes here 

này được giả định rằng ứng dụng của bạn (hoặc bất cứ ai đang cập nhật bảng) là đủ thông minh để cập nhật các trường CLOB CHỈ KHI đã có một sự thay đổi được thực hiện cho các lĩnh vực clob, và không phải mỗi khi bảng của bạn được cập nhật.

0

Chỉ cần khai báo trình kích hoạt để kích hoạt nếu cột cụ thể đó được cập nhật.

create trigger T_TRIG on T 
before update of CLOB_COL 
... 
0

Tạo giá trị băm và so sánh chúng là cách tốt nhất IMHO.

Đây là mã chưa được kiểm tra:

... 
declare leftClobHash integer; 
declare rightClobHash integer; 
set leftClobHash = (
    SELECT DBMS_UTILITY.GET_HASH_VALUE(OLD_ROW.CLOB_FIELD,100,1024) AS HASH_VALUE 
    FROM SYSIBM.SYSDUMMY1); 
set rightClobHash = (
    SELECT DBMS_UTILITY.GET_HASH_VALUE(UPDATED_ROW.CLOB_FIELD,100,1024) AS HASH_VALUE 
    FROM SYSIBM.SYSDUMMY1); 

IF leftClobHash != rightClobHash 
... 

Lưu ý rằng bạn cần phải đặc quyền EXECUTE trên module DBMS_UTILITY. Bạn có thể tìm thêm thông tin về mã SQL PL được cung cấp trong các liên kết sau.

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