Oracle ORA-01858 при использовании параметров в запросе - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть таблица, которая содержит столбец типа 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 «не числовой символ был найден там, где ожидалось число», предоставляя значения, как указано выше.Я также пытался обернуть параметры в TO_TIMESTAMP (), используя формат Mask из NLS_PARAMETERS.

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 работает хорошо, если это кому-то помогает

Ответы [ 4 ]

0 голосов
/ 18 сентября 2018

Спасибо всем за ваш вклад. Я все время был на неправильном пути.

После удаления моей старой версии SQL Developer и установки текущей, проблема исчезла. Я не знаю, что вызвало это, но это было исправлено.

В результате я теперь знаю больше о форматировании времени и даты, как и раньше.

С уважением ATTIX

0 голосов
/ 18 сентября 2018

Это действительно отметка времени? Потому что опубликованные вами значения выглядят как обычные даты для меня.

В любом случае: я считаю, что вы должны использовать 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');

Исправьте маску формата, если необходимо.

0 голосов
/ 18 сентября 2018

Вы не можете использовать TO_TIMESTAMP('13.09.18 11:30:00') в качестве содержимого переменной привязки. СУБД ожидает значение, а не код.

Таким образом, вы либо передадите метку времени или значение даты, если ваш инструмент или язык программирования это позволят, либо вы передадите только строку '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').

0 голосов
/ 18 сентября 2018

Вы должны использовать param внутри функции

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