Oracle OCI: запрос с полем даты - PullRequest
2 голосов
/ 15 января 2010

Клиент, скомпилированный с OCI: 10.2.0.4.0
Сервер: Oracle9i Enterprise Edition, выпуск 9.2.0.4.0

Проблемный запрос:

SELECT CODIGO FROM LOG WHERE TEL = :telnumber AND DATE_PROC = '05-JUL-08'

Описание таблицы:

SQL>describe LOG;

TEL NOT NULL VARCHAR2(15)
CODIGO NOT NULL VARCHAR2(20)
DATE_PROC NOT NULL DATE

Как бы просто это не выглядело, при выполнении непосредственно на сервере с SQLPlus он возвращает результат, но при выполнении из приложения, использующего OCI, этот запрос возвращает OCI_NO_DATA всегда . В начале значение даты также было заполнителем, но я обнаружил, что даже предоставление литерала типа '05-JUL-08' не работает. Я пробовал следующее:

  • Я попробовал основы: запрос базы данных от клиента работает. Это то, что доставляет мне неприятности
  • Работает следующее:

    SELECT CODIGO FROM LOG WHERE TEL = :telnumber
    
  • Выполнение ALTER SESSION SET NLS_DATE_FORMAT="DD-MM-YYYY"; перед запросом как на сервере, так и на клиенте. Тот же результат: сервер возвращает данные, клиент OCI_NO_DATA

  • Попробовал изменить DATE_PROC формат, сочетая это с использованием TO_DATE(). Тот же результат.
  • Искал, искал, искал. Нет ответа

Я немного отчаянно нуждаюсь в поиске ответа, буду признателен за любую помощь и могу предоставить столько дополнительной информации, сколько потребуется. Спасибо.

--- Дополнительная информация ---

update log set DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS') where CODIGO='BancoOne';

Я пробовал разные комбинации, используя trunc () и "alter session set nls_date_format" ... и вот что я получаю:

SELECT CODIGO FROM LOG WHERE TEL = 11223344 AND DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS');

На сервере: Возвращает: "BancoOne" (хорошее значение)
В приложении OCI: Возвращает OCI_NO_DATA

SELECT CODIGO FROM LOG WHERE TEL = 11223344 AND trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');

На сервере: Возвращает: "BancoOne"
В приложении OCI: возвращает «BancoOne»

Итак, почему приложение OCI дает разные результаты, если оба обращаются к одному и тому же серверу БД?

Также, чтобы уточнить назначение приложения OCI: у него есть запрос, который должен быть настроен пользователем. Идея состоит в том, что пользователь будет адаптировать запрос по своему усмотрению, чтобы он соответствовал полю Date, присутствующему в целевой БД, поэтому я не должен включать в свой код операторы «alter session set nls_date_format», поскольку я не буду знать формат даты. Таким образом, я хочу предоставить пользователю гибкость и не полагаться на конкретные форматы даты. Имеет ли это смысл? Есть предложения?

Ответы [ 4 ]

2 голосов
/ 15 января 2010

ваш столбец DATE_PROC - это DATE, вы должны всегда сравнивать его с датой и никогда полагаться на неявное преобразование данных.

Попробуйте это:

SELECT CODIGO FROM LOG WHERE TEL = :telnumber AND DATE_PROC = DATE '2008-07-05'

или это:

SELECT CODIGO 
  FROM LOG 
 WHERE TEL = :telnumber 
   AND DATE_PROC = to_date('05-JUL-08', 'DD-MON-RR')

Если вы можете, воздержитесь от использования формата даты в вашем коде , который использует буквы в течение нескольких месяцев (поскольку код потерпит неудачу при изменении языка по умолчанию) и только двух символов на годы (двусмысленность века). Мне нравится использовать 'YYYY/MM/RR', потому что этот формат будет отсортирован как исходная дата.

0 голосов
/ 26 апреля 2013

Мы только что получили эту ошибку (OCI_NO_DATA), вызванную тем, что кто-то меняет время суток на своем компьютере Когда они вернули дату / время назад к нужному времени, приложение начало работать нормально.

0 голосов
/ 18 января 2010

Я бы сказал, что вы задаете неправильный вопрос.

Oracle полагается на совместное использование SQL для повышения производительности, и когда вы вставляете строку, например «20080705», SQL не может быть разделен. Подробности здесь .

Таким образом, значение данных должно быть заполнителем и должно иметь правильный тип данных (DATE). Пример здесь должен помочь сделать это.

Тем не менее, если это работает

SELECT CODIGO FROM LOG 
WHERE TEL = 11223344 AND 
trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');

но это не

SELECT CODIGO FROM LOG 
WHERE TEL = 11223344 
AND DATE_PROC = TO_DATE('20080705162918', 'YYYYMMDDHH24MISS');

Я бы попробовал

SELECT TO_CHAR(DATE_PROC,'DD-MM-YYYY HH24:MI:SS') FROM LOG 
WHERE TEL = 11223344 AND 
trunc(DATE_PROC) = TO_DATE('20080705', 'YYYYMMDD');
0 голосов
/ 15 января 2010

Как были вставлены записи?

Поля даты хранят информацию о времени, поэтому при вставке записей с использованием sysdate поле даты будет содержать различные «значения» для записей в течение этого дня. Когда вы выполняете date_proc = '05 -JUL-08 ', вы говорите, что date_proc в точности соответствует 5 июля 2008 года в 12:01:00. Если вы вставили запись в 12:01 с помощью sysdate, она не будет возвращена. Вы пробовали использовать между или усечением?

Вот пример:

drop table test_date;
create table test_date (id number, ud date);

insert into test_date values (1, '15-jan-10');
insert into test_date values (2, '15-jan-10');
insert into test_date values (3, '15-jan-10');
insert into test_date values (6, sysdate);    -- sysdate as of writing is 15-JAN-2010 08:01:55
insert into test_date values (7, sysdate);    -- sysdate as of writing is 15-JAN-2010 08:01:55
insert into test_date values (8, '16-jan-10');
commit;

select id, ud, to_char(ud, 'dd-MON-yyyy HH:MM:SS') from test_date where ud = '15-jan-10';
---------------------- ------------------------- --------------------
1                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
2                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
3                      15-JAN-10                 15-JAN-2010 12:01:00      

select id, ud, to_char(ud, 'dd-MON-yyyy HH:MM:SS') from test_date where trunc(ud) = '15-jan-2010';
---------------------- ------------------------- --------------------
1                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
2                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
3                      15-JAN-10                 15-JAN-2010 12:01:00                                                        
6                      15-JAN-10                 15-JAN-2010 08:01:55                                                        
7                      15-JAN-10                 15-JAN-2010 08:01:55
...