首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >关于to_char和to_number的混淆

关于to_char和to_number的混淆
EN

Stack Overflow用户
提问于 2021-07-06 08:28:11
回答 2查看 239关注 0票数 2

首先,我了解基本知识。

select to_number('A231') from dual; --这是行不通的,但是

select to_char('123') from dual;

select to_number('123') from dual;--这也能起作用

实际上,在我的包中,我们有两个表-- A(X number)和B(Y varchar) --有很多列,但是我们只担心XYX只包含数值,如123,456等,而Y包含一些string和一些number,例如'123','HR123','Hello'。我们得把这两张桌子连接起来。它的遗留应用程序使我们无法更改表和列。在此之前,下面的条件是正常工作的。

代码语言:javascript
运行
复制
to_char(A.x)=B.y;

但是由于Y上有索引,性能团队建议我们执行在dev env中运行的A.x=to_number(B.y);

我的问题是,在任何情况下,这个查询会产生错误吗?如果它选择'123',它肯定会给123。但如果它选择'AB123',那么它就会失败。它会失败吗?即使在加入其他'AB123'时,它也能选择table吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-07-06 08:43:11

它会失败吗?

是。它必须将每一行都放在TO_NUMBER中,然后才能检查它是否符合筛选条件。因此,如果有任何一行它将失败,那么它总是会失败的。

甲骨文12.2 (因为您标记了Oracle 12),您可以使用:

代码语言:javascript
运行
复制
SELECT *
FROM   A
       INNER JOIN B
       ON (A.x = TO_NUMBER(B.y DEFAULT NULL ON CONVERSION ERROR))

或者,将索引放在TO_CHAR(A.x)上并使用原始查询:

代码语言:javascript
运行
复制
SELECT *
FROM   A
       INNER JOIN B
       ON (TO_CHAR(A.x) = B.y)

还要注意:在B.y上建立索引并不意味着将使用该索引。如果您正在对TO_NUMBER(B.y)进行筛选(无论是否存在转换错误的默认值),那么您将需要在您正在使用的函数TO_NUMBER(B.Y)上建立一个基于函数的索引。您应该分析查询并检查解释计划,以查看索引的使用是否有任何改进或更改。

票数 3
EN

Stack Overflow用户

发布于 2021-07-06 08:42:53

永远不要转换可以包含非数字字符串VARCHAR2to_number列。

这可能部分奏效,但最终还是会失败的。

小型示例

代码语言:javascript
运行
复制
create table a as
select rownum X from dual connect by level <= 10;

create table b as
select to_char(rownum) Y from dual connect by level <= 10
union all
select 'Hello' from dual;

这可以工作(因为您限制了行,以便转换工作;如果幸运的话,Oracle选择正确的执行计划;这是可能的,但不受保护;)

代码语言:javascript
运行
复制
select * 
from a
join b on A.x=to_number(B.y)
where B.y =  '1';

但这将使失败

代码语言:javascript
运行
复制
select * 
from a
join b on A.x=to_number(B.y)

ORA-01722: invalid number

性能

但由于有Y指标,绩效团队建议我们做A.x=to_number(B.y);

您应该对团队进行访问,就好像不能使用列(to_number(B.y))索引上的函数一样。

相反,您的原始查询可以完美地使用以下索引:

代码语言:javascript
运行
复制
create index b_y on b(y);
create index a_x on a(x);

查询

代码语言:javascript
运行
复制
select * 
from a
join b on to_char(A.x)=B.y
where A.x = 1;

执行计划

代码语言:javascript
运行
复制
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     5 |     1   (0)| 00:00:01 |
|   1 |  NESTED LOOPS     |      |     1 |     5 |     1   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN| A_X  |     1 |     3 |     1   (0)| 00:00:01 |
|*  3 |   INDEX RANGE SCAN| B_Y  |     1 |     2 |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------

 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("A"."X"=1)
   3 - access("B"."Y"=TO_CHAR("A"."X"))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68267070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档