|
Программирование >> Программирование баз данных
SELECT COUNT (*). Следует отметить, что сообщение (1 row(s) affected) относится к этому результирующему набору, а не к оператору удаления, который составляет суть текущей части кода триггера. После этого выполняются последние операторы данной части триггера (при этом снова формируется соответствующее сообщение) и наконец появляется сообщение (2 row(s) affected) , сформированное самим исходным оператором удаления. Таким образом, все проверки прошли успешно. Были опробованы все возможные варианты активизируемых действий, причем в каждом из этих вариантов мы могли бы, безусловно, предусмотреть осуществление гораздо более сложных операций. В сл\ае необходимости можно было бы также обеспечить выполнение расширенных операций с помощью триггера BEFORE. Специализированные типы данных Иногда возникает необходимость обеспечить хранение данных, на которые должны распространяться правила строгого контроля типов, притом что для этих данных не подходит ни один тип из списка простых типов данных SQL Server. Безусловно, можно было бы предусмотреть применение сложного набора правил для определения того, соответствуют ли хранимые данные требованиям типа, определяемого пользователем, или нет. Но потребность в обеспечении поддержки сложных типов данных в СУБД SQL Server не была удовлетворена в течение очень долгого времени. В частности, еще на совещании, посвященном разработке программного обеспечения Sphinx Beta 2.0 (которое многим больше известно как Beta 2 для SQL Server 7.0), проходившем в 1998 году, среди пожеланий к будущим версиям SQL Server на втором месте были пожелания ускорить выпуск программного обеспечения, позволяющего поддерживать сложные типы данных. С тех пор прошло много лет, но наконец-то мечты стали реальностью. Применение сборок .NET открывает перед нами практически неограниченные возможности создания требуемых типов данных. Создаваемый тип может подчиняться сложным правилам и даже содержать многочисленные свойства. Прежде чем перейти к изучению синтаксиса, позволяющего вводить в действие сборки, рассмотрим, как происходит формирование сборки. В дашюм разделе в качестве образца используется решегае ComplexNumber.sln, которое включено в состав образцов для SQL Server. Для этого необходимо найти основной каталог, относящийся к рассматриваемому решению; местонахождение этого каталога в каждой конкретной инсталляции может оказаться иным. Затем мы можем приступить к реализации проекта, после выполнения предварительного этапа - создания ключей подписи для данного проекта. Чтобы иметь возможность осуществить это действие, автор рекомендует вначале перейти в каталог решения, а затем вызвать на выполнение программу sn.exe с использованием полностью уточненного имени пути (еще один вариант состоит в том, что можно включить обозначение каталога инфраструктуры .NET в состав системной переменной PATH; в таком случае указанная операция намного упрощается). В системе автора применяемая команда выглядит следующим образом: с:\Program Files\Microsoft.NET\SDK\v2.О 64bit\LateBreaking\SQLCLR\UserDefined DataType> C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\Bin\sn -k temp . snk Вслед за осуществлением указанных действий можно приступить к созданию библиотеки DLL. После выполнения этой задачи необходимо выгрузить фактически пол)енную сборку (читатель должен внести изменения в следующий код с учетом путей к каталогам, применяемым в конкретной системе): CREATE ASSEMBLY ComplexNumber FROM <solution path>\ComplexNumber\bin\debug\ComplexNumber.dll WITH PERMISSION SET = SAFE; По завершении загрузки сборки можно провести эксперименты. Создание пользовательского типа данных на основе сборки На предьщущем этапе была создана сборка, которая реализует сложный тип данных, и выгружена в СУБД SQL Server с использованием команды CREATE ASSEMBLY. В результате появилась возможность передать указание в СУБД SQL Server, касающееся того, как применить эту сборку. Для этого требуется выполнить в основном такие же операции, как и по отношению к другим сборкам. Применяемый для этого синтаксис выглядит следующим образом: CREATE TYPE [ <schema name>. ] <type name> FROM <base type> [ ( <precision> [ , <scale> ] ) ] [ NULL I NOT NULL ] I EXTEiyAIj NAME <assembly name> [ .<class name> ] } [ ; ] В данном случае автор привел полное определение типа, но в действительности в этом определении изменения по сравнению с определением пользовательского типа данных в старом стиле произошли только в предпоследней строке. Кроме того, можно сразу же обнаружить, что применяемые конструкции аналогичны применявшимся ранее конструкциям, относящимся к сборкам, и в действительности эти конструкции имеют аналогичное назначение. Поэтому оператор создания сложного типа на основе определения, приведенного в предыдущем разделе, может выглядеть так: CREATE TYPE ComplexNumber EXTERNAL NAME [ComplexNumber].[Microsoft.Samples.SqlServer.ComplexNumber]; Применение сложного типа данных в программном обеспечении, подготовленном корпорацией Microsoft, предусмотрен файл test. sql, который позволяет выполнить проверку сборки, определенной водном из предьщущих разделов и предназначенной для создания сложного типа данных, но автор решил дополнить указанный файл сценария, поскольку он не позволяет получить полное представление о той теме, которая здесь рассматривается. Дополнения, внесенные автором в этот сценарий, позволяют показать, как может быть получен доступ к различным функциям поддерживающего класса, относящегося к пользовательскому типу данных. Кроме того, можно убедиться в том, что каждое отдельное свойство создаваемой переменной является полностью адресуемым. Модифицированная версия указанного сценария приведена ниже. USE AdventureWorks GO -- Создается переменная указанного типа и переменной присваивается значение, -- после чего происходит вызов метода DECLARE ®с ComplexNumber; SET ®с = CONVERT(ComplexNumber, (1, 2i)); SELECT ©c.ToString0 AS FullValueAsString; SELECT ©C.Real AS JustRealProperty GO Вызовем этот сценарий на выполнение и проверим полученные результаты: FullValueAsString (l,2i) (1 row(s) affected) JustRealProperty (1 row(s) affected) В первой части возвращенных результатов показано, что была вызвана функция ToString, которая определена как метод класса. Форматирование строки произошло именно так, как требуется в применяемом методе. Если бы нам потребовалось изменить порядок расположения чисел на противоположный или реализовать какое-то другое произвольное требование, подобное этому, то достаточно было бы модифицировать определение функции ToString в классе, повторно откомпилировать код и еще раз импортировать этот код в применяемую базу данных. Во второй части полученных результатов показано, что произошло обращение всего лишь к одному свойству применяемого сложного типа данных. Простой разграничитель в виде точки (.) передает в СУБД SQL Server информацию о том, что осуществляется доступ к свойству, по такому же принципу, как в языке С# или VB.NET. Удаление типов данных Как и следует ожидать, синтаксис удаления определяемого пользователем типа данных полностью аналогичен синтаксису других операторов удаления: DROP TYPE [ <schema name>. ] <type name> [ ; ] После вызова на выполнение оператора удаления тот тип данных, к которому относится этот оператор, может быть исключен из базы данных. Обратите внимание на то, что в предьщущем предложении не утверждается категорически, что применение оператора удаления приводит к уничтожению рассматриваемого типа данных. Дело в том, что если имеется хотя бы один объект, который ссылается на этот тип данных, то оператор DROP будет отвергнут и попытка его выполнения окончится неудачей. Это происходит и в том случае, если в какой-то таблице имеется столбец с данными удаляемого типа. Удаление определения типа оканчивается неудачей и в том случае, если имеются представление, связанное со схемой, хранимая процедура, триггер или функция, при создании которых использовался удаляемый тип данньгх.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |