2015-06-29 3 views
0

Я довольно новичок в SQL, но все еще написал несколько запросов, которые очень похожи на тот, который я пишу сейчас. По какой-либо причине, когда я запускаю этот запрос, мне возвращается ошибка «ORA-01821: формат даты не распознан». Я посмотрел на это и осмотрелся здесь, в Stack и других местах, и я считаю, что мой синтаксис имеет смысл, поэтому я смущен тем, почему у меня возникла ошибка.Oracle Date Format Mystery - Почему это не приемлемый формат?

Мой запрос работает в зависимости от того, в какой день месяца он находится. Если это первый, он должен работать в течение 15-го числа предыдущего месяца. Если это 16-й, он должен работать в течение 1-го 15-го числа текущего месяца.

Это мой код, когда это первый день месяца:

select 
case 
    when to_char(sysdate, 'yyyymmdd') = to_char(sysdate, 'yyyymm' || '01') then (do a lot of things) 
    . 
    . 
    . 
end as FirstReportGroup 
where *datetable* between between to_char(sysdate, 'yyyymm' || '16') and to_char(last_day(sysdate), 'yyyymmdd'); 

и это мой код, когда это шестнадцатый:

select 
case 
    when to_char(sysdate, 'yyyymmdd') = to_char(sysdate, 'yyyymm' || '16') then (do a lot of things again) 
    . 
    . 
    . 
end as SecondReportGroup 
where *datetable* between to_char(sysdate, 'yyyymm' || '01') and to_char(sysdate, 'yyyymm' || '15') 

Он должен быть какой-то синтаксической ошибки форматирования даты, которую я просто не вижу. Я был бы очень признателен за помощь здесь, и я с нетерпением жду этого! Дайте мне знать, если вам нужна дополнительная информация.

Спасибо.

+0

sysdate - какой тип данных по сравнению с to_char? (дата для символа правильная?) Вам нужно сравнить, как типы данных, чтобы начать. – xQbert

+0

О, ну, глупая ошибка. Я просто изменил sysdate на: to_char (sysdate, 'yyyymmdd) и исправил эту проблему. Тем не менее, все еще не удается увидеть мою синтаксическую ошибку с форматом даты. – rtoken

+0

ошибка вызвана '01' и '16', это не допустимый формат для инструкции to_char, поэтому, если вы хотите получить этот день, вы должны использовать 'to_char (sysdate, 'dd')'. Это возвращает часть дня – Aramillo

ответ

1

Две проблемы

  • сравнить, как тип данных, чтобы дата на оба или шнурок на оба, но не даты и строки
  • два to_char работает только на сегодняшний день, так что вы должны to_char(sysdate, 'yyyymm') || '16' вместо этого как to_char работает только на дату, вы соглашаетесь с строкой, которая недействительна для функции to_char. так что сделайте это после функции.
+0

Я исправил ваш первый пункт, прежде чем вы ответили, но я ценю ваше продолжение независимо. Что касается вашего второго момента, да, это была проблема. Очень маленькая проблема, как обычно - спасибо, что указали! Я проверю и вернусь. – rtoken

0

Возможно, вам удастся просто получить один запрос, используя оператор case для генерации дат начала и окончания в предложении where. Вот пример из утверждений дела:

with dts as (select sysdate dt from dual union all 
      select to_date('02/06/2014 15:09:23', 'dd/mm/yyyy hh24:mi:ss') dt from dual)  
select dt, 
     case when dt - trunc(dt, 'mm') < 16 then add_months(trunc(dt, 'mm'), -1) + 15 -- goes from 16th of previous month; change to 14 if needing from 15th. 
      else trunc(dt, 'mm') 
     end start_dt, 
     case when dt - trunc(dt, 'mm') < 16 then trunc(dt, 'mm') -- goes from 16th of previous month; change to 14 if needing from 15th. 
      else trunc(dt, 'mm') + 15 
     end end_dt 
from dts; 

DT     START_DT    END_DT    
--------------------- --------------------- --------------------- 
29/06/2015 12:50:00 01/06/2015 00:00:00 16/06/2015 00:00:00 
02/06/2014 15:09:23 16/05/2014 00:00:00 01/06/2014 00:00:00 

Имейте в виду, что а) ДАТЫ в Oracle есть элемент времени, а и б) вы, вероятно, не хотите использовать между ними, как это делает начало и (вы можете получить строки, появляющиеся в обоих запросах, или, может быть, даже пропустить строки в целом, если вы ошиблись в end_date и забудете о чем-нибудь после полуночи в день в end_date!) - вместо этого вы, вероятно, захотите сделать что-то вроде:

and datecol >= <case statement generating start_date> 
and datecol < <case statement generating end_date>