在 oracle 中解码 clob 然后在经典 asp 中编码这个 blob 不会给出相同的 clob

decoding clob in oracle and then encoding this blob in classic asp does not give the same clob

我在 table 中有两列,其数据类型为 clob 和 blob 。我在 clob 列中插入一个 clob 数据,并通过以下代码在 oracle 中解码此 clob 将此数据插入到 blob 数据:

function decode_base64(p_clob_in in clob) return blob is
    v_blob blob;
    v_result blob;
    v_offset integer;
    v_buffer_size binary_integer := 48;
    v_buffer_varchar varchar2(48);
    v_buffer_raw raw(48);
  begin
    if p_clob_in is null then
      return null;
    end if;
    dbms_lob.createtemporary(v_blob, true);
    v_offset := 1;
    for i in 1 .. ceil(dbms_lob.getlength(p_clob_in) / v_buffer_size) loop
      dbms_lob.read(p_clob_in, v_buffer_size, v_offset, v_buffer_varchar);
      v_buffer_raw := utl_raw.cast_to_raw(v_buffer_varchar);
      v_buffer_raw := utl_encode.base64_decode(v_buffer_raw);
      dbms_lob.writeappend(v_blob, utl_raw.length(v_buffer_raw), v_buffer_raw);
      v_offset := v_offset + v_buffer_size;
    end loop;
    v_result := v_blob;
    dbms_lob.freetemporary(v_blob);
    return v_result;
  end decode_base64;

然后我通过以下代码在 asp.net 中获取此 blob 数据:

strSQL ="SELECT BIO_DATA FingerData ,  DATA_LENGTH len_of_data , SERIAL_NO sl_no FROM FP_BIOMETRIC_DATA WHERE   CUST_NO =" & trim(Request("name")) & "  "
        Set objExec = Conn.Execute(strSQL)
fingerData1 = objExec("FingerData")

然后我通过以下代码将此数据编码为 base64:

Function Base64Encode(sText)
        Dim oXML, oNode

        Set oXML = CreateObject("Msxml2.DOMDocument.3.0")
        Set oNode = oXML.CreateElement("base64")
        oNode.dataType = "bin.base64"
        oNode.nodeTypedValue =sText
        Base64Encode = oNode.text
        Set oNode = Nothing
        Set oXML = Nothing
    End Function

Then I am trying to compare this data and clob data in oracle database by this website .这个网站说两个数据不一样。为什么 ?错误在哪里?如何通过在 oracle 中解码 clob 数据来获取 blob 数据?

我认为问题出在这一行

dbms_lob.read(p_clob_in, v_buffer_size, v_offset, v_buffer_varchar);

v_buffer_size 固定为 48 个字符,但是您的 BASE64 字符串可能包含 NEW_LINE 个字符,这些字符在解码时会被忽略,但它们会被计入 v_buffer_size.

在读取缓冲区或将 v_buffer_size 的值增加子字符串中的 NEW_LINE 个字符之前,您必须删除所有 NEW_LINE 个字符。

试试这个:

CREATE OR REPLACE FUNCTION DecodeBASE64(InBase64Char IN OUT NOCOPY CLOB) RETURN BLOB IS

    res BLOB;
    clob_trim CLOB;

    dest_offset INTEGER := 1;
    src_offset INTEGER := 1;
    read_offset INTEGER := 1;
    ClobLen INTEGER;

    amount INTEGER := 1440; -- must be a whole multiple of 4
    buffer RAW(1440);
    stringBuffer VARCHAR2(1440);

BEGIN
    IF DBMS_LOB.GETLENGTH(InBase64Char) IS NULL THEN 
        RETURN NULL;
    END IF;

    -- Remove all NEW_LINE from base64 string
    ClobLen := DBMS_LOB.GETLENGTH(InBase64Char);
    DBMS_LOB.CREATETEMPORARY(clob_trim, TRUE);
    LOOP
        EXIT WHEN read_offset > ClobLen;
        stringBuffer := REPLACE(REPLACE(DBMS_LOB.SUBSTR(InBase64Char, amount, read_offset), CHR(13), NULL), CHR(10), NULL);
        DBMS_LOB.WRITEAPPEND(clob_trim, LENGTH(stringBuffer), stringBuffer);
        read_offset := read_offset + amount;
    END LOOP;

    read_offset := 1;
    ClobLen := DBMS_LOB.GETLENGTH(clob_trim);
    DBMS_LOB.CREATETEMPORARY(res, TRUE);
    LOOP
        EXIT WHEN read_offset > ClobLen;
        buffer := UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW(DBMS_LOB.SUBSTR(clob_trim, amount, read_offset)));
        DBMS_LOB.WRITEAPPEND(res, DBMS_LOB.GETLENGTH(buffer), buffer);
        read_offset := read_offset + amount;
    END LOOP;

    RETURN res;    

END DecodeBASE64;