Oracle: программа неправильно разветвляется в операторе SELECT CASE на дату - PullRequest
0 голосов
/ 01 апреля 2009

В настоящее время я работаю над проектом, который ведет себя по-разному в зависимости от того, является ли он государственным праздником или нет (среди прочих ограничений, очевидно). С этой целью я пытаюсь создать таблицу, которая содержит дату и день недели (учитывая, что «выходной» - восьмой «день недели»).

У меня есть таблица, из которой я получаю список выходных, с именем holiday, в котором есть только одно поле, holidaydate (DATE тип данных). Таблица, в которую я пытаюсь поместить значения, называется daydates, с двумя полями: day (DATE тип данных) и dayofweek (CHAR(10) тип данных).

Это логика, которая у меня есть на данный момент, пока я тестирую.

 INSERT INTO holiday
  (holidaydate)
 SELECT sysdate FROM dual;

 SELECT sysdate,
   (
   CASE
     WHEN sysdate IN
       (SELECT h.holidaydate FROM holiday h)
     THEN 'holiday'  
     ELSE TO_CHAR(sysdate , 'day')
   END)
 FROM dual;

К сожалению, в настоящее время он возвращает, скажем, «среду», а не «праздник». У меня такое чувство, что мне нужно изменить WHEN sysdate IN на WHEN to_char (sysdate, 'dd-mon-yyyy') IN или что-то в этом роде, но я попробовал несколько вариантов, и они, похоже, пока не работают.

Есть предложения?

Ответы [ 3 ]

5 голосов
/ 01 апреля 2009

Я думаю, что ваша проблема в том, что он почти никогда не достигнет этого случая:

CASE
     WHEN sysdate IN
       (SELECT h.holidaydate FROM holiday h)

Поскольку при вставке SYSDATE в таблицу holiday она вставляется с информацией о дате и Таким образом, дело, о котором вы говорите, почти никогда не выполняется.

Попробуйте сравнить только значимые части даты в вашем деле.

CASE
   WHEN TRUNC(SYSDATE) IN (SELECT TRUNC(h.holidaydate) from holiday h)

Это должно работать.

2 голосов
/ 01 апреля 2009

В вашей праздничной таблице вас интересуют только даты, а не компонент времени. Чтобы обеспечить это, наложите ограничение и остановите любого, кто совершит ту же ошибку, что и вы:

CREATE TABLE HOLIDAY
(holidaydate  DATE NOT NULL 
              CONSTRAINT DateOnlyNoTime 
                 CHECK (holidayDate = TRUNC(holidayDate)));

Без сомнения, вам понадобится первичный ключ и некоторые другие столбцы.

Предпочтительным способом удаления части даты и времени даты является использование TRUNC (), как указано выше, а не TO_DATE () для повышения производительности. Ваш пример запроса станет:

SELECT sysdate,
  (
  CASE
    WHEN TRUNC(sysdate) IN
      (SELECT h.holidaydate FROM holiday h)
    THEN 'holiday'
    ELSE TO_CHAR(sysdate , 'day')
  END)
FROM dual;
0 голосов
/ 01 апреля 2009

Вы просили предложения, так что ...

  • Вы проверили, что вставляется в праздничный стол первым утверждением, чтобы убедиться в его правильности?
  • Вы пытались убрать sysdate из картинки (например, используя константу), чтобы узнать, не в этом ли причина проблемы?
  • Вы пробовали заменить внутренний выбор постоянным списком?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...