将 AL32UTF8 转换为 Base64 的问题
Issue converting AL32UTF8 to Base64
为什么在 WE8ISO8859P1 字符集中连接字符串的 base64 编码部分会产生与对完整字符串进行 base64 编码相同的结果,但在 AL32UTF8 中不会发生同样的情况?
WITH charset_names AS (
SELECT 'WE8ISO8859P1' charset_name FROM dual
UNION ALL
SELECT 'AL32UTF8' FROM dual
),
encoded_strings AS (
SELECT charset_name, 'FULL' style, NULL nivel, utl_encode.text_encode('DESCRIÇÃO_DA_REQUISIÇÃO', charset_name, 1) encoded_string
FROM
charset_names
UNION ALL
SELECT charset_name, 'SPLITTED', nivel, utl_encode.text_encode(substr('DESCRIÇÃO_DA_REQUISIÇÃO', (nivel-1)*3+1, 3), charset_name, 1) encoded_string
FROM
charset_names,
(
SELECT level nivel
FROM dual
CONNECT BY level <= 8
)
)
SELECT charset_name, style, LISTAGG(encoded_string) WITHIN GROUP (ORDER BY charset_name, style, nivel)
FROM encoded_strings
GROUP BY style, charset_name
ORDER BY charset_name, style
查询结果:
AL32UTF8 FULL REVTQ1JJw4fDg09fREFfUkVRVUlTScOHw4NP ok
AL32UTF8 SPLITTED REVTQ1JJw4fDg08=X0RBX1JFUVVJU0nDhw==w4NP invalid
WE8ISO8859P1 FULL REVTQ1JJx8NPX0RBX1JFUVVJU0nHw08= ok
WE8ISO8859P1 SPLITTED REVTQ1JJx8NPX0RBX1JFUVVJU0nHw08= ok
Oracle 数据库 11g 企业版发布 11.2.0.4.0 - 64 位生产
数据库字符集:WE8ISO8859P1
BASE64 编码占用 3 Bytes 并将其转换为 4 个 ASCII 字符。如果您的输入数据不是 3 的整数倍,则 BASE64 将用 =
填充
字符集 WE8ISO8859P1
(又名 ISO-8859-1)是一个单字节字符集,即每个字符都是 一个字节。在 AL32UTF8
(又名 UTF-8)中,一个字符可以是 1 到 4 个字节
字符 DESCRI
每个使用 1 个 UTF-8 字节。这些是 6 个字符 => 6 字节 = 2*3 字节,它们被转换为 8 个 BASE64 字符。因此前 8 个字符 REVTQ1JJ
相同。
您可以尝试 SUBSTRB()
而不是 SUBSTR()
,它可能有效,但我没有测试,因为您的查询对我来说意义不大。也许您正在寻找这个:Base64 encoding and decoding in oracle
为什么在 WE8ISO8859P1 字符集中连接字符串的 base64 编码部分会产生与对完整字符串进行 base64 编码相同的结果,但在 AL32UTF8 中不会发生同样的情况?
WITH charset_names AS (
SELECT 'WE8ISO8859P1' charset_name FROM dual
UNION ALL
SELECT 'AL32UTF8' FROM dual
),
encoded_strings AS (
SELECT charset_name, 'FULL' style, NULL nivel, utl_encode.text_encode('DESCRIÇÃO_DA_REQUISIÇÃO', charset_name, 1) encoded_string
FROM
charset_names
UNION ALL
SELECT charset_name, 'SPLITTED', nivel, utl_encode.text_encode(substr('DESCRIÇÃO_DA_REQUISIÇÃO', (nivel-1)*3+1, 3), charset_name, 1) encoded_string
FROM
charset_names,
(
SELECT level nivel
FROM dual
CONNECT BY level <= 8
)
)
SELECT charset_name, style, LISTAGG(encoded_string) WITHIN GROUP (ORDER BY charset_name, style, nivel)
FROM encoded_strings
GROUP BY style, charset_name
ORDER BY charset_name, style
查询结果:
AL32UTF8 FULL REVTQ1JJw4fDg09fREFfUkVRVUlTScOHw4NP ok
AL32UTF8 SPLITTED REVTQ1JJw4fDg08=X0RBX1JFUVVJU0nDhw==w4NP invalid
WE8ISO8859P1 FULL REVTQ1JJx8NPX0RBX1JFUVVJU0nHw08= ok
WE8ISO8859P1 SPLITTED REVTQ1JJx8NPX0RBX1JFUVVJU0nHw08= ok
Oracle 数据库 11g 企业版发布 11.2.0.4.0 - 64 位生产 数据库字符集:WE8ISO8859P1
BASE64 编码占用 3 Bytes 并将其转换为 4 个 ASCII 字符。如果您的输入数据不是 3 的整数倍,则 BASE64 将用 =
字符集 WE8ISO8859P1
(又名 ISO-8859-1)是一个单字节字符集,即每个字符都是 一个字节。在 AL32UTF8
(又名 UTF-8)中,一个字符可以是 1 到 4 个字节
字符 DESCRI
每个使用 1 个 UTF-8 字节。这些是 6 个字符 => 6 字节 = 2*3 字节,它们被转换为 8 个 BASE64 字符。因此前 8 个字符 REVTQ1JJ
相同。
您可以尝试 SUBSTRB()
而不是 SUBSTR()
,它可能有效,但我没有测试,因为您的查询对我来说意义不大。也许您正在寻找这个:Base64 encoding and decoding in oracle