私の環境はOracle 11gです。列が画像ブロブ、画像識別子、および SHA256 として計算された画像のハッシュであるテーブル T_IMG があります。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 行が選択されました。SHA2_BLOB(UTL_RAW.CAST_TO_RAW('0123456789'),256)
-------------------------------------- ------------------------------------------- 84D89877F0D4041EFB6BF91A16F0248F2FD573E6AF05C19F96BEDB9F882F7882
1 行が選択されました。
T_IMG の挿入または更新で before トリガーを使用して、image 列の 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 例外によって Java 呼び出しが終了しました: java.sql.SQLException: 無効な空 の
LOB操作
です
04088: トリガー 'TEST.TR_IMG_UPSERT' の実行中にエラーが発生しました
トリガーは :new.IMG データを空の blob として読み取るようです。
T_IMG テーブルで行が挿入または更新されるたびに、画像のハッシュを自動的に計算して T_IMG テーブルに挿入するという問題を解決するにはどうすればよいですか?
注: データ行を挿入/更新するクライアント アプリによってハッシュを提供することはできません。
AdiM