Создание Web-приложений с использованием ASP.NET 2.0 и SQL Server 2005 Сергей Байдачный Технический директор ITG Ukraine, Beliron
Содержание Введение в SQL Server 2005 Работа с XML в SQL Server 2005 SQL Server 2005 и встроенный CLR Новые элементы по работе с данными в ASP.NET
SQL Server 2005 Relational Database Engine.NET CLR Analysis Services Native HTTP Support Service Broker Replication Reporting Services Full-Text Search Notification Services Data Transformation Services
Для разработчиков Расширения Transact-SQL Встроенная поддержка XML Работа с сообщениями Родная поддержка HTTP Notification Services Интеграция с CLR Reporting Services SQL Management Objects
Утилиты разработчика SQL Server Management Studio Business Intelligence Development Studio sqlcmd Visual Studio Designer
SQL Server Management Studio
Business Intelligence Development Studio
SQL Server проекты в VS 2005 Проекты для создания управляемых объектов Автоматически включают необходимые ссылки sqlaccess.dllSystem.Data.dll Содержат все необходимые шаблоны Простое развертывание и отладка Stored procedure Trigger User-defined function User-defined type Aggregate
Разделенные таблицы Распределение данных таблицы Увеличивает производительность на многопроцессорных системах Более простое управление большими таблицами
Обработка исключений TRY…CATCH – обработка ошибок Код "IF больше не нужен Требует XACT_ABORT ON можно использовать в блоке catch Используйте "RAISERROR … WITH TRAN_ABORT" для создания исключений CREATE PROCEDURE int AS SET XACT_ABORT ON BEGIN TRY BEGIN TRAN INSERT INTO dbo.DataTable COMMIT TRAN END TRY BEGIN CATCH TRAN_ABORT int = --trap the error number ROLLBACK TRAN INSERT INTO END CATCH GO
Расширение типов данных Увеличение размера некоторых типов: varchar(max)nvarchar(max)varbinary(max) xml – хранение данных XML с возможной схемой
Доступ из различных источников Встроенная поддержка HTTP Web Server SQL Server Internet LAN Mainframe Client Безопасность.NET Client LAN Java Client
Service Broker Service program Contract Service Queue Message type
Иерархия классов SQL Management Object Server Database Tables Table Columns Column … Schemas StoredProcedures Views … … Databases Утилитные классы Backup, Restore, Scripter, Transfer
Поддержка XML
Хранение XML в базе Преимущества: Единое хранилище данных Работа с содержимым на уровне БД Выбирайте наиболее подходящую модель хранения данных Единое хранилище данных Работа с содержимым на уровне БД Выбирайте наиболее подходящую модель хранения данных Функциональность: XML индексы XQuery – для возврата данных XQuery – для модификации данных XML индексы XQuery – для возврата данных XQuery – для модификации данных Поддержка схем: Typed XML: Проверка данных по схеме Untyped XML: Отсутствие проверки Typed XML: Проверка данных по схеме Untyped XML: Отсутствие проверки
Не типизированные XML CREATE TABLE Invoices (InvoiceID int, SalesDate datetime, SalesDate datetime, CustomerID int, CustomerID int, ItemList xml) ItemList xml) xml CREATE TABLE Invoices (InvoiceID int, SalesDate datetime, SalesDate datetime, CustomerID int, CustomerID int, ItemList xml) ItemList xml) xml = ' etc. ' = CAST(' etc. ') AS xml CAST(' etc. ') AS xml = CAST(' etc. ') AS xml CAST(' etc. ') AS xml = CONVERT(xml,' etc. ') CONVERT(xml,' etc. ') = CONVERT(xml,' etc. ') CONVERT(xml,' etc. ') = CONVERT(xml,' etc.') CONVERT(xml,' etc.')ERROR! = CONVERT(xml,' etc.') CONVERT(xml,' etc.')ERROR! Определение xml типа данных Неявное преобразование Явное преобразование Правильное формирование XML Явное конвертирование
Управление XML схемами CREATE XML SCHEMA COLLECTION cvSchemas AS N' N'
Типизированные XML Создание типизированной колонки CREATE TABLE HumanResources.EmployeeResume (EmployeeID int, Resume xml (cvSchemas)) CREATE TABLE HumanResources.EmployeeResume (EmployeeID int, Resume xml (cvSchemas)) INSERT INTO HumanResources.EmployeeResume VALUES (1, ' '......') INSERT INTO HumanResources.EmployeeResume VALUES (1, ' '......') Вставка XML (соответствие схеме)
Управление XML индексами Создание основного XML индекса CREATE PRIMARY XML INDEX xidx_Item ON Sales.Invoices(ItemList) CREATE PRIMARY XML INDEX xidx_Item ON Sales.Invoices(ItemList) CREATE XML INDEX xidx_ItemPath ON Sales.Invoices(ItemList) USING XML INDEX xidx_Item FOR PATH CREATE XML INDEX xidx_ItemPath ON Sales.Invoices(ItemList) USING XML INDEX xidx_Item FOR PATH Создание вторичного PATH XML индекса CREATE XML INDEX xidx_ItemProp ON Sales.Invoices(ItemList) USING XML INDEX xidx_Item FOR PROPERTY CREATE XML INDEX xidx_ItemProp ON Sales.Invoices(ItemList) USING XML INDEX xidx_Item FOR PROPERTY Создание вторичного PROPERTY XML индекса CREATE XML INDEX xidx_ItemVal ON Sales.Invoices(ItemList) USING XML INDEX xidx_Item FOR VALUE CREATE XML INDEX xidx_ItemVal ON Sales.Invoices(ItemList) USING XML INDEX xidx_Item FOR VALUE Создание вторичного VALUE XML индекса
Использование XQuery SELECT xmlCol.query( ' ' { for $i in /InvoiceList/Invoice for $i in /InvoiceList/Invoice return return } ') ') SELECT xmlCol.query( ' ' { for $i in /InvoiceList/Invoice for $i in /InvoiceList/Invoice return return } ') ') SELECT xmlCol.value( 'int') 'int') SELECT xmlCol.value( 'int') 'int') SELECT xmlCol.exist( SELECT Invoices.query( ' ' {sql:column("StoreName")} {sql:column("StoreName")} ') ') SELECT Invoices.query( ' ' {sql:column("StoreName")} {sql:column("StoreName")} ') ') Запросы Значение Связывание с другими колонками Проверка на существование
Модификация XML 'insert element salesperson {"Bill"} 'insert element salesperson {"Bill"} as first as first into (/InvoiceList/Invoice)[1]') into (/InvoiceList/Invoice)[1]') 'insert element salesperson {"Bill"} 'insert element salesperson {"Bill"} as first as first into (/InvoiceList/Invoice)[1]') into (/InvoiceList/Invoice)[1]') SET xmlCol.modify( replace value of replace value of(/InvoiceList/Invoice/SalesPerson/text())[1] with "Ted"') with "Ted"') SET xmlCol.modify( replace value of replace value of(/InvoiceList/Invoice/SalesPerson/text())[1] with "Ted"') with "Ted"') 'delete 'delete (/InvoiceList/Invoice/SalesPerson)[1]') (/InvoiceList/Invoice/SalesPerson)[1]') 'delete 'delete (/InvoiceList/Invoice/SalesPerson)[1]') (/InvoiceList/Invoice/SalesPerson)[1]') Использование insert Использование replace Использование delete
Использование FOR XML РасширенияОписание Директива ELEMENTS В RAW режиме создаются элементы, а не атрибуты XML Поддержка NULL Результат может включать пустые элементы для null значений Inline XSD schemas Вы можете создать встроенную XSD схему TYPE directive returns results as xml data type Результат для FOR XML запроса может содержать xml values PATH режим Вы можете использовать XPath ROOT директива Позволяет задать root элемент Именованные элементы Имеется возможность задавать имена в RAW и PATH режимах
Использование OPENXML РасширенияОписание Документы могут содержать xml Процедура sp_xml_preparedocument разрешает xml параметры Поддержка типа xml в WITH Колонки типа xml могут возвращаться с помощью WITH Блок – область видимости Уничтожение документа в конце блока
Интеграция с CLR
SQL Server 2005 и CLR Запуск кода в базе данных, используя встроенные сборки Создание управляемых процедур, триггеров, функций, типов и агрегатов Преимущества: Расширение программной модели Общее окружение для разработки Производительность и расширяемость
Управляемый код vs. Transact-SQL Использование управляемого кода для: Процедур со сложной логикой Доступа к.NET Framework библиотеке Использование Transact-SQL для доступа к данным в методах с простой логикой
Импорт сборок Создайте объект БД для сборки 1 1 Свяжите объект со сборкой 2 2 Установите разрешения 3 3 CREATE ASSEMBLY HelperLibrary CREATE ASSEMBLY Contacts CREATE ASSEMBLY HelperLibrary CREATE ASSEMBLY Contacts CREATE ASSEMBLY HelperLibrary FROM '\\Server1\Private\AProject\bin\HelperLibrary.dll' CREATE ASSEMBLY Contacts FROM 'C:\AProject\bin\Contacts.dll' CREATE ASSEMBLY HelperLibrary FROM '\\Server1\Private\AProject\bin\HelperLibrary.dll' CREATE ASSEMBLY Contacts FROM 'C:\AProject\bin\Contacts.dll' CREATE ASSEMBLY HelperLibrary FROM '\\Server1\Private\AProject\bin\HelperLibrary.dll' WITH PERMISSION_SET SAFE -- default value CREATE ASSEMBLY Contacts FROM 'C:\AProject\bin\Contacts.dll' WITH PERMISSION_SET EXTERNAL_ACCESS CREATE ASSEMBLY HelperLibrary FROM '\\Server1\Private\AProject\bin\HelperLibrary.dll' WITH PERMISSION_SET SAFE -- default value CREATE ASSEMBLY Contacts FROM 'C:\AProject\bin\Contacts.dll' WITH PERMISSION_SET EXTERNAL_ACCESS
Использование сборок Используйте соответствующее Create выражение 1 1 Свяжите объект со сборкой 2 2 Используйте созданный объект 3 3 CREATE PROCEDURE Person.UpdatePhoneList AS EXTERNAL NAME Contacts.PhoneList.SaveList GO CREATE PROCEDURE Person.UpdatePhoneList AS EXTERNAL NAME Contacts.PhoneList.SaveList GO CREATE PROCEDURE Person.UpdatePhoneList AS EXTERNAL NAME Contacts. PhoneList.SaveList GO EXEC Person.UpdatePhoneList CREATE PROCEDURE Person.UpdatePhoneList AS EXTERNAL NAME Contacts. PhoneList.SaveList GO EXEC Person.UpdatePhoneList
Использование VS.NET
Создание хранимой процедуры Создайте открытый метод 1 1 Добавьте SqlProcedure атрибут для развертывания 2 2 Создайте логику хранимой процедуры 3 3 public class ContactCode { public static void GetContactNames() { } public class ContactCode { public static void GetContactNames() { } public class ContactCode { [SqlProcedure(Name="GetContactNames")] public static void GetContactNames() { } public class ContactCode { [SqlProcedure(Name="GetContactNames")] public static void GetContactNames() { } public class ContactCode { [SqlProcedure(Name="GetContactNames")] public static void GetContactNames() { SqlCommand cmd = SqlContext.GetCommand(); cmd.CommandText = "SELECT FirstName + ' ' + LastName" + " AS [Name] FROM Person.Contact"; SqlDataReader rdr = cmd.ExecuteReader(); SqlPipe sp = SqlContext.GetPipe(); sp.Send(rdr); } public class ContactCode { [SqlProcedure(Name="GetContactNames")] public static void GetContactNames() { SqlCommand cmd = SqlContext.GetCommand(); cmd.CommandText = "SELECT FirstName + ' ' + LastName" + " AS [Name] FROM Person.Contact"; SqlDataReader rdr = cmd.ExecuteReader(); SqlPipe sp = SqlContext.GetPipe(); sp.Send(rdr); }
Создание триггеров Создайте открытый статический метод 1 1 Добавьте SqlTrigger атрибут 2 2 Создайте логику 3 3 public class ContactCode { public static void Change () { } public class ContactCode { public static void Change () { } public class ContactCode { [SqlTrigger(Name="ContactUpdTrg", Target="Person.Contact", Event="FOR UPDATE")] public static void Change () { } public class ContactCode { [SqlTrigger(Name="ContactUpdTrg", Target="Person.Contact", Event="FOR UPDATE")] public static void Change () { } public class ContactCode { [SqlTrigger(Name="ContactUpdTrg", Target="Person.Contact", Event="FOR UPDATE")] public static void Change () { SqlTriggerContext trg = SqlContext.GetTriggerContext(); if (trg.TriggerAction == TriggerAction.Update) { if (trg.ColumnsUpdated[7] == true) //send to each new contact } public class ContactCode { [SqlTrigger(Name="ContactUpdTrg", Target="Person.Contact", Event="FOR UPDATE")] public static void Change () { SqlTriggerContext trg = SqlContext.GetTriggerContext(); if (trg.TriggerAction == TriggerAction.Update) { if (trg.ColumnsUpdated[7] == true) //send to each new contact }
Создание функций Создайте открытый статический метод 1 1 Добавьте SqlFunction атрибут 2 2 Реализуйте логику 3 3 public class MyFunctions { public static SqlString GetLongDate(SqlDateTime DateVal) { } public class MyFunctions { public static SqlString GetLongDate(SqlDateTime DateVal) { } public class MyFunctions { [SqlFunction(Name="GetLongDate" )] public static SqlString GetLongDate(SqlDateTime DateVal) { } public class MyFunctions { [SqlFunction(Name="GetLongDate" )] public static SqlString GetLongDate(SqlDateTime DateVal) { } public class MyFunctions { [SqlFunction(Name="GetLongDate" )] public static SqlString GetLongDate(SqlDateTime DateVal) { // Return the date as a long string return DateVal.Value.ToLongDateString(); } public class MyFunctions { [SqlFunction(Name="GetLongDate" )] public static SqlString GetLongDate(SqlDateTime DateVal) { // Return the date as a long string return DateVal.Value.ToLongDateString(); }
Создание агрегатов Создайте открытый класс 1 1 Добавьте Serializable и SqlUserDefinedAggregate атрибуты 2 2 Создайте Init, Accumulate, Merge и Terminate методы 3 3 public class CommaDelimit { } public class CommaDelimit { } [Serializable, SqlUserDefinedAggregate(…)] public class CommaDelimit { } [Serializable, SqlUserDefinedAggregate(…)] public class CommaDelimit { } [Serializable, SqlUserDefinedAggregate(…)] public class CommaDelimit { public void Init() {…} public void Accumulate(SqlString Value) {…} public void Merge(CommaDelimit Group) {…} public SqlString Terminate() {…} } [Serializable, SqlUserDefinedAggregate(…)] public class CommaDelimit { public void Init() {…} public void Accumulate(SqlString Value) {…} public void Merge(CommaDelimit Group) {…} public SqlString Terminate() {…} }
Создание типов Создайте открытый класс или структуру 1 1 Добавьте Serializable и SqlUserDefinedType атрибуты 2 2 Обработайте NULL 3 3 Поддержка преобразования к строкам 4 4 Предоставьте открытые свойства для доступа к закрытым данным 5 5
Развертывание объектов Используйте атрибуты 1 1 Используйте Deploy меню 2 2 [SqlProcedure(Name="ProcName")] public static void Proc ( )
ADO.NET 2.0 Новые возможности SQL Server 2005 Asynchronous data access Multiple active result sets (MARS) Bulk copy operations Batch updates Notifications Snapshot isolation mode Support for SQL Server 2005 data types
ASP.NET 2.0
DataSource – еще меньше кода Новые элементы управления Задавайте параметры в описании Используйте конфигурационный файл
GridView Замена DataGrid Использует источники данных Улучшенная сортировка и разбиение на страницы
DetailView Информация о текущей записи
Data Connections
Вопросы
© 2004 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.