【问题标题】:Entering special characters fails in Oracle table在 Oracle 表中输入特殊字符失败
【发布时间】:2012-01-09 21:22:44
【问题描述】:

我需要测试我的应用程序是否正在从数据库中读取特殊字符并以完全相同的方式显示它们。为此,我需要使用所有可用的特殊字符填充数据库表。但是,我不确定如何在 sql 插入查询中指定特殊字符。谁能指导我一个可以在查询中插入特殊字符的示例?为简单起见,假设该表是 City 表,其中 Area 和 Avg_Temperature 为 2 列。如果我需要在 Avg_Temperature 列中插入度数(摄氏度/远海特)符号,我应该如何编写查询?


*[编辑于 2012 年 1 月 9 日下午 2:50 EST]*根据 Justin Cave 下面的建议,我做了以下分析:

表:create table city(area number, avg_temperature nvarchar2(10));

日期:insert into city values (1100, '10◦C');

Query:
select dump(avg_temperature, 1010) from city where area = 1100;

O/P
DUMP(AVG_TEMPERATURE,1010)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
----------------------------------------------------------
Typ=1 Len=8 CharacterSet=AL16UTF16: 0,49,0,48,0,191,0,67                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              

Query
select value$ from sys.props$ where name='NLS_CHARACTERSET';

O/P
VALUE$
----------------
WE8MSWIN1252

Query:
select value$ from sys.props$ where name='NLS_NCHAR_CHARACTERSET';

O/P
----------------
AL16UTF16

似乎插入确实像 Justin Cave 所建议的那样弄乱了特殊字符。但我无法理解为什么会这样?谁能提供相关建议?

【问题讨论】:

  • 什么是数据库字符集?什么是国家字符集?您是否将数据加载到 VARCHAR2 列中?还是 NVARCHAR2 列?该字符是否存在于数据库字符集中?
  • @JustinCave:数据库字符集:WE8MSWIN1252;全国 CS:AL16UTF16。我会将数据加载到 NVARCHAR2 中。我不确定该字符是否存在于字符集中!我被告知要在现有数据库中构建 applcn,因此我想确保不会遇到这些问题。你能指导我在哪里可以找到上述字符集允许的字符
  • @darkie15:在使用包含人类已知的几乎所有字符的 UTF16 时,您应该不会遇到问题。真正的问题是从客户端到服务器的传输(以及所有中间步骤,如导入文件、网页、电子邮件……)
  • @darkie15 - 维基百科等有一个 Windows-1252 字符集 en.wikipedia.org/wiki/Windows-1252 的字符映射表,它将显示数据库字符集中的有效字符。
  • 好的。所以我只是在包含度数符号的数据库表中添加了一行,即INSERT INTO CITY(Area, Avg_Temparature) VALUES (1100, '10◦C');正在使用的 SQL 客户端是 Oracle SQL Developer。查看表格内容时,带有度数符号的温度列的值显示不正确。我检查了 SQL Developer 的编码,它是 UTF8。是不是输入特殊字符时数据库编码乱了?

标签: sql unicode oracle11g special-characters


【解决方案1】:

首先,您不应将符号存储为列的一部分。这要求您将列声明为 VARCHAR 从长远来看会给您带来很多问题(例如,您不能对它们进行 sum(),不能对它们进行 avg() 等等)

您应该将获取温度的单位存储在第二列中(例如 1 = 摄氏度和 2 = 华氏度),并在前端显示数据时对其进行转换。如果您真的想存储符号,请将单位列声明为 CHAR(1):

CREATE TABLE readings
(
    area               number(22),
    avg_temperature    number(10,3),
    units              varchar(2)
)

那么就可以这样插入了:

INSERT INTO readings 
 (area, avg_temperature, units)
VALUES 
 (1000, 12.3, '°C');

但同样:我不建议存储实际符号。只存储代码!

【讨论】:

  • 感谢您的建议,但问题是度数符号只是一个示例。我们实际上是从客户端接收这些数据,它包含许多特殊字符(包括度数符号)。我不确定您的解决方案是否适合实际情况。
  • 那么真正的问题是什么?我向您展示了如何插入度数符号的示例。
【解决方案2】:

首先你需要知道数据库字符集是什么。然后你需要知道你的“客户端”连接使用的是什么字符集。如果这些都相同,生活总是会更轻松。

如果您的数据库是 utf-8 而您的客户端是 utf-8,那么您不需要进行任何字符转义,您只需对所需字符使用 utf-8 编码即可。

在您的示例中,度数字符是 unicode 代码点 u+00b0。

在 utf-8 中,这是一个两字节序列:x'c2', x'b0'。

【讨论】:

  • "输入特殊字符时是不是数据库编码搞错了?"不完全是。根据您上面的信息,您在数据库级别使用 Windows-1252 字符集编码 - 此字符集由最多 256 个字符组成,0-127 是标准 ASCII 集,128-255 由代码页定义定义。如果您的 SQLDEVELOPER 客户端设置为使用 UTF-8 编码,则它使用 UNICODE 字符集(数千个字符),具有 1 字节、2 字节、3 字节或 4 字节编码(取决于字符)。
  • 续 -- 标准 ASCII 字符 (0-127) 在 UNICODE 中是相同的(并且在 UTF-8 中编码为单个字节)与在 Windows-1252 字符集中,所以这就是为什么一切正常,直到您尝试存储非 ASCII 字符。将您的 SQLDeveloper“环境”编码切换到 windows-1252——你应该没问题,因为数据库和客户端都将以相同的方式编码字符。最终,您需要询问您的客户他们的数据采用何种编码方式,以确保数据库能够支持它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-04
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多