Странность в SQL под Oracle

Программирование на Атлантисе (VIP, FCOM, ARD), FastReport

Модераторы: m0p3e, edward_K, Модераторы

Ответить
АлександерK
Посетитель
Сообщения: 36
Зарегистрирован: 28 сен 2009, 00:19

Странность в SQL под Oracle

Сообщение АлександерK »

Здрасьте всем, пишем внешний софт, при этом часть данных берем из "Галактики" прямым нормальным oracle-овым SQL-ем

Запрос:
select katsopr.fnsopr, gal.to_oradate(katsopr.fdsopr) from gal.katsopr
where KATSOPR.fnsopr ='000315' and katsopr.fvidsopr=600 and gal.to_oradate(katsopr.fdsopr)=to_date('27.01.2010')
отрабатывается корректно и выводит данные,

а вот аналогичный запрос:
select katsopr.fnsopr, gal.to_oradate(katsopr.fdsopr) from gal.katsopr
where KATSOPR.fnsopr ='697' and katsopr.fvidsopr=201 and gal.to_oradate(katsopr.fdsopr)=to_date('18.12.2009')

выдает ошибку:
SQL Error: ORA-01847: день месяца должен быть в диапазоне от 1 до последнего дня месяца
ORA-06512: на "GAL.TO_ORADATE", line 1
01847. 00000 - "day of month must be between 1 and last day of month"

Разница только в значении vidsopr
может кто сталкивался с подобным, как лечить?
Nikos
Местный житель
Сообщения: 577
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Томск

Сообщение Nikos »

Сталкивался с аналогичным. Дело было в том, что GAL.TO_ORADATE не мог преобразовать какие-то даты, по-моему нулевые, уже не помню. Пришлось написать свою аналогичную функцию, где есть проверка и пользоваться ей

Код: Выделить всё

 (DATETIME INTEGER) RETURN DATE AS  MM INTEGER; YY INTEGER; TMP INTEGER; RESULT DATE;
 BEGIN
   if DATETIME = 0 THEN
     RESULT := TO_DATE(TO_CHAR(1)||'.'||TO_CHAR(1)||'.'||TO_CHAR(1900),'DD.MM.YYYY');
   END IF;
   if DATETIME <> 0 THEN
       YY := DATETIME / 65536;
       TMP := MOD(DATETIME,65536);
       MM := TMP / 256;
       TMP := MOD(TMP,256);
       RESULT := TO_DATE(TO_CHAR(TMP)||'.'||TO_CHAR(MM)||'.'||TO_CHAR(YY),'DD.MM.YYYY');
   END IF;
   RETURN RESULT;
 END;
galover
Местный житель
Сообщения: 794
Зарегистрирован: 16 ноя 2007, 13:52

Сообщение galover »

Код: Выделить всё

select katsopr.fnsopr, gal.to_oradate(katsopr.fdsopr) from gal.katsopr
where KATSOPR.fnsopr ='697' and katsopr.fvidsopr=201 and 
decode(katsopr.fdsopr, 0, to_date('00.00.0000', 'DD.MM.YYYY'), gal.to_oradate(katsopr.fdsopr)) = to_date('18.12.2009', 'DD.MM.YYYY');
АлександерK
Посетитель
Сообщения: 36
Зарегистрирован: 28 сен 2009, 00:19

Сообщение АлександерK »

Всем спасибо, пошли пробовать :)
Иван
Местный житель
Сообщения: 200
Зарегистрирован: 28 апр 2009, 13:19
Откуда: Новороссийск

Сообщение Иван »

а я тупо поставил перехватчик исключений и в случае ошибки возвращал типа 01.01.1900
Прохожий
Постоянный обитатель
Сообщения: 134
Зарегистрирован: 23 мар 2007, 05:38
Откуда: Дальний Восток, Хабаровск
Контактная информация:

Re: Странность в SQL под Oracle

Сообщение Прохожий »

Привет всем.

Чтоб не даблпостить, апну тему.

Задача - выдернуть людей, переведенных в другое подразделение на предыдущей неделе. Отчет формируется во вторник. Запрос:

Код: Выделить всё

select p.ffio, gala.to_oradate(ap.fappointdate) from gala.persons p, gala.appointments ap, gala.contdoc cd, gala.attrval av, gala.x$users xu
where ap.fappointdate!=0
      and p.ftabnmb=av.fvdouble
      and av.fwtable=6
      and ap.fperson=p.fnrec 
      and ap.fccont=cd.fnrec 
      and cd.ftypeoper=5
      and av.fcrec=xu.atl_nrec
      and bitand(power(2,3),xu.xu$flag)=0
      and 
      (
      GALA.TO_ORADATE(AP.FAPPOINTDATE) >= sysdate-8
      and 
      GALA.TO_ORADATE(AP.FAPPOINTDATE) <= sysdate-4
      )
      ;
выдает ошибку:
ORA-01847: day of month must be between 1 and last day of month
ORA-06512: at "GALA.TO_ORADATE", line 1
01847. 00000 - "day of month must be between 1 and last day of month"
*Cause:
*Action:
Заморочка в двух последних условиях по дате. Но, интересный момент. Каждое условие отдельно от другого отрабатывает корректно. А вместе - никак. Почему так?
Галактика 8.10, Oracle 10g patch 10.2.0.4
edward_K
Заслуженный деятель интернет-сообщества
Сообщения: 5187
Зарегистрирован: 29 мар 2005, 17:49
Откуда: SPB galaxy spb

Re: Странность в SQL под Oracle

Сообщение edward_K »

я бы все таки использовал inner join и есть такая функция COALESCE или нужно писать CASE для проверки на валидность. Логично будет, если главной будет таблица назначений - добавьте еще проверку person=0, чтобы отсечь записи в не утвержденных приказах..
m0p3e
Местный житель
Сообщения: 1386
Зарегистрирован: 29 мар 2005, 17:49
Откуда: Москва

Re: Странность в SQL под Oracle

Сообщение m0p3e »

Не может int в дату разгрести на составляющие. У меня запрос отрабатывает :) Следовательно есть какая-то запись корявенькая.
Кстати sysdate возвращает дату со временем. Правильнее trunc(sysdate).
Прохожий
Постоянный обитатель
Сообщения: 134
Зарегистрирован: 23 мар 2007, 05:38
Откуда: Дальний Восток, Хабаровск
Контактная информация:

Re: Странность в SQL под Oracle

Сообщение Прохожий »

Выкрутился. Не дату назначения конвертил в ORADATE, а sysdate сконвертил в ATLDATE.
Галактика 8.10, Oracle 10g patch 10.2.0.4
Ответить