|
Программирование >> Проектирование баз данных
REM Завершение последней строки во временном ряде REM и добавление после нее новых строк INSERT INTO contig VALUES(01-JAN-90,NULL); UPDATE contig SET date to = 31-JAN-90 WHERE date frotn = 01-JAN-90 ; INSERT INTO CONTIG values(Ol-FEB-90, NULL); UPDATE contig SET date to = 28-FEB-90 WHERE date frotn = Ol-FEB-90; INSERT INTO contig VALUES(01-MAR-90,NULL); REM Теперь данные выглядят так: REM DATE FROM DATE TO REM -------------------- REM Ol-JAN-1990 31-JAN-1990 REM Ol-FEB-1990 28-FEB-1990 REM Ol-MAR-1990 31-DEC-4712 REM REM Теперь попробуем выполнить недопустимые действия REM ================= REM 1. Изъятие средней строки (создание разрыва) - будет сгенерировано: REM ORA-20002: Gap detected REM ORA-06512: at line 35 REM ORA-04088: error during execution of trigger REM ORIGIN.CONTIG AI0D DELETE contig WHERE date from = Ol-FEB-90; REM REM 2. Создание перекрытия - будет сгенерировано следующее: REM ORA-20001: Overlap detected REM ORA-06512: at line 23 REM ORA-04088: error during execution of trigger REM ORIGIN.CONTIG AIUD INSERT INTO contig VALUES(15-FEB-90,20-FEB-90) ; REM 3. Предположим, у нас неправильные границы и 1-й период должен REM заканчиваться 15 января 19 90 года, а второй должен REM начинаться 16 января 1990 года. REM Задача состоит в том, чтобы сделать это в одном операторе, REM не Создавая временных разрывов или перекрытий UPDATE contig SET date to = DECODE(date to,31-JAN-90,15-JAN-90,date to) , date f rotn = DECODE (date frotn, Ol-FEB-90 , 46-JAN-90 , date frotn) WHERE date to IN (31-JAN-90,28-FEB-90); REM Таблица теперь выглядит так: REM DATE FROM DATE TO REM--- -- REM Ol-JAN-1990 15-JAN-1990 REM 16-JAN-1990 28-FEB-1990 REM Ol-MAR-1990 31-DEC-4712 REM REM 4. Давайте вернем таблицу в прежнее состояние. Если решение 3 слишком REM непонятное, то лучше удалить все до того места, REM откуда начинается изменение, и вновь вставить оттуда. DELETE contig WHERE date to >= 28-FEB-90; UPDATE contig SET date to = 31-JAN-90 WHERE date from = Ol-JAN-90; INSERT INTO contig VALUES (01-FEB-90,28-FEB-90); INSERT INTO contig VALUES (Ol-MAR-90,NULL) ; Этот пример хорош в качестве иллюстрации, но используемый в нем подход обладает рядом недостатков: Мы применяем триггеры уровня оператора, а не уровня строки. Когда триггер срабатывает, он проверяет на предмет нарушений всю таблицу, а не только те строки, на которые воздействовал данный оператор. Это объясняется тем, что в триггере уровня оператора нельзя обратиться к предыдущему и последующему значениям, чтобы определить, какие строки были объектом операции DELETE или UPDATE. Если бы мы использовали триггеры уровня строки (где могли бы получить предыдущее и последующее значения), то триггер не смог бы обратиться к таблице для проверки наличия перекрытия или разрыва. Дело в том, что данная таблица является огранигивающей и мутирующей и в рамках триггера уровня строки на ней самой доступ к ней невозможен. (В приложении Б предлагается основа для лучшего решения,- там показано, как избежать проблемы мутирующих таблиц.) При создании нового экземпляра строки во временном ряду обычно выполняются следующие действия. Сначала временной диапазон текущей строки завершается оператором SET date to = SYSDATE, где date to = Ol-DEC-4712 a затем с помощью date from = SYSDATE и date to = Ol-DEC-4712 определяется новый диапазон. Триггеры хороши, когда они служат средством, обеспечивающим выполнение правил. При попытке же сделать что-нибудь посложнее, например исправить ошибку, если изменение цены было произведено не в тот день, с ними возникают проблемы. Дело в том, что вы не сможете создать в данных временные разрывы или перекрытия, потому что триггеры не дадут это сделать. В пункте 3 примера показано, что все идет нормально, если мы изменяем данные в одном SQL-предложении, после выполнения которого не остаются ни разрывы, ни перекрытия. Иногда при работе с SQL нужно проявлять изобретательность. В исключительных случаях требуется временно отключить триггеры, чтобы можно было откорректировать ошибочные данные (правда, брать это за правило мы не рекомендуем). И еще несколько слов по поводу второго пункта нашего перечня. Если кажется вероятным, что указанное в нем ограничение не даст пользователям исправлять простые ошибки ввода данных, то делайте проверку в приложении, а не при помощи триггера. Приложение может провести пользователя по всему процессу изменения данных и обеспечить, что его действия не приведут к созданию разрывов и перекрытий. К сожалению, простых решений нет, и это - одно из разочарований, сопровождающих реализацию временных баз данных в реляционной модели. Использовать ли отдельную таблицу для архивных данных? В этом разделе мы рассмотрим ситуации, когда выгодно хранить текущие данные (обладающие особой действительностью по дате) отдельно от остальных действительных по дате данных. Мы обязательно должны рассмотреть возможность применения этого метода в случае, если все временные данные, кроме текущих, являются архивными. Если же нам требуется хранить архивные значения в таблице для проверки или анализа, то тоже следует подумать о том, чтобы разместить их в отдельной таблице. Мы также рассмотрим вопросы, связанные с использованием логического, а не физического удаления. Термин логическое удаление мы определяем как маркирование данных в качестве более не применимых. Этот вид удаления отличается от физического удаления, при котором данные удаляются по-настоящему. Во многих случаях логическое удаление является ничем иным, как одним из методов проектирования действительности по дате. В конце концов может оказаться, что существуют весьма незначительные различия между тем, что один проектировщик называет логическим удалением, а второй - флагом активности, т.е. столбцом, определяющим, какой является строка - активной или неактивной. Если вы решили применить такой флаг, необходимо создать триггеры, обеспечивающие, чтобы только одна строка группы (в данном случае одна строка на товар) помечалась как текущая, или активная. До сих пор мы пытались улучшить выполнение запросов, в которых извлекался только текущий экземпляр данных. Это наиболее распространенный тип запросов, потому что архивные данные часто хранятся исключительно как вспомогательное средство для аудита или очень редкого специального исследования. В случаях, где основной интерес вызывают текущие данные, можно рассмотреть возможность разбивки таблицы на две: в первой будет храниться только текущая строка, а во второй - все архивные. Таблица,
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |