【问题标题】:Oracle whitespaces bugOracle 空格错误
【发布时间】:2017-11-07 17:44:50
【问题描述】:

当我们从一个数据库 (Oracle 11.2.0.3.0) 迁移到另一个数据库 (Oracle 11.2.4.0) 时,我注意到我们的 Oracle 数据库中有一个奇怪的错误。数据库服务器位于不同的数据中心,具有不同的操作系统和支持团队。所以改变的不仅仅是版本。

所以,这就是我面临的错误:当我执行这个小 SQL 语句时,我得到了不同的结果:

SELECT 'hello' FROM DUAL;

在旧数据库上,输出为:"hello"
在新数据库上,输出为:"hello "

这些空格是从哪里来的?

更新:

我在版本 12.10.0.30 中使用 TOAD for Oracle。

我已经检查了这两个数据库的参数,但找不到任何差异(当然版本除外):

SELECT * FROM V$VERSION;
SELECT * FROM v$nls_parameters;
SELECT * FROM nls_session_parameters;
SELECT * FROM nls_instance_parameters;
SELECT * FROM nls_database_parameters;

然后我检查了这个并没有发现任何差异:

DESC DUAL;

我做的下一个测试是:

SELECT dummy FROM DUAL;

两个数据库的结果都是:X

下一个测试:

SELECT '|' || 'hello' || '|' FROM DUAL;

结果旧数据库:"|hello|"
结果新数据库:"|hello| "

还有一个测试:

SELECT '|' || dummy || '|' || 'Hello' || '|' FROM DUAL;
SELECT '|' || dummy || '|' FROM DUAL;
SELECT '|' || 'Hello' || '|' FROM DUAL;

结果:
"|X|Hello|"
"|X|"
"|Hello| "
有趣的是,它适用于第一个 SQL,但第三个又被空格填充了。

SQL*Plus

我在运行 TOAD 的同一台笔记本电脑上安装了 SQL*Plus。
旧数据库:

SQL> select dummy from dual;
D
-
X
SQL> select 'dummy' from dual;
'DUMM
-----
dummy
SQL> SELECT dump('hello') FROM DUAL;
DUMP('HELLO')
---------------------------------
Typ=96 Len=5: 104,101,108,108,111

新数据库:

SQL> select dummy from dual;
D
-
X
SQL> select 'dummy' from dual;
'DUMMY'
--------------------------------
dummy
SQL> SELECT dump('hello') FROM DUAL;
DUMP('HELLO')
--------------------------------------------------------------------------------
Typ=96 Len=5: 104,101,108,108,111

解决方案

数据库参数 *.cursor_sharing 在旧数据库上为“EXACT”,在新数据库上为“FORCE”。因此,我们也必须将其更改为“EXCACT”。

【问题讨论】:

  • 空格可能在您的应用程序中。试试select '|' || 'hello' || '|' from dual
  • 你是如何运行查询的?
  • 解释 Gordon 和 Kaushik 的 cmets:如果您使用 SQL Developer 或 Toad 等前端应用程序,他们可能会添加空格,而不是 Oracle 数据库。 (SQL Developer 和 Toad 没有这样的事情,但我们不知道您实际上在做什么)。 Gordon 建议的查询将证明,如果添加了任何空格,则在结束管道字符 (|) 之后添加了任何空格 - 您仍然不会知道是谁在这样做,但您会知道“你好”没有任何问题。该填充很可能来自声明为 CHAR(20) 或类似的列,而不是 VARCHAR2。
  • 尝试:desc dual;这应该指向 sys.dual。
  • 感谢您的反馈,我已经更新了我原来的帖子。

标签: sql oracle oracle11g


【解决方案1】:

不知何故,文字字符串 hello 被解释为 CHAR(26) 数据类型(将用空格填充,长度为 26 个字符)而不是 VARCHAR2(4000) 数据类型。由于您是从DUAL 表中选择的,因此在您发出查询的环境变量或工具中一定有些奇怪。

【讨论】:

  • 感谢您的反馈,我已经更新了我原来的帖子。
【解决方案2】:

只是弄乱了这个,发现如果你弄乱了客户端上的 NLS_LANG 设置(来自 linux,Windows 可能相同)我会得到不同的结果(至少在它显示时):

  1. 没有设置 NLS_LANG 环境变量:

SQL> 从对偶中选择“你好”;

'HELL
-----
hello
  1. 导出 NLS_LANG=American_America.UTF8

SQL> 从对偶中选择“你好”;

'HELLO'
---------------
hello

我猜它与多字节字符集有关,但请注意,两者的长度函数仍然返回 5。

因此请检查您的新设置以确保您的 NLS 设置正确。

希望对您有所帮助。

编辑

我登录 Oracle 以运行您的 liveSQL 测试,但没有看到您看到的间距。我想你可能会在下载后在 Excel 中打开 csv。我在文本编辑器 (V) 中打开并转储了您给出的示例的十六进制,该示例应该有填充,但它没有:

00000000  27 7C 27 7C 7C 27 48 45 4C 4C 4F 27 7C 7C 27 7C    '|'||'HELLO'||'|
00000010  27 0A 7C 68 65 6C 6C 6F 7C 0A                      '.|hello|.    

上面的点是换行符(0A)。我找不到任何空白填充。

您的问题不可重现(至少在我的环境或 liveSQL 中不可重现)。

【讨论】:

  • 感谢您的反馈,我已经更新了我原来的帖子。
  • 感谢您更新您的帖子。所以你的客户对所有测试都是一样的? (所有测试在同一台机器上运行相同的 Toad)
  • 是的,所有测试都是同一个客户端。同时我很确定自 11.2.0.4.0 以来存在一个错误,因为我可以在 Oracles LiveSQL 上重现该错误。
  • 真的很抱歉,这是我的错,在直播系统上无法重现...不知道我在编辑器中看到了什么,也许是时候休息一下了,抱歉!
  • 好吧,这发生在我们所有人身上!如果我的回答对您有帮助,请采纳,谢谢
猜你喜欢
  • 2012-12-13
  • 1970-01-01
  • 1970-01-01
  • 2016-07-18
  • 2012-06-24
  • 2014-11-21
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
相关资源
最近更新 更多