在查询中使用参数时,Oracle ORA-01858

时间:2018-09-18 07:15:34

标签: oracle timestamp oracle-sqldeveloper bind-variables

我有一个表,其中包含一个TIMESTAMP(6)类型的列,如果我尝试查询该表,只要不对其参数化,一切都很好。

这有效:

SELECT
  COUNT(*)
FROM
  t_data
WHERE
  DATA_TS >= TO_TIMESTAMP('13.09.18 11:30:00')
  AND   DATA_TS <= TO_TIMESTAMP('13.09.18 11:33:00');

但是,这与ORA-01858失败,该错误提供了如上所述的值,“在非预期的数字位置发现了数字”。 我还尝试使用NLS_PARAMETERS中的Mask格式将参数包装在TO_TIMESTAMP()中。

SELECT
  COUNT(*)
FROM
  t_data
WHERE
  DATA_TS >= TO_TIMESTAMP(:AStart,'DD.MM.RR HH24:MI:SSXFF')
  AND   DATA_TS <= TO_TIMESTAMP(:AEnd,'DD.MM.RR HH24:MI:SSXFF');

任何人都知道导致此问题的原因是什么?

测试用例: 创建表

create table t_data ( 
    data varchar2(80), 
    data_ts timestamp 
);

插入数据

Insert into t_data (data,data_ts) VALUES ('TEST', systimestamp);

使用&AStart代替:AStart可以很好地解决问题,

4 个答案:

答案 0 :(得分:2)

您不能使用TO_TIMESTAMP('13.09.18 11:30:00')作为绑定变量内容。 DBMS需要一个值,而不是代码。

因此,如果您的工具或编程语言允许,则可以传递时间戳或日期值,或者仅传递字符串'13.09.18 11:30:00'并在查询中包含TO_DATE(:AStart, 'dd.mm.rr hh24:mi:ss')

更新:在将字符串作为绑定变量传递时,请确保不包括引号。仅传递字符串内容(例如13.09.18 11:30:00,而不传递'13.09.18 11:30:00')。

答案 1 :(得分:1)

您应该在函数内部使用

SELECT   COUNT(*)
FROM  t_data
WHERE   DATA_TS >= TO_TIMESTAMP(:AStart)
  AND   DATA_TS <= TO_TIMESTAMP(:AEnd);

答案 2 :(得分:1)

真的是时间戳吗?因为,您发布的值对我来说好像普通日期。

无论如何:我相信您应该使用TO_TIMESTAMP并为参数值提供适当的格式掩码。不是您应该应用NLS设置格式掩码,而是键入该参数的值时所使用的掩码。

例如:

SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';

Session altered.

SQL> select sysdate from dual;

SYSDATE
-------------------
18.09.2018 10:07:57

SQL> select to_timestamp('&par_ts', 'dd.mm.yy hh24:mi:ss') result from dual;
Enter value for par_ts: 18.09.18 10:08:23

RESULT
---------------------------------------------------------------------------
18.09.18 10:08:23,000000000

SQL>

如果您传递了格式不同的参数,则格式掩码必须反映该更改:

SQL> select to_timestamp('&par_ts', 'mm-yyyy-dd hh24:mi:ss') result from dual;
Enter value for par_ts: 09-2018-18 10:10:15

RESULT
---------------------------------------------------------------------------
18.09.18 10:10:15,000000000

SQL>

这意味着您的查询应如下所示:

SELECT COUNT(*)
FROM  t_data
WHERE DATA_TS >= TO_TIMESTAMP(:AStart, 'dd.mm.yy hh24:mi:ss')
  AND DATA_TS <= TO_TIMESTAMP(:AEnd, 'dd.mm.yy hh24:mi:ss');

如有必要,修复格式掩码。

答案 3 :(得分:1)

感谢大家的贡献。我一直都走错路了。

在卸载我的旧版本的SQL Developer并安装了当前版本后,该问题消失了。我不知道是什么原因造成的,但是它已经解决了。

其结果是,我现在比以往更加了解时间和日期格式。

问候 Attix