我收到错误消息" ORA-01722:无效号码"当我执行我的查询。正如我所知,当我对期望varchar
的列使用数值时,我会得到该错误。
在我的情况下,我的查询有一个案例陈述,如
CASE WHEN CHAR_COLUMN= 1 THEN 'SOME VALUE' END
但是在同一个oracle版本的不同实例中,行为是不同的。相同的查询在我们的一个dev oracle服务器上工作,但在另一个中没有。我很好奇是否有任何配置允许oracle使用数值在字符列中使用。
PS: 我们使用的oracle版本是 Oracle Database 11g Express Edition版本11.2.0.2.0 - 64位生产
答案 0 :(得分:2)
我从不依赖implicit data type conversion,但始终明确指出:
CASE WHEN CHAR_COLUMN = TO_CHAR(1) THEN 'SOME VALUE' END
甚至根本不转换:
CASE WHEN CHAR_COLUMN = '1' THEN 'SOME VALUE' END
原因是Oracle倾向于将字符串转换为数字,而不是相反。请参阅链接手册页中的示例:
文字文字示例
文字文字' 10'数据类型为CHAR。如果它出现在数值表达式中,Oracle会将其隐式转换为NUMBER数据类型,如以下语句中所示:
SELECT salary + '10' FROM employees;
答案 1 :(得分:1)
create table foo (
CHAR_COLUMN varchar2(10)
);
create table bar (
CHAR_COLUMN varchar2(10)
);
insert into foo (CHAR_COLUMN) values ('1');
insert into foo (CHAR_COLUMN) values ('2');
insert into bar (CHAR_COLUMN) values ('1');
insert into bar (CHAR_COLUMN) values ('yellow');
然后,当查询数字1
时,第一个查询表工作,第二个查询表不工作:
select * from foo where CHAR_COLUMN = 1;
select * from bar where CHAR_COLUMN = 1;
当您要求Oracle解决此比较时:
WHEN CHAR_COLUMN = 1
... Oracle将查询内部转换为:
WHEN TO_NUMBER(CHAR_COLUMN) = 1
在我的例子中,这可以在解释计划中找到:
---------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
---------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 7 | 3 | 00:00:01 |
| * 1 | TABLE ACCESS FULL | FOO | 1 | 7 | 3 | 00:00:01 |
---------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 1 - filter(TO_NUMBER("CHAR_COLUMN")=1)