- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个数据库,目前只用英文存储用户名。
我想加入 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数据类型,它不支持NVARCHARN'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/
将 nvarchar(max) 转换为 nvarchar(n) 并指示有更多数据的最快方法是什么? 例如:将列地址转换为 nvarchar(100),如果地址大于 100 个字符,则将最后 3 个字符
SO 和其他网站上都有多个帖子明确指出 nvarchar(max) 的最大长度是 2GB。但是,我在互联网和现实生活中也看到很多困惑,它实际上是 Unicode 中的 8000/4000。 我想知道什
我刚刚将表中的一个 nvarchar(MAX) 字段更改为 nvarchar(250)。有人可以告诉我如果条目超过 250 个字符,数据会发生什么情况吗? 我关心的不是可见数据,而是幕后发生的事情:
如果下面两个表的唯一区别是 nvarchar(50) 与 nvarchar(max) 以及每个表中的字符串,它们之间的一般存储和性能差异是什么字段范围从 1 到 50 个字符?这是在 SQL Serv
我在 SQL SERVER 2008 中有一个现有表,其中一列为 NVARCHAR(MAX) 并且其中只有少于 10 个字符的值。 此表正在生产中,其中包含数据。 我有一个要求,我必须将此列从 NVA
我正在构建一个表来跟踪数据库中特定对象的历史记录。目前我有以下列: HistoryId int IDENTITY(1,1) NOT NULL HistoryDate datetimeoffset(7)
在最终向用户呈现结果集之前,我对表变量进行了大量工作。例如,我可能会从许多不同的表中提取全部列,如下所示: DECLARE @tmp TABLE ( ID int, username nvarchar
我今天在 SQL Server(2008R2 和 2012)中遇到了一个非常奇怪的问题。我正在尝试结合使用连接和 select 语句来构建一个字符串。 我已经找到了解决方法,但我真的很想了解这里发生了
例如,nvarchar(max) 的性能是否低于 nvarchar(100)? 最佳答案 here (SO) 和 here (MSDN) 回答了同样的问题 引用 David Kreps 的回答: Wh
我们的 SQL Server(2005 和 2008)数据库中有几个表,其中的列定义为 nvarchar(4000)。我们有时需要能够存储比这更多的数据,并考虑改用 nvarchar(max)。现在回
当你在 fluent NHibernate 中设置一个字符串值时,它总是将 DB 值设置为 Nvarchar(255),我需要存储相当多的基于用户输入的长字符串,而 255 是不切实际的。 补充一下,
我在 sql 中有一个列,在某些情况下有时是 nvarchar 和数字。该列的数据类型为 nvarchar 。我只对我不需要它的数字的地方感兴趣。我使用如下案例 (SELECT case when i
在 SQL Server 中,如果您创建一个 NVARCHAR(MAX) 类型的列,并且仅在其中填充 128 个字符 - 与将其创建为 NVARCHAR 相比,它是否会消耗更多的存储空间(128) -
我们有一个索引列(ModelName),它在表中非常重要,并且与“目录号”非常相似,但它不是 PK。 大量按 ModelName 订购 ;正在使用 WHERE ModelName 等。 该列最初为 N
使用 SQL Server 2014,我有一个表,其中有 nvarchar(max)名为 [ASCII File] 的列它可以包含许多 K 的 ASCII 文本文件。然后我想对该文件执行 MD5 哈希
如何将 NTEXT 列转换为 NVARCHAR(MAX)? 我有 4 个数据库,其中有一个表存在于所有四个数据库中。在此表中,存在一个类型为 NTEXT except 的 Notes 列,该列为 nv
我面临的情况是必须使用脚本将现有数据库结构从 varchar 更新为 nvarchar。由于每次运行配置应用程序时都会运行此脚本,因此我宁愿确定列是否已更改为 nvarchar,而不是对表执行更改。我
我想知道定义 nvarchar(max) 类型的列而不是为其指定(较小的)最大大小是否有任何缺点。 我在某处读到,如果列值超过 4?KB,则剩余数据将添加到“溢出”区域,这是可以的。 我正在创建一个表
我想更改表 stk020 中的列类型。所以,我使用了这个查询.. ALTER TABLE [stk020] ALTER COLUMN [t16] nvarchar(Max) not null [t16
我正在尝试将存储在 CONTEXT_INFO 中的 nvarchar 转换回。 declare @LanguageCode nvarchar(6) = 'en'; declare @binvar va
我是一名优秀的程序员,十分优秀!