gpt4 book ai didi

utf-8 - PLSQL 将 NVARCHAR2 从 BASE64 解码为 UTF-8

转载 作者:行者123 更新时间:2023-12-01 13:21:44 25 4
gpt4 key购买 nike

我有一个数据库,目前只用英文存储用户名。

我想加入 BASE64 & UTF-8 以便也以其他语言存储;我想将它存储在 NVARCHAR2 类型的列中.

数据库过程在BASE64 中收到名称, 我正在通过 UTL_ENCODE.BASE64_DECODE 对其进行解码& 将字符串转换为 VARCHAR2使用 UTL_RAW.CAST_TO_VARCHAR2 .但我得到的是乱码,而不是真正的词。

例如,我将 'алекс' 作为 BASE64 中的名称.我能够解码它,但转换为 VARCHAR2/NVARCHAR2不返回值:我得到的只是乱码。

我正在运行 Oracle 12c使用 NLS_CHARACTERSET WE8ISO8859P1

这是我用来解码的代码:

DECLARE 
lv_OrgUserName VARCHAR2(2000);
lv_encodedUserName VARCHAR2(2000);
lv_UserName VARCHAR2(2000);
BEGIN

lv_OrgUserName := 'алекс';
lv_encodedUserName := UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(lv_OrgUserName)));
DBMS_OUTPUT.PUT_LINE (lv_encodedUserName);
lv_UserName := UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW (lv_encodedUserName)));
DBMS_OUTPUT.PUT_LINE (lv_UserName);

END;

我怎样才能克服这个问题?

最佳答案

首先,WE8ISO8859P1(西欧 8 位 ISO 8859 第 1 部分,或 - ISO8859 第 1 部分)不支持西里尔字符:
请参阅此链接:https://en.wikipedia.org/wiki/ISO/IEC_8859-1

因此,如果您尝试将 алекс 之类的字符串存储到 VARCHAR2 变量/列中,您将始终得到 a???? 作为结果。

可能在数据库安装过程中,有人没有考虑西里尔字符,选择了错误的代码页。
更好的选择是 ISO/IEC 8859-5(第 5 部分),请参阅此链接:https://en.wikipedia.org/wiki/ISO/IEC_8859-5

一种选择是更改此编码 - 但这并不容易,而且超出了这个问题。


您可以做的是在应用程序中所有必须支持西里尔字符的地方严格使用NVARCHAR2 数据类型而不是VARCHAR2 数据类型。

尽管您需要注意,但仍有一些陷阱:

  • 你不能使用DBMS_OUTPUT包来调试你的代码,因为这个包只支持VARCHAR2数据类型,它不支持NVARCHAR
  • 您必须在所有文字中使用N'some string' 文字(带有 N 前缀) --> 'алекс' 是 VARCHAR2 数据类型,它总是自动转换在您的编码中转换为 'a????',而 n'алекс' 是 NVARCHAR2 数据类型,因此不会发生此类转换。

下面的代码是在 12c 版本上测试的,我使用的是 EE8MSWIN1250 代码页(它也不支持西里尔字符):

select * from nls_database_parameters
where parameter like '%CHARACTERSET%';

PARAMETER VALUE
----------------------- ------------
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_CHARACTERSET EE8MSWIN1250

请试一试:

CREATE OR REPLACE PACKAGE my_base64 AS
FUNCTION BASE64_ENCODE( str nvarchar2 ) RETURN varchar2;
FUNCTION BASE64_DECODE( str varchar2 ) RETURN nvarchar2;
END;
/

CREATE OR REPLACE PACKAGE BODY my_base64 AS

FUNCTION BASE64_ENCODE( str nvarchar2 ) RETURN varchar2
IS
lv_encodedUserName VARCHAR2(2000);
BEGIN
lv_encodedUserName := UTL_RAW.CAST_TO_VARCHAR2(UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(str)));
RETURN lv_encodedUserName;
END;


FUNCTION BASE64_DECODE( str varchar2 ) RETURN nvarchar2
IS
lv_UserName nVARCHAR2(2000);
BEGIN
lv_UserName := UTL_RAW.CAST_TO_nVARCHAR2(UTL_ENCODE.BASE64_DECODE(UTL_RAW.CAST_TO_RAW (str)));
RETURN lv_UserName;
END;

END;
/

几个例子:

select 'aлекс' As A, n'aлекс' As B from dual;

A B
----- -----
a???? aлекс

select my_base64.BASE64_ENCODE( n'аaaлекс' ) As aleks from dual;

ALEKS
--------------------------------------------------------------------------------
BDAAYQBhBDsENQQ6BEE=

select my_base64.BASE64_DECODE( 'BDAAYQBhBDsENQQ6BEE=' ) as aleks from dual;

ALEKS
--------------------------------------------------------------------------------
аaaлекс

select my_base64.BASE64_DECODE( my_base64.BASE64_ENCODE( n'аaaлекс' ) ) as Aleks from dual;

ALEKS
--------------------------------------------------------------------------------
аaaлекс

关于utf-8 - PLSQL 将 NVARCHAR2 从 BASE64 解码为 UTF-8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37907398/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com