Oracle substr(),隐式转换?

时间:2015-10-23 09:22:54

标签: sql oracle substr

我遇到了Oracle SQL substr()函数的问题。

看起来substr()的行为超出了其声明的目的,因此,

substr(some.field, 0, 7) <> '1598200'

,其中

some.field = '1598200, 123456'

在这里开始玩,

select sum(t.amount)
from ivtransaction t
inner join ivpaymentreminders p on p.transactionid = t.transactionid
left join ivinvoice i on i.invoiceid = t.invoiceid
where substr(p.collectiveinvoiceno, 0, 7) = '1598200'

p.collectiveinvoiceno中,预计会有4条记录出现:

rownum | p.collectiveinvoiceno
---------------------------------
1      | 1598200
2      | 1598200
3      | 1598200, 123456
4      | 1598200, 456789

但只有第1行和第2行出现并添加到sum(t.amount)

  • 单独测试时,substr(p.collectiveinvoiceno, 0, 7)会提取正确的值
  • 使用to_char转换参数的左侧和右侧没有区别

这是某种隐式转换吗?如果是这样,如何解决?

感谢任何想法,

英格丽

编辑:事实证明,substr(field,1,7)比较并没有捕获4/4行,因为目标字符串位于第3和第4行的后面,而不是前导。我被骗了,因为在应用程序中,目标字符串显示为领先!我是一名初学者,所以无论如何这都非常有用,感谢您的所有投入。英格丽

1 个答案:

答案 0 :(得分:1)

  

substr(p.collectiveinvoiceno,0,7)

SUBSTR 中使用0作为开始位置是一种不好的做法,您应该使用1。虽然,文档说明:

  

如果position为0,则将其视为1。

过滤谓词中的SUBSTR没有问题,它将获取所有4行。

SQL> WITH DATA AS(
  2  SELECT '1598200' str FROM dual UNION ALL
  3  SELECT '1598200' FROM dual UNION ALL
  4  SELECT '1598200, 123456' FROM dual UNION ALL
  5  SELECT '1598200, 456789' FROM dual
  6  )
  7  SELECT str, substr(str, 1, 7) FROM DATA
  8  WHERE substr(str, 1, 7) = '1598200';

STR             SUBSTR(
--------------- -------
1598200         1598200
1598200         1598200
1598200, 123456 1598200
1598200, 456789 1598200

不需要使用 TO_CHAR ,因为您已经在两侧都有字符串数据类型。因此,毫无疑问隐式数据类型转换。查看解释计划

SQL> select * from table(dbms_xplan.display);

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------
Plan hash value: 560839587

-------------------------------------------------------------------------
| Id  | Operation        | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------
|   0 | SELECT STATEMENT |      |     4 |    36 |     8   (0)| 00:00:01 |
|   1 |  VIEW            |      |     4 |    36 |     8   (0)| 00:00:01 |
|   2 |   UNION-ALL      |      |       |       |            |          |
|   3 |    FAST DUAL     |      |     1 |       |     2   (0)| 00:00:01 |
|   4 |    FAST DUAL     |      |     1 |       |     2   (0)| 00:00:01 |
|   5 |    FAST DUAL     |      |     1 |       |     2   (0)| 00:00:01 |

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------
|   6 |    FAST DUAL     |      |     1 |       |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------

13 rows selected.
  

但只有第1行和第2行出现并加入sum(t.amount)

取决于 JOIN 条件。文件管理器谓词工作正常。