gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 18:10:02 26 4
gpt4 key购买 nike

我的环境是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 哈希值由以下代码计算,该代码基于 http://seanstuber.wordpress.com/2012/03/22/using-java-to-extend-dbms_crypto/ 上 Sean Stuber 的示例
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 表的问题?

注意:客户端应用程序无法通过插入/更新数据行来提供哈希。

阿迪姆

最佳答案

我在 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, dbms_lob.getlength(img) as length, 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 执行表(插入、更新)时发生。

阿迪姆

关于oracle - 在 blob 表的触发器中计算 blob 哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18522525/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com