【发布时间】: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。
-
感谢您的反馈,我已经更新了我原来的帖子。