Вопрос

Клиент, скомпилированный с помощью 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() и «изменить набор сеансов 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');

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

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

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

Это было полезно?

Решение

ваш столбец DATE_PROC — это ДАТА, вам следует всегда сравните это с датой и никогда полагаться на неявное преобразование данных.

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

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' потому что этот формат будет отсортирован как исходная дата.

Другие советы

Как вставлялись записи?

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

Вот пример:

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top