oracle – 在blob表的触发器中计算blob哈希值
我的环境是Oracle 11g.我有一个表T_IMG,其列是图像blob,图像标识符,图像的哈希计算为SHA256.我希望每次在T_IMG表中插入或更新行时计算图像哈希并将其插入到T_IMG表中.为此,我在T_IMG表上使用插入或更新的before触发器,但是我很难访问触发器内的图像blob列.
CREATE TABLE TEST.T_IMG ( IDN VARCHAR2(18 BYTE) NOT NULL,IMG BLOB NOT NULL,IMGHASH VARCHAR2(128 BYTE) ); 字符串和blob的SHA256哈希值由以下代码计算,该代码基于Sean Stuber在http://seanstuber.wordpress.com/2012/03/22/using-java-to-extend-dbms_crypto/的示例 CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED sha2 AS import java.security.MessageDigest; import oracle.sql.*; public class sha2 { public static oracle.sql.RAW get_digest_string( String p_string,int p_bits ) throws Exception { MessageDigest v_md = MessageDigest.getInstance( "SHA-" + p_bits ); byte[] v_digest; v_digest = v_md.digest( p_string.getBytes( "UTF-8" ) ); return RAW.newRAW(v_digest); } public static oracle.sql.RAW get_digest_blob( oracle.sql.BLOB p_blob,int p_bits ) throws Exception { byte[] allBytesInBlob; allBytesInBlob = p_blob.getBytes(1,(int) p_blob.length()); MessageDigest v_md = MessageDigest.getInstance( "SHA-" + p_bits ); byte[] v_digest = v_md.digest( allBytesInBlob ); return RAW.newRAW(v_digest); } } / CREATE OR REPLACE FUNCTION sha2_string(p_string in VARCHAR2,p_bits in number) RETURN RAW AS LANGUAGE JAVA NAME 'sha2.get_digest_string( java.lang.String,int ) return oracle.sql.RAW'; / CREATE OR REPLACE FUNCTION sha2_blob(p_byte in BLOB,p_bits in number) RETURN RAW AS LANGUAGE JAVA NAME 'sha2.get_digest_blob( oracle.sql.BLOB,int ) return oracle.sql.RAW'; / 以上功能有效.测试他我得到: SELECT sha2_string('0123456789',256) FROM DUAL; SELECT sha2_blob(utl_raw.cast_to_raw('0123456789'),256) FROM DUAL;
我在T_IMG上插入或更新时使用before触发器来计算图像列的SH256散列. CREATE OR REPLACE TRIGGER TEST.TR_IMG_UPSERT BEFORE INSERT OR UPDATE ON TEST.T_IMG FOR EACH ROW DECLARE imghash varchar2(128); vblob blob; BEGIN vblob := :new.IMG; IF(vblob IS NOT NULL)THEN /*-- this works imghash := sha2_string('0123456789',256); :new.imghash := imghash; */ /*-- this works too vblob := utl_raw.cast_to_raw('0123456789'); imghash := sha2_blob(vblob,256); :new.imghash := imghash; */ -- this DOES NOT work imghash := sha2_blob(vblob,256); :new.imghash := imghash; END IF; END; / 触发器本身起作用;它计算并在模拟数据(制造的字符串或blob)上插入哈希值,但在抛出以下错误时不在实际图像blob数据上:
似乎触发器将:new.IMG数据读取为空blob. 为什么会发生这种情况?如何在每次在T_IMG表中插入或更新行时自动计算并将图像的哈希值插入到T_IMG表中? 注意:插入/更新数据行的客户端应用程序无法提供哈希值. ADIM 解决方法我在Oracle PL / SQL中执行了以下代码:var idn varchar2(18 byte); exec :idn := '0'; insert into t_img (idn,img) values (:idn,utl_raw.cast_to_raw('0123456789') ); commit; select idn,dbms_lob.getlength(img) as length,imghash from t_img where idn=:idn; update t_img set img=utl_raw.cast_to_raw('012345678901') where idn=:idn; commit; select idn,imghash from t_img where idn=:idn; 它的工作原理
我发现我发布的错误只发生在Toad(11.6.0.43免费版)中提交手动编辑的IMG blob字段时,而不是在我通过PL / SQL执行表(插入,更新)时. ADIM (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |