5

私の環境は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

4

2 に答える 2