Страница 1 из 1

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

Добавлено: 03 фев 2010, 14:55
Александер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
может кто сталкивался с подобным, как лечить?

Добавлено: 03 фев 2010, 16:38
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;

Добавлено: 03 фев 2010, 17:07
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');

Добавлено: 04 фев 2010, 14:38
АлександерK
Всем спасибо, пошли пробовать :)

Добавлено: 16 фев 2010, 21:26
Иван
а я тупо поставил перехватчик исключений и в случае ошибки возвращал типа 01.01.1900

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

Добавлено: 01 авг 2013, 10:21
Прохожий
Привет всем.

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

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

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

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:
Заморочка в двух последних условиях по дате. Но, интересный момент. Каждое условие отдельно от другого отрабатывает корректно. А вместе - никак. Почему так?

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

Добавлено: 01 авг 2013, 10:51
edward_K
я бы все таки использовал inner join и есть такая функция COALESCE или нужно писать CASE для проверки на валидность. Логично будет, если главной будет таблица назначений - добавьте еще проверку person=0, чтобы отсечь записи в не утвержденных приказах..

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

Добавлено: 01 авг 2013, 11:03
m0p3e
Не может int в дату разгрести на составляющие. У меня запрос отрабатывает :) Следовательно есть какая-то запись корявенькая.
Кстати sysdate возвращает дату со временем. Правильнее trunc(sysdate).

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

Добавлено: 06 авг 2013, 07:17
Прохожий
Выкрутился. Не дату назначения конвертил в ORADATE, а sysdate сконвертил в ATLDATE.