加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

oracle – 在blob表的触发器中计算blob哈希值

发布时间:2020-12-12 13:15:44 所属栏目:百科 来源:网络整理
导读:我的环境是Oracle 11g.我有一个表T_IMG,其列是图像blob,图像标识符,图像的哈希计算为SHA256.我希望每次在T_IMG表中插入或更新行时计算图像哈希并将其插入到T_IMG表中.为此,我在T_IMG表上使用插入或更新的before触发器,但是我很难访问触发器内的图像blob列. C
我的环境是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;

SHA2_STRING(‘0123456789’,256)
——————————————————————————– 84D89877F0D4041EFB6BF91A16F0248F2FD573E6AF05C19F96BEDB9F882F7882
1 row selected.

SHA2_BLOB(UTL_RAW.CAST_TO_RAW(‘0123456789’),256)
——————————————————————————– 84D89877F0D4041EFB6BF91A16F0248F2FD573E6AF05C19F96BEDB9F882F7882
1 row selected.

我在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数据上:

ORA-29532: Java call terminated by uncaught Java exception: java.sql.SQLException: Invalid empty lob operation
ORA-06512: at “TEST.SHA2_BLOB”,line 1
ORA-06512: at “TEST.TR_IMG_UPSERT”,line 13
ORA-04088: error during execution of trigger ‘TEST.TR_IMG_UPSERT’

似乎触发器将: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;

它的工作原理

SQL*Plus: Release 11.2.0.1.0 Production on Sat Aug 31 11:20:04 2013

Copyright (c) 1982,2010,Oracle. All rights reserved.

Connected to: Oracle Database 11g Release 11.2.0.1.0 – 64bit
Production

PL/SQL procedure successfully completed.

1 row created.
Commit complete.

IDN LENGTH IMGHASH


0 10 84D89877F0D4041EFB6BF91A16F0248F2FD573E6AF05C19F96BEDB9F882F7882

1 row updated.
Commit complete.

IDN LENGTH IMGHASH


0 12 5CE9AB10EA74270D12620DFACD74D262C6411E20761E459BB1B265DE883422AC

我发现我发布的错误只发生在Toad(11.6.0.43免费版)中提交手动编辑的IMG blob字段时,而不是在我通过PL / SQL执行表(插入,更新)时.

ADIM

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读