Oracle — проблема с созданием справочной таблицы дат

#oracle #plsql

#Oracle #plsql

Вопрос:

Я пытаюсь создать справочную таблицу, отобразить все даты и ссылки в моих таблицах по ключу даты. Однако это работает не так, как я ожидал.

 DECLARE
  start_date DATE := TO_DATE('2009-01-01','YYYY-RR-DD');
  end_date DATE := TO_DATE('2021-01-01','YYYY-RR-DD');
BEGIN
  WHILE start_date < end_date LOOP
      SELECT 
            TO_CHAR(start_date, '-YYYYMMDD') AS DATE_KEY
          , TO_CHAR(start_date, 'YYYY-MM-DD') AS "ACTUAL_DATE"
          , EXTRACT(YEAR FROM start_date) AS "YEAR"
          , EXTRACT(MONTH FROM start_date) AS "MONTH"
          , TO_CHAR(start_date, 'MONTH') AS "MONTH_NAME"
          , TO_CHAR(start_date, 'WW') AS "WEEK_OF_YEAR"
          , EXTRACT(DAY FROM start_date) AS "DAY"
          , TO_CHAR(start_date, 'DDD') AS "DAY_OF_YEAR"
          , TO_CHAR(start_date, 'DAY') AS "WEEKDAY"
          , TO_CHAR(start_date, 'Q') AS "QTR_OF_YEAR"
          , TO_CHAR(start_date, 'MONTH DD, YYYY') AS FRIENDLY
      INTO V_DATE
      FROM dual;
      start_date := start_date 1;
  END LOOP;
END;
  

Я получаю эту ошибку, но независимо от того, что я пытаюсь, я продолжаю получать ошибки.
Я попытался объявить V_DATE, но это не сработало должным образом.

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

Спасибо, Аллан

Комментарии:

1. У вас неправильная маска формата при преобразовании даты. Вы должны использовать ‘ГГГГ-ММ-ДД’

2. Вы получаете какую ошибку? Ваши маски формата объявления имеют RR вместо MM; возможно, вы захотите использовать для них литералы даты ANSI. Вы также можете заполнить таблицу иерархическим запросом и избежать PL / SQL.

3. Вы используете встроенные функции Oracle. Зачем вам нужна таблица?

4. Я предполагаю, что V_DATE в конечном итоге станет представлением? Зачем вам нужен код PL / SQL для его заполнения? Вы можете сделать все это в обычном SQL.

5. Расширение текущего дизайна. На эту таблицу ссылаются в настройке хранилища данных. Мне нужно продлить дату, но не было существующего кода для того, как он был изначально создан.

Ответ №1:

Синтаксис:

 select . . .
into v_date
. . .
  

используется (в Oracle) для выбора в переменной.

Кажется, вы хотите вставить строки в таблицу:

 insert into ??( . . . )
    <your select here>;
  

Это ?? имя вашей таблицы. Это . . . список столбцов.

Кроме того, вы могли бы отказаться от PL / SQL и выполнить все это в одном запросе, используя CTE для генерации всех дат (либо с использованием connect by , либо рекурсивного CTE).

Ответ №2:

Вы можете создать таблицу с помощью одного оператора следующим образом:

   CREATE TABLE refdates AS 
  SELECT 
        TO_CHAR(start_date, '-YYYYMMDD') AS DATE_KEY
      , TO_CHAR(start_date, 'YYYY-MM-DD') AS "ACTUAL_DATE"
      , EXTRACT(YEAR FROM start_date) AS "YEAR"
      , EXTRACT(MONTH FROM start_date) AS "MONTH"
      , TO_CHAR(start_date, 'MONTH') AS "MONTH_NAME"
      , TO_CHAR(start_date, 'WW') AS "WEEK_OF_YEAR"
      , EXTRACT(DAY FROM start_date) AS "DAY"
      , TO_CHAR(start_date, 'DDD') AS "DAY_OF_YEAR"
      , TO_CHAR(start_date, 'DAY') AS "WEEKDAY"
      , TO_CHAR(start_date, 'Q') AS "QTR_OF_YEAR"
      , TO_CHAR(start_date, 'MONTH DD, YYYY') AS FRIENDLY
  FROM (SELECT TO_DATE('2008-12-31','YYYY-MM-DD')   level as start_date
        FROM   dual
        CONNECT BY level < 10000);