Оракул sql побить рекорды

У меня есть таблица с полями StartDate и EndDate, а также множество других полей. Мне нужно разбить каждую запись на все дни между включением StartDate & EndDate в другую таблицу, которая выглядит точно так же, как оригинал, за исключением того, что у нее есть поле CurrentDate и 2 вычисляемых поля. Поле CurrentDate - это текущая дата между StartDate и EndDate, о которой я говорю.

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

2 ответа

Достаточно просто уплотнить данные в одном операторе SQL. Предполагая, что вы знаете разумный минимальный и максимальный диапазон для вашего begin_date а также end_date (Я предполагаю, что 1 января 2000 г. - 31 декабря 2020 г., но вы, очевидно, можете изменить это)

WITH all_days AS (
  SELECT date '2000-01-01' + level dt
    FROM dual
 CONNECT BY level <= date '2020-12-31' - date '2000-01-01'
)
SELECT <<list of colums from your table>>,
       all_days.dt current_date
  FROM your_table actual
       JOIN all_days ON (actual.begin_date <= all_days.dt AND
                         actual.end_date   >= all_days.dt)

Если вы не хотите жестко задавать даты начала и окончания, вы также можете получить их из таблицы. Это просто требует, чтобы вы попали за стол во второй раз, что, как правило, будет менее эффективным.

Если ваши таблицы источника и назначения соответствуют этому профилю:

  1. Столбцы таблицы назначения совпадают со столбцами исходной таблицы, и
  2. Новый столбец назначения находится в конце

... тогда вы могли бы сделать что-то вроде этого:

INSERT INTO dest_table
SELECT Source_Table.*, new_value
  FROM Source_Table
  WHERE Source_Table.PKValue = cursor.PKValue

Если ваш курсор похож на таблицу назначения, то может сработать что-то вроде этого, но обратите внимание, я не проверял это:

CREATE PROCEDURE whatever IS
  destRow dest_table%ROWTYPE;
  CURSOR fromSourceTable IS
    SELECT <your existing select list>, NULL AS new_value
    FROM <the rest of your cursor query>;
BEGIN
  FOR destRow IN fromSourceTable LOOP
     destRow.new_value = <the split date>;
     INSERT INTO dest_table VALUES destRow;
  END LOOP;
END whatever;

Я выхожу на конечности с NULL AS new_value, Если у вас есть проблемы, попробуйте CAST(NULL AS DATE) AS new_value вместо этого, и если у вас все еще есть проблемы, попробуйте что-то вроде SYSDATE AS new_value, Опять же, это не проверено, но если вы считаете, что это многообещающе и у вас есть проблемы с реализацией, я был бы рад проверить это.

Другие вопросы по тегам