Оракул 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)
Если вы не хотите жестко задавать даты начала и окончания, вы также можете получить их из таблицы. Это просто требует, чтобы вы попали за стол во второй раз, что, как правило, будет менее эффективным.
Если ваши таблицы источника и назначения соответствуют этому профилю:
- Столбцы таблицы назначения совпадают со столбцами исходной таблицы, и
- Новый столбец назначения находится в конце
... тогда вы могли бы сделать что-то вроде этого:
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
, Опять же, это не проверено, но если вы считаете, что это многообещающе и у вас есть проблемы с реализацией, я был бы рад проверить это.