Why does utl_encode.base64_encode produce different results in PLSQL and SQL?
(UTL_ENCODE is used when you have binary data that you want to transfer across the network. If you just stream this in it's raw format some protocols may interpret the binary data as control characters or character combinations and may act on this. To get around this, the binary data is encoded into characters using UTL_ENCODE.)
For example, from PL/SQL:
CREATE OR REPLACE FUNCTION TestEncodeBase64 (email nvarchar2) RETURN nvarchar2 IS
result nvarchar2(256);
BEGIN
SELECT UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(email)))
INTO result
FROM dual;
RETURN result;
END TestEncodeBase64;
/
SQL> select TestEncodeBase64 ('TEST') from dual;
TESTENCODEBASE64('TEST')
-----------------------------------------
AFQARQBTAFQ=
From SQL:
SELECT UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW('TEST'))) as test
FROM dual;
TEST
-----------------
VEVTVA==
SOLUTION
The reason there is a difference is because the PLSQL user defined function uses NVARCHAR2 whereas SQL defaults to VARCHAR2. The NVARCHAR2 datatype uses 3 bytes per character so therefore 'TEST' is 12 bytes in length. The VARCHAR2 datatype uses 2 bytes per character so 'TEST' is 8 bytes in length.
When this character string is converted to RAW data this is where the difference occurs as the two strings are different lengths. SQL uses the default VARCHAR2 datatype and when you change the function to use VARCHAR2 the result of SQL and PLSQL is the same.
There should be no issue here as when the strings are decoded back again you will not see any difference.