在 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;
我在 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;