Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

strange behavior of DBMS_CRYPTO.hash(), how to manage?

TPD-OpitzFeb 25 2020 — edited Feb 25 2020

Situation:

I'm on a 12g database

Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production

I'm creating an XML from a master/detail relationship. I need to calculate a reproducable ID from the detail elements. The list of detail elements can become longer that 4000 chars so I use XMLAGG rather than LISTAGG.

But there also can be no details at all (which is the problematic situation for now).

For the same reason I decided for a sha1 from  DBMS_CRYPTO.hash().

here is a ssce:

CREATE OR REPLACE VIEW master_test
AS
      SELECT LEVEL AS master_id
        FROM DUAL
  CONNECT BY LEVEL < 5;

CREATE OR REPLACE VIEW detail_test
AS
  SELECT 10 AS master_id
       , 'test' AS detail_value
    FROM DUAL
   WHERE 1 = 2;

  SELECT master_id
       , DBMS_CRYPTO.hash( XMLAGG( XMLELEMENT( e
                                             ,    TO_CHAR( master_id )
                                               || detail_value
                                             , ''
                                              ).EXTRACT( '//text()' )
                                   ORDER BY detail_value
                                  ).getclobval( )
                         , 3
                          ) detail_hash
    FROM master_test LEFT JOIN detail_test USING( master_id )
GROUP BY master_id;

CREATE OR REPLACE PACKAGE dbms_crypto_test AS
  FUNCTION my_test
    RETURN VARCHAR2;
END dbms_crypto_test;
/

CREATE OR REPLACE PACKAGE BODY dbms_crypto_test AS
  FUNCTION my_test
    RETURN VARCHAR2 AS
    CURSOR crypto_hash_test_c IS
        SELECT master_id
             , DBMS_CRYPTO.hash( XMLAGG( XMLELEMENT( e
                                                   ,    TO_CHAR( master_id )
                                                     || detail_value
                                                   , ''
                                                    ).EXTRACT( '//text()' )
                                         ORDER BY detail_value
                                        ).getclobval( )
                               , 3
                                ) detail_hash
          FROM master_test LEFT JOIN detail_test USING( master_id )
      GROUP BY master_id;

    TYPE crypto_hash_test_t IS TABLE OF crypto_hash_test_c%ROWTYPE;

    crypto_hash_test  crypto_hash_test_t;

    output            VARCHAR2( 4000 );
  BEGIN
    OPEN crypto_hash_test_c;

    FETCH crypto_hash_test_c
      BULK COLLECT INTO crypto_hash_test;

    CLOSE crypto_hash_test_c;

    FOR my_row IN crypto_hash_test.FIRST .. crypto_hash_test.LAST LOOP
      output  :=
           output
        || 'master-'
        || crypto_hash_test( my_row ).master_id
        || ' detailHash='
        || crypto_hash_test( my_row ).detail_hash
        || CHR( 13 );
    END LOOP;

    RETURN output;
  END;
END dbms_crypto_test;
/

SELECT dbms_crypto_test.my_test
  FROM DUAL;

Problem:

while this SSCE works in my real application I get the same hash for each row but only in the PL/SQL package:

direct select:

  Master_01    2100010001    BD165A66337DA315DAF171BB84F8DD77CBC1A2E6
  Master_02    12300010001    14802186C09ACEA11BC97DFF5AA6752AC6716F20
  Master_03    50400010001    71857DCF3633AB4A34D429914245A2961478E504
  Master_04    18500010001    F6C9933D7290E55D731B6FA7BC1211B04B120934

fetch in package

Master_01 2100010001-<XmlElement  name="Master_01" structId="DA39A3EE5E6B4B0D3255BFEF95601890AFD80709">

Master_02 12300010001-<XmlElement  name="Master_02" structId="DA39A3EE5E6B4B0D3255BFEF95601890AFD80709">

Master_03 50400010001-<XmlElement  name="Master_03" structId="DA39A3EE5E6B4B0D3255BFEF95601890AFD80709">

Master_04 18500010001-<XmlElement  name="Master_04" structId="DA39A3EE5E6B4B0D3255BFEF95601890AFD80709">

how can I further analyse the strange behavior and finally resolve it?

This post has been answered by TPD-Opitz on Feb 25 2020
Jump to Answer
Comments
Post Details
Added on Feb 25 2020
1 comment
526 views