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

问题描述 投票:0回答:4

我有一个包含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 
);

插入DATA

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

使用&AStart而不是:AStart运行良好,如果这有助于某人

oracle timestamp oracle-sqldeveloper bind-variables
4个回答
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
投票

你应该在函数中使用param

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

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');

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


1
投票

谢谢大家的贡献。我一直在错误的轨道上。

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

结果是我现在比以前更多地了解时间和日期格式。

关心Attix

© www.soinside.com 2019 - 2024. All rights reserved.