(Возврат на основную страницу)
Энтузиасты Oracle очень любят критиковать SQL Server, и Бак Вуди думает, что пришло время перевести этот спор на более профессиональный уровень. Раз есть такой спор, то он хочет логически выявить, что лучше: SQL Server или Oracle. Хотите узнать, кто победитель?
Мы все видели их — эти статьи, блоги, новостные группы и руководства пользователей, которые превозносят достоинства одной платформы базы данных, ругая при этом конкурирующую платформу. Большинство из них (кроме, возможно, руководств пользователей) постоянно впадают в технологический экстремизм или безосновательные разглагольствования. Профессионал, который хочет найти подходящую платформу для определенной задачи, сталкивается с конфликтующими между собой «фактами» и полярными мнениями, так и не получая нужной информации для принятия верного решения, подходящего для его компании.
Я подумал, что смогу применить формальную дисциплину к этой проблеме, а так как логика является языком дискуссии, то я применю правила логики к обсуждению этой проблемы. Наконец, видно, что Microsoft SQL Server пытается удовлетворить большую часть бизнестребований, что логично, оказываясь в результате во многих случаях «наилучшей» базой данных.
Согласно словарю MerriamWebster, логика — это «наука, которая оперирует принципами и критериями обоснованности вывода и доказательства, наука о формальных принципах аргументации». Так как логика (хотя и другая ее часть) является неотъемлемой частью информационных технологий (согласно Wikipedia), то она и есть лучший метод определения, какую платформу использовать в определенной ситуации. Попытайтесь воспринять информацию логически — при этом обычно становится видна истина.
Логическая аргументация включает три шага:
• Определение языка и терминов дискуссии.
• Создание предпосылок, выводов и следствий.
• Опровержение логических ошибок в контраргументах.
Используя этот процесс, я покажу, что Microsoft SQL Server — подходящий выбор базы данных.
Определение терминов дискуссии
Сначала нам нужно определить термины и точно сформулировать, о чем же ведется дискуссия. Заметьте, что доказательство, которое я хочу привести, и наиболее частый вопрос, о который спотыкаются люди в спорах в Интернете, выражаются в точности следующим вопросом: «Является ли SQL Server правильной базой данных для использования в данной ситуации?» Здесь мы имеем два неоднозначных термина, которые должны быть устранены. (Неоднозначные термины — это термины, которые истолкованы более чем одним способом.) В этом вопросе слова «правильный» и «ситуация» вносят такую неоднозначность.
То, что может быть «правильным» для человека, знакомого с Oracle, скорее всего не будет являться таким для человека, имеющего опыт работы с SQL Server, — и ни один из них может не включить в это понятие факторы, которые имеют в виду другие люди. Я начну с объяснения, что я подразумеваю под понятием «правильности», чтобы у нас было одинаковое понимание, о чем идет речь.
В данном случае «правильность» относится к набору факторов, который наиболее полным образом удовлетворяет потребности пользователя. «Пользователи», в случае платформы базы данных, в большинстве компаний делятся на три группы: технический персонал, управляющий персонал и пользователи данных, хранящихся в базе данных. Каждая из этих групп имеет разные точки принятия решений и разную важность этих факторов для группы. Эта разница в пожеланиях должна учитываться во время выбора платформы базы данных.
«Ситуация» определяется как общая среда во время использования базы данных. Среда включает разные факторы, такие как внешние и внутренние факторы принятия решений. Например, если я хочу впечатлить свою подругу, то фастфуд не очень для этого подходит. С другой стороны, если я ограничен в средствах и спешу, то в данном случае фастфуд является правильным выбором. В нашем случае ситуация определяется не только техническими достоинствами или производительностью TPC, но также включает и такие факторы, как набор свойств, скорость разработки, простота использования и т. д. Для доказательства посмотрите на вашу машину: является ли она самой быстрой? Или она та, которую вы могли себе позволить купить, чинить и страховать? Ситуация с вашим транспортным средством определяется не самой лучшей машиной на рынке, а той, какая наилучшим образом подходит лично вам. Та же ситуация и с компаниями.
SQL Server — это наилучший выбор
Определившись с терминами, можно продемонстрировать предпосылки, выводы и следствия, которые указывают на превосходство SQL Server над Oracle.
Примечание. Я использую дедуктивный метод доказательства, который предполагает, что если все утверждения правильны, то следствие тоже должно быть правильным. Заметьте, что в этом методе доказательства утверждения должны быть связаны между собой. Недостаточно сказать: «Сегодня встало солнце. Я почистил зубы. Значит, солнце встает потому, что я чищу зубы». Обе предпосылки правильны, но из одной не следует другая, так что это доказательство приводит к логической ошибке «adhoc ergo proctorhoc», что значит «после этого, следовательно, изза этого». Я объясню еще несколько логических ошибок в части статьи, относящейся к опровержению.
SQL Server стоит меньше, чем Oracle
Лицензии на Oracle версии 9i для использования на двухпроцессорном компьютере стоят около $30,000.
Лицензии на SQL Server 2000 стоят около $9,998.
Это довод часто критикуется в лагере сторонников Oracle, потому что для определенной компании — с определенными начальными условиями, скидками и т. д. — цена каждой из этих платформ может очень сильно различаться. Однако при просмотре в интернете цен на программное обеспечение от сторонних поставщиков часто возникает именно такое, в два раза и более, соотношение цен. «Ситуация», определенная выше, включает менеджеров и владельцев, которые часто технические достоинства ставят ниже цены и удобства. Их отношение обычно выражается так: «Если вещь А делает практически то же, что и вещь В, то покупаем более дешевую». Хотя такое отношение и не технологично, в сфере информационных технологий часто существует такое ограничение.
SQL Server более прост в управлении, чем Oracle
Oracle включает несколько инструментов, имеет более сложные клиентские конфигурации, имеет больше опций и требует большей ручной настройки.
SQL Server имеет три главных инструмента с клиентской конфигурацией, встроенной в операционную систему, и является полностью самонастраиваемым.
Хотя Oracle сделал большие шаги в этой области, его просто нельзя сравнивать в простоте использования с SQL Server. Чтобы в этом убедиться, скачайте и установите каждую платформу. Подсчитайте количество шагов, объем информации и количество принимаемых решений, необходимых для установки. Также учтите время от начала до конца установки. Я думаю, что вы обнаружите (как и я), что установка SQL Server проходит гораздо быстрее и с меньшим количеством шагов.
SQL Server имеет более низкие системные требования
Oracle 9i требует Pentium 166 МГц и выше, 128 Mб памяти (рекомендуется 256 Mб), 400 Mб виртуальной памяти и 140 Mб места на системном диске жесткого диска, плюс 4,5 Гб для Oracle Home Drive (FAT) или 2,8 Гб для Oracle Home Drive (NTFS).
SQL Server требует Pentium 166 МГц и выше, 64 Mб памяти и 270 Mб места на жестком диске.
Конечно, это минимальные требования, но масштаб примерно соблюдается. Некоторые компании имеют неограниченный бюджет для аппаратного обеспечения, но в большинстве случаев это не так. Использование менее производительного аппаратного обеспечения для достижения той же цели является дополнительным фактором в определении «правильности» и «ситуации».
SQL Server
имеет
практически все свойства, необходимые для современных бизнесприложений
Oracle включает все требования стандарта ANSI92 SQL, а также дополнительно содержит несколько новшеств и наборов свойств.
SQL Server включает все требования стандарта ANSI92 SQL, а также дополнительно содержит несколько новшеств и наборов свойств.
Без сомнения, Oracle имеет несколько дополнительных типов индексов, опций хранения, команд PLSQL и других улучшений, которых нет в SQL Server. Но при этом возникает вопрос: «А нужно ли вам все это?» Если вам определенно нужен bitmap индекс, используйте Oracle. Если же изза качественных дизайна и реализации этого не требуется, то вы обнаружите, что SQL Server содержит все, что вам нужно. Это позволяет выставить контраргумент доводам типа «А против В» от менеджмента и пользователей.
Также существуют и другие аргументы за SQL Server, но место здесь ограничено. Так как в компании в целом факторы, влияющие на принятие решения о покупке, включают в себя цену, простоту управления и использования, возможности поддержки и адекватный набор свойств, то я верю, что логические аргументы, представленные выше, показывают, что SQL Server фактически является подходящей платформой практически для всех ситуаций в бизнесе.
Почему фанаты Oracle нелогичны
Теперь давайте перейдем к опровержению логических аргументов энтузиастов Oracle, если таковые имеются. Чтобы увидеть эти заблуждения, загляните в любую новостную группу Oracle, в которой критикуют SQL Server. Вы найдете там эти ошибки вместе со многими другими.
Я начну с логической ошибки, которой обычно завершаются все разглагольствования в дискуссионных группах. Эта ошибка называется «Ad hominem», что означает «переход на личности». Она возникает, когда ктото начинает критиковать личность оппонента, а не его логические построения. Для приверженцев Oracle это обычно сводится к унижению Microsoft или ее основателя. Для конечного пользователя эти аргументы абсолютно не важны.
Следующей логической ошибкой, замеченной в группах Oracle, является «Argumentum ad numerum», что означает, что большинство должно быть правым. «Большее количество людей использует Oracle», — утверждается в аргументе, — «значит, он лучше». Это напоминает мне одну историю, в которой исполнительный директор одной фирмы шла по улице с финансовым директором. «Смотри», — воскликнула она, — «там в траве двадцатидолларовая купюра!» «Это не может быть двадцатидолларовой купюрой», — сказал финансовый директор. «Почему нет?» — спросила исполнительный директор. «Потому что», — ответил он, — «если бы это была двадцатидолларовая купюра, ее бы ктонибудь уже поднял. Все эти люди вокруг не могут ошибаться».
Хотя существует и множество других заблуждений, поддерживаемых приверженцами Oracle, я продемонстрирую последний пример. Эта ошибка называется «Ignoratio elenchi», означающая, что представленный довод не имеет никакого отношения к утверждению. Это происходит, когда на утверждение «Но SQL Server более легок в управлении — разве это не важно?» следует ответ: «SQL Server не масштабируется!» Сам этот ответ спорен, но он также и абсолютно не отвечает на заданный вопрос.
Заключение
В заключение хочется сказать, что очень важно, чтобы вы сами пользовались таким методом. Применяйте простую логику, и вы поймете, что зачастую именно SQL Server лучше всего подходит для ваших требований.
Эрик Черен (Eric Charran)
В первой части статьи рассказывалось об архитектуре базы данных и проекте хранения двоичных файлов для приложения .NET. Здесь будут рассмотрены архитектура приложения и технические приемы проектирования, которые позволят изучить последовательное преобразование двоичных данных и их хранение в SQL Server.
Структура приложения определяется множеством слоев, каждый из которых отвечает за то, чтобы замаскировать от смежного верхнего слоя множество ненужных деталей. В результате схема реализации представляет собой единственный класс, ответственный за все передачи в базу данных и из нее, и формупотребитель для Web, которая реализует прием двоичной информации из компьютера пользователя.
Как только слой базы данных будет внедрен, различные типы приложений смогут воспользоваться обусловленными моделью данных возможностями хранения и извлечения документов. В этой статье мы сконцентрируемся на решениях для .NET и кратко поговорим о формах Web.
Общая структура решения (.NET Solution) должна концентрироваться вокруг использования этого класса для всех операций, связанных с документами, включая поиск, сохранение в двоичном виде и извлечение. Тогда класс Documents можно будет также использовать для всех элементов решения. Он будет способствовать реализации во всем решении унифицированного слоя обработки данных, который отвечает за выполнение операций в базе данных, управление соединениями и возврат отформатированных наборов данных (то есть DataSets, DataReaders и т. д.). Блок Microsoft Data Access Application Block представляет собой свободно доступный слой обращения к данным, который можно скачать на сайте Microsoft. Этот блок поможет абстрагировать в классе Documents взаимодействия с базой данных и позволит передать параметры SqlParameters в принадлежащий блоку приложения класс SqlHelper.
Цель данного решения — получение документа в виде потока (System.IO.Stream) в .NET и преобразование этого потока в SqlParameter с типом данных VarBinary. Класс Documents будет управлять этими действиями. Цель формы Web — обеспечить интерфейс, который позволит пользователям загрузить документ в объект HttpPostedFile.
Кен Хендерсон (Ken Henderson)
В этой статье рассказывается, какой эффект на работу системы оказывает совместное применение волоконного режима SQL Server (fiber mode) и планировщика пользовательского режима User Mode Scheduler и на что следует обратить особое внимание при включении волоконного режима.
В статье «Устройство User Mode Scheduler в SQL Server 2000»1 я подробно рассказал о том, как компонент SQL Server, отвечающий за диспетчирование процессов SQL Server, User mode Scheduler (UMS), выполняет на сервере свою работу. Сконфигурировать UMS можно для работы в режиме либо потоков, либо волокон, и по умолчанию применяется режим потоков. Режим волокон может уменьшить количество переключений контекста между потоками и количество переключений центрального процессора с пользовательского режима на режим ядра. В этой статье мы обсудим, почему режим волокон, как правило, не рекомендуется к применению и что лежит в основе этих рекомендаций.
Режим волокон использует не потоки, а волокна (fiber) Windows для обслуживания рабочих процессов, которые представляют собой более легкие исполнительные механизмы. Обычно в одном потоке существует множество волокон. Поток создает волокно с помощью API функции CreateFiber() [или CreateFiberEx()] и планирует его работу через SwitchToFiber(). Поскольку базовым механизмом исполнения в Windows попрежнему остается поток, то исполняемый в волокне код Win32 все же работает через поток. Переключение контекста между потоками происходит значительно реже, и намного меньше случается дорогостоящих переключений в режим ядра, потому что волокна являются конструкциями пользовательского режима, о которых ядро ничего не ведает. Переключения контекста могут происходить между несколькими волокнами, принадлежащими одному потоку, а часть операций, которые в обычных условиях потребовали бы перехода в режим ядра, вместо этого может выполняться целиком в пользовательском режиме. Использование волокон эффективно учит потоки «хитрить».
Учитывая все это и принимая во внимание сомнительное название, которое в SQL Server дано волоконному режиму, — облегченная организация пулов (lightweight pooling), трудно не воспользоваться режимом волокон на всех производственных компьютерах с SQL Server, особенно на тех, которые планируется наращивать. В конце концов, разве «облегченный» режим не повышает производительность? Не будет ли он способствовать наращиванию системы? Не спешите. Как правило, следует избегать использования волоконного режима до тех пор, пока специалист из Microsoft или из компаниипартнера не посоветует поступить иначе. Существует несколько важных аспектов, о которых следует знать, размышляя о введении режима упрощенной организации пулов в SQL Server.
Уильям Пирсон (William Pearson)
В этой статье рассказывается о функциях Parent, Children и Ancestor() и обсуждается возвращаемая ими информация, а также синтаксические вопросы, связанные с их использованием. Мы покажем, как использовать эти функции, и прокомментируем полученные наборы результатов.
Мне нравится называть одно подмножество функций членов и операторов «семейными» функциями, потому что многие из них называются, как члены семьи. В эту группу входят следующие функции:
Parent (родитель);
Children (ребенок);
Ancestor() (предок);
Cousin() (кузен);
FirstChild (первый ребенок);
LastChild (последний ребенок);
FirstSibling (первый брат/сестра);
LastSibling (последний брат/сестра).
Метафора семьи оказывается подходящей, поскольку эти функции выполняют операции на размерностях, иерархиях и уровнях подобно тому, как если бы мы двигались по генеалогическому древу. Существуют и другие «семейные» функции, возвращающие множества, но в этой статье мы сконцентрируемся в основном на функциях членов.
Мы обсудим некоторые концепции, лежащие в основе «семейных» функций, и разберем синтаксис, позволяющий эффективно использовать каждую из них. Затем мы продемонстрируем примеры их практического применения в простых выражениях и запросах, которые впоследствии будут использованы, чтобы просмотреть результаты и глубже понять действие этой функции или компонента с точки зрения возвращаемого набора данных.
Данная статья содержит:
общие вопросы, связанные с членами и функциями членов, а также с их ролью в MDX;
представление функций Parent, Children и Ancestor(), включая анализ синтаксиса каждой их них, пример использования функции на практике и краткое обсуждение результатов MDX;
введение в оборот WHERE и определение срезов размерностей;
краткое упоминание дополнительных «семейных» функций, которые мы будем изучать в последующих статьях.
Функции членов, особенно входящие в группу «семейных», позволяют выполнять операции на основании относительного положения члена в иерархии размерности либо вверху (над тем членом, который указан в функции), либо внизу (под тем членом, который указан в функции). Если мы попытаемся выйти за пределы заданной размерности, будет возвращен ноль. Примером такой ситуации может служить попытка выполнить функцию Children для члена, находящегося на самом дне иерархии (на уровне листьев), который по определению является «бездетным». Подобно большинству функций членов, «семейные» функции могут быть крайне полезными для упрощения запросов MDX и написания их в более компактной форме.
Боб Бошмен, Нилс Берглунд, Дэн Салливан (Bob Beauchemin, Niels Berglund, Dan Sullivan)
Мы продолжаем рассказ об изменениях в TSQL. В этой статье рассматриваются перекомпиляция на операторном уровне и DDL триггеры.
Перекомпиляция на операторном уровне — это нововведение, способствующее повышению производительности. В SQL Server 2000 архитектура плана выполнения запроса отличается от предыдущих версий и разделяется на две категории: план компиляции и план исполнения.
План компиляции (план запроса) — структура данных, доступная только для чтения и используемая некоторым количеством пользователей. План допускает повторное использование. Подразумевается, что все пользователи совместно используют план, и он не содержит информации о контексте пользователя (например значений переменных). В памяти не может существовать более одной или двух копий плана запроса — одна копия для последовательного выполнения, другая для параллельного.
План исполнения — информационная структура, которая создается для каждого из пользователей, одновременно выполняющих запросы. Эта структура данных может содержать отличающиеся данные для каждого пользователя, например значения параметров.
Такая архитектура, основанная на повторном выполнении плана, повышала производительность исполнения не только хранимых процедур, но также функций, пакетов, динамических запросов и т. д. Однако она приводит к проблеме частой перекомпиляции хранимых процедур. Могут вызвать перекомпиляцию:
изменения схемы данных;
качественные изменения состава строк;
установка опций SET.
Перекомпиляция может быть очень дорогостоящей операцией, особенно если процедура, функция или пакет очень большие, потому что SQL Server 2000 осуществляет перекомпиляцию на уровне всего модуля. Иначе говоря, процедура будет перекомпилирована полностью, даже если изменения затронули лишь малую ее часть. Кроме того, если перекомпиляция происходит по причине установки опции SET, план выполнения не будет использоваться и не кэшируется. Код в листинге 1 чрезвычайно прост, но его можно использовать для иллюстрации этой проблемы.
В листинге 1 приведен код хранимой процедуры, в теле которой изменяется установка CONCAT_NULL_YIELDS_NULL. В момент смены опции в процедуре выполняется перекомпиляция для всех следующий операторов.
Листинг 1. Пример процедуры, провоцирующей рекомпиляцию
CREATE PROCEDURE test2
AS
SELECT
‘before set option’
// Меняем значение настройки
SET DATEFORMAT
‘MDY’
SELECT
‘after set option’
Для того чтобы убедиться, что в SQL Server 2000 происходит перекомпиляция, необходимо сделать следующее:
Откомпилировать процедуру из листинга 1.
Запустить утилиту SQL Server Profiler, выбрать в меню File | New | Trace
В диалоговом окне Trace Properties перейти на вкладку Events.
Перейти в группу событий Stored Procedures, выбрать событие SP:Recompile, щелкнуть кнопку Add, и затем нажать Run.
Выполнить процедуру из Query Analyzer, а затем просмотреть трассу.
В трассе в колонке Event Class получаем значение SP:Recompile; это значит, что процедура была перекомпилирована.
Как уже упоминалось, для очень больших процедур стоимость перекомпиляции может быть очень высока, и поэтому в SQL Server 2005 внедрена перекомпиляция на операторном уровне. Вы наверняка предположите, что производительность может снизиться изза того, что каждый оператор в процедуре будет перекомпилироваться отдельно. Но не стоит волноваться — ведь при перекомпиляции на операторном уровне начальная компиляция происходит также на уровне модуля, а при необходимости производится перекомпиляция отдельного оператора.
Другим достоинством перекомпиляции на операторном уровне является то, что после ее выполнения план выполнения остается. Процедура из листинга 1 может быть использована для выявления отличий между SQL Server 2000 и 2005. Для SQL Server 2005 можно проделать шаги, описанные выше, и убедиться в том, что перекомпиляция выполняется только в момент первого запуска процедуры, но не для всех последующих запусков. Выполните представленный ниже код, после того как несколько раз запустили процедуру, и убедитесь, что результат содержит и план компиляции, и план выполнения:
SELECT
* FROM syscacheobjects
WHERE dbid = db_id('pubs')
AND objid = object_id('test2')
Чтобы полученный результат был правильным, необходимо очистить кэш перед выполнением процедуры, для этого нужно выполнить dbcc freeproccache.
При настройке параметров трассы вы увидите, что SQL Profiler позволяет отслеживать больше событий, чем в SQL Server 2000.
Перекомпиляцию на операторном уровне можно назвать чисто инфраструктурным расширением. Как разработчик или администратор базы данных, вы не будете явно ее использовать, несмотря на повышение производительности, но, возможно, вы измените метод разработки хранимых процедур. Теперь перекомпиляция не оказывает значительного негативного воздействия на производительность.
DDL триггеры
Триггер — это совокупность TSQLоператоров, выполняющихся на определенное действие (INSERT, UPDATE или DELETE) в таблице или представлении. В предыдущих версиях SQL Server составляющие триггер инструкции должны были быть написаны на TSQL, но в SQL Server 2005 они могут быть написаны на языках .NET. Триггеры срабатывают на выполнение инструкций языка DML.
Что касается изменений, производимых инструкциями языка определения данных, таких как изменение схемы базы данных или сервера баз данных, то до SQL Server 2005 на эти события невозможно было создавать триггеры. В SQL Server 2005 можно создавать триггеры как на инструкции языка DML, так и на инструкции DDL.
В листинге 2 приведен синтаксис определения триггера на инструкцию DDL. DDLтриггер, также как и DMLтриггер, может быть создан с помощью языков .NET.
Листинг 2. Синтаксис определения DDLтриггера
CREATE
TRIGGER trigger_name
ON { ALL SERVER | DATABASE }
[ WITH ENCRYPTION ]
{ FOR | AFTER } { event_type [ ,...n ] | Ã
DDL_DATABASE_LEVEL_EVENTS }
[ WITH APPEND ]
[ NOT FOR REPLICATION ]
{ AS
{ sql_statement [ ...n ] | EXTERNAL NAME Ã
< method specifier > }
}
< method_specifier > ::=
assembly_name:class_name[::method_name]
Синтаксис определения DML и DDLтриггеров почти одинаков, однако есть и отличия.
Предложение ON в DDLтриггере относится ко всему серверу (ALL SERVER) или к текущей базе данных (DATABASE).
DDLтриггер не может быть триггером INSTEAD OF.
Событие, на которое срабатывает триггер, определяется параметром event_type. Если событий несколько, то они образуют список и отделяются друг от друга запятыми. Также можно использовать общий параметр DDL_DATABASE_LEVEL_EVENTS.
В SQL Server Books Online приведен полный список операторов DDL, которые используются в качестве значения для аргумента event_type и по умолчанию включены в DDL_DATABASE_LEVEL_EVENTS. Можно применять DDLтриггеры для аудита. Следующий код демонстрирует создание триггера для записи в таблицу информации об удалении таблиц в базе:
--
Сначала создаем таблицу для аудита
CREATE TABLE ddlLog (id INT PRIMARY KEY IDENTITY,
logTxt VARCHAR(MAX))
GO
-- Создаем тестовую таблицу
CREATE TABLE triTest (id INT PRIMARY KEY)
GO
-- Создаем триггер
CREATE TRIGGER ddlTri
ON DATABASE
AFTER DROP_TABLE
AS
INSERT INTO ddlLog VALUES('table dropped')
Вы можете задаться вопросом, зачем использовать тип VARCHAR(MAX) при создании первой таблицы, — поясним это ниже. Триггер создан для локальной базы данных (ON DATABASE) и срабатывает, как только в этой базе данных будет удалена таблица (ON DROP_TABLE). Выполните следующий код, чтобы увидеть, как работает триггер:
DROP
TABLE triTest
SELECT * FROM ddlLog
Команда DROP TABLE вызовет выполнение триггера, и в таблицу ddlLog добавится одна запись, которую можно посмотреть, выполнив команду SELECT.
Очевидно, что DDLтриггеры очень полезны для аудита. Однако мы не получим исчерпывающую информацию от триггера, который только что создали. В DMLтриггерах мы имеем таблицы inserted и deleted, которые позволяют получать информацию о данных, изменения которых затрагивает триггер. Таким образом, становится ясно, что нам необходим способ получения подробной информации о событиях, когда срабатывает DDLтриггер. Ее можно получить с помощью функции Eventdata.
Функция Eventdata
Функция Eventdata () возвращает информацию о том, что вызвало срабатывание DDLтриггера. Она возвращает значение в виде XML, и этот XML типизируется специализированной схемой XSD. В зависимости от типа события XSD включает различную информацию. Однако следующие четыре элемента обязательны для любого типа событий:
время события;
SPID, в контексте которого было вызвано срабатывание триггера;
учетная запись и имя пользователя, выполнившего инструкцию, повлекшую срабатывание триггера;
тип события.
Дополнительные сведения о результатах работы функции Eventdata содержатся в SQL Server Books Online. Однако для нашего триггера из примера, который срабатывает при выполнении инструкции DROP TABLE, дополнительная информация будет следующая:
база данных;
схема;
объект;
тип объекта;
инструкция TSQL.
В листинге 3 изменим триггер, чтобы он вставлял информацию, полученную с помощью функции Eventdata, в таблицу ddlLog, и сделаем так, чтобы триггер срабатывал на все события DDL.
Листинг 3. Использование функции Eventdata в триггере
--
Изменим триггер
ALTER TRIGGER ddlTri
ON DATABASE
AFTER DDL_DATABASE_LEVEL_EVENTS
AS
INSERT INTO ddlLog VALUES
CONVERT(VARCHAR(max), eventdata())
При помощи этого кода мы получим информацию, показанную в листинге 4.
Удаляем все строки в ddlLog
DELETE ddlLog
Создаем новую таблицу
CREATE TABLE evtTest (id INT PRIMARY KEY)
Выводим поле logTxt в виде XML
SELECT logTxt
FROM ddlLog
Листинг 4. Результат работы функции Eventdata
<EVENT_INSTANCE>
<PostTime>2004-01-30T11:58:47.217</PostTime>
<SPID>57</SPID>
<EventType>CREATE_TABLE</EventType>
<ServerName>ZMV44</ServerName>
<LoginName>ZMV44\Administrator</LoginName>
<UserName>ZMV44\Administrator</UserName>
<DatabaseName>pubs</DatabaseName>
<SchemaName>dbo</SchemaName>
<ObjectName>foo</ObjectName>
<ObjectType>TABLE</ObjectType>
<TSQLCommand>
<SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON"
ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON"
ENCRYPTED="FALSE" />
<CommandText>
CREATE TABLE evtTest (id int primary key)
</CommandText>
</TSQLCommand>
</EVENT_INSTANCE>
Поскольку функция возвращает результаты в формате XML, можно использовать запрос XQuery для получения детальной информации. Это можно сделать прямо из триггера или из таблицы, в которой хранятся результаты. Следующий код демонстрирует, как получить значения EventType, Object и CommandText, если результаты работы функции Eventdata хранятся в таблице ddlLog. Обратите внимание: прежде чем выполнить инструкцию XQuery, мы сначала сохраняем это значение в переменной типа данных XML:
DECLARE @data XML
SELECT @data = logTxt FROM ddlLog
WHERE id = 11
SELECT
CONVERT(NVARCHAR(100),
@data.query('data(//EventType)')) EventType,
CONVERT(NVARCHAR(100),
@data.query('data(//Object)')) Object,
CONVERT(NVARCHAR(100),
@data.query('data(//TSQLCommand/CommandText)'))
Command
Синтаксис предыдущего кода может казаться странным, но таковы особенности XML и XQuery.
Модель программирования для триггеров DML и DDL — синхронная модель, которая исправно действует, когда работа триггера выполняется быстро. Это необходимо, потому что DML и DDLтриггеры могут использоваться для создания правил и могут «откатить» изменения, если эти правила нарушены. Если триггер должен выполняться продолжительное время, при этом неизбежно страдает масштабируемость. Поразмыслив над этим, можно придти к выводу, что для некоторых задач было бы лучше иметь асинхронную модель регистрации событий. Поэтому в SQL Server 2005 включена новая модель уведомления о событиях, которая работает асинхронно, — event notifications. О ней речь пойдет в следующей части статьи.
Рэнди Пэк (Randy Pack)
Подстановки DTS (DTS Lookup) облегчают задачу преобразования данных средствами DTS. Они позволяют извлекать из таблицы значение, используя в качестве параметра запроса данные исходной преобразуемой строки. Поддерживая не только оператор SELECT, но и операторы INSERT, UPDATE и DELETE, подстановки DTS существенно расширяют функциональные возможности преобразования данных. В этой статье рассказывается о применении подстановок DTS.