Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

Лекция 22. Доступ к данным из прикладных программ Продолжительность- 2 часа 90 мин

Работа добавлена на сайт samzan.net: 2016-03-13

Поможем написать учебную работу

Если у вас возникли сложности с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой - мы готовы помочь.

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 21.5.2024


  1.  Лекция № 22. Доступ к данным из прикладных программ

Продолжительность: 2 часа (90 мин.)

  1.   Ключевые вопросы
  •  Доступ к данным из прикладных программ.
  •  ODBC.
  •  JDBC.
  •  OLE DB.

  1.  Текст лекции
    1.  Использование специализированных библиотек и встраиваемого SQL — до 10 мин.

Каждая СУБД помимо интерактивной SQL-утилиты обязательно имеет библиотеку доступа и набор драйверов для различных операционных систем. Схема взаимодействия клиентского приложения с сервером базы данных в этом случае выглядит, как показано на рисунке 23.1.

 

Рисунок 23.1 — Схема взаимодействия клиентского приложения с сервером БД

Библиотека доступа — это, как правило, объектный файл, исходный код которого создан на универсальном языке типа C. Эта библиотека содержит набор функций, позволяющих пользовательскому приложению соединяться с базой данных, передавать запросы серверу и получать ответные данные.

Программа, обеспечивающая взаимодействие пользователя с СУБД, компилируется совместно с библиотекой доступа. Библиотечные вызовы преобразуются драйвером базы данных в сетевые вызовы и передаются сетевым программным обеспечением на сервер.

На сервере происходит обратный процесс преобразования: сетевые пакеты -> функции библиотеки -> SQL-запросы, запросы обрабатываются, их результаты передаются клиенту.

Такой способ создания приложений чрезвычайно гибок, позволяет реализовать практически любое приложение, но в то же время имеет явные недостатки:

  •  разработка клиентской программы возможна только для той операционной системы и на том языке программирования, который поддерживается библиотекой
  •  необходим драйвер базы данных, который определяет допустимые типы сетевых интерфейсов
  •  большой объем кодирования
  •  не стандартизованные библиотечные функции.

В результате получаем приложение, которое привязано как к сетевой среде, так и к программно-аппаратной платформе и используемой базе данных.

Некоторой модификацией данного способа является использование "встроенного" языка SQL. В этом случае в текст программы на языке третьего поколения включаются не вызовы библиотек, а непосредственно предложения SQL, которые предваряются ключевым выражением "EXEC SQL". Перед компиляцией в машинный код такая программа обрабатывается препроцессором, который транслирует смесь операторов "собственного" языка СУБД и операторов SQL в "чистый" исходный код. Затем коды SQL замещаются вызовами соответствующих процедур из библиотек исполняемых модулей, служащих для поддержки конкретного варианта СУБД.

Такой подход позволил несколько снизить степень привязанности к СУБД, например, при переключении прикладной программы на работу с другим сервером базы данных достаточно было заново обработать ее исходный текст новым препроцессором и перекомпилировать.

  1.  CLI - интерфейс уровня вызовов — до 10 мин.

Большим достижением явилось появление в 1994 г. в стандарте SQL интерфейса уровня вызова CLI (Call Level Interface), в котором стандартизован общий набор рабочих процедур, обеспечивающий совместимость со всеми основными серверами баз данных. Ключевой элемент CLI - специальная библиотека для компьютера-клиента, в которой хранятся вызовы процедур и большинство часто используемых сетевых компонентов для организации связи с сервером. Это ПО поставляется разработчиком средств SQL, не является универсальным и поддерживает разнообразные транспортные протоколы.

Использование программных вызовов позволяет свести к минимуму операции на компьютере-клиенте. В общем случае клиент формирует оператор языка SQL в виде строки и пересылает ее на сервер посредством процедуры исполнения (execute). Когда же сервер в качестве ответа возвращает несколько строк данных, клиент считывает результат с помощью серии вызовов процедуры выборки данных. Далее информация из столбцов полученной таблицы может быть связана с соответствующими переменными приложения. Вызов специальной процедуры позволяет клиенту определить считанное число строк, столбцов и типы данных в каждом столбце.

Интерфейс CLI построен таким образом, что перед передачей запроса серверу клиент не должен заботиться о типе оператора SQL, будь то выборка, обновление, удаление или вставка.

  1.  ODBC - открытый интерфейс к базам данных на платформе Microsoft Windows — до 15 мин.

Очень важный шаг к созданию переносимых приложений обработки данных сделала фирма Microsoft, опубликовавшая в 1992 году спецификацию ODBC (Open Database Connectivity - открытого интерфейса к базам данных), предназначенную для унификации доступа к данным с персональных компьютеров работающих под управлением операционной системы Windows. (Заметим, что ODBC опирается на спецификации CLI). Структурная схема доступа к данным с использованием ODBC приведена на рисунке 23.2.

ODBC представляет из себя программный слой, унифицирующий интерфейс приложений с базами данных. За реализацию особенностей доступа к каждой отдельной СУБД отвечает специальный ODBC-драйвер. Пользовательское приложение этих особенностей не видит, т.к. взаимодействует с универсальным программным слоем более высокого уровня. Таким образом, приложение становится в значительной степени независимым от СУБД. Однако, этот способ также не лишен недостатков:

  •  приложения становятся привязанными к платформе MS Windows
  •  увеличивается время обработки запросов (как следствие введения дополнительного программного слоя)
  •  необходимо предварительная инсталляция ODBC-драйвера и настройка ODBC (указание драйвера, сетевого пути к серверу, базы данных и т.д.) на каждом рабочем месте. Параметры этой настройки являются статическими, т.е. приложение их самостоятельно изменить не может.

Рисунок 23.2 — Структурная схема доступа к данным с использованием ODBC

  1.  JDBC - мобильный интерфейс к базам данных на платформе Java — до 5 мин.

JDBC (Java DataBase Connectivity) — это интерфейс прикладного программирования (API) для выполнения SQL-запросов к базам данных из программ, написанных на языке Java. Напомним, что язык Java, созданный компанией Sun, является платформенно-независимым и позволяет создавать как собственно приложения (standalone application), так и программы (апплеты), встраиваемые в web-страницы.

JDBC во многом подобен ODBC, также построен на основе спецификации CLI, однако имеет ряд отличий. Во-первых, приложение загружает JDBC-драйвер динамически, следовательно, администрирование клиентов упрощается, более того, появляется возможность переключаться на работу с другой СУБД без перенастройки клиентского рабочего места. Во-вторых, JDBC, как и Java в целом, не привязан к конкретной аппаратной платформе, следовательно, проблемы с переносимостью приложений практически снимаются. В-третьих, использование Java-приложений и связанной с ними идеологии "тонких клиентов" обещает снизить требования к оборудованию клиентских рабочих мест.

  1.  OLE DB — до 20 мин.

OLE DB представляет собой набор COM-интерфейсов (Component Object Model), которые предоставляют приложению-клиенту унифицированный доступ к различным источникам данных.

Можно сказать, что OLE DB — это метод доступа к любым данным через стандартные COM-интерфейсы, вне зависимости от типа данных и места их расположения. В качестве данных могут выступать базы данных, простые документы, таблицы Excel и любые другие источники данных. В отличие от доступа, предоставляемого посредством драйверов OBDC, OLE DB позволяет реализовывать доступ к источникам данных, как с применением языка SQL (к SQL-серверам), так и к любым другим произвольным источникам данных.

Средства, предоставляющие доступ к источнику данных с использованием технологии OLE DB, называются OLE DB провайдерами. Программы-клиенты, использующие для доступа OLE DB провайдеры, называются потребителями данных.

В том случае, если существует только ODBC-драйвер для доступа к конкретному источнику данных, то для применения технологии OLE DB можно использовать OLE DB провайдер, предназначенный для доступа к ODBC-источнику данных.

Так как архитектура OLE DB основана на COM, то механизм создания результирующих наборов состоит из последовательностей шагов типа: создание объекта -> запрос указателя на интерфейс созданного объекта -> вызов метода интерфейса.

Аналогично комплексу действий, который производится после создания результирующего набора при применении технологии ODBC — выполнению связывания, в технологии OLE DB используется механизм аксессоров. Аксессоры описывают, каким образом данные записываются в область памяти потребителя данных, устанавливая адресное соответствие между областью памяти в буфере потребителя данных и столбцами данных в результирующем наборе. Иногда такой набор связей называют картой столбцов (column map).

Объектная модель OLE DB

Спецификация OLE DB описывает набор интерфейсов, реализуемых объектами OLE DB. Каждый объектный тип определен как набор интерфейсов. Спецификация OLE DB определяет набор интерфейсов базового уровня, которые должны реализовываться любыми OLE DB провайдерами.

В базовую модель OLE DB входят следующие объекты:

  •  объект DataSource (источник данных), используемый для соединения с источником данных и создания одного или нескольких сеансов. Этот объект управляет соединением, использует информацию о полномочиях и аутентификации пользователя;
  •  объект Session (сеанс) управляет взаимодействием с источником данных - выполняет запросы и создает результирующие наборы. Сеанс также может возвращать метаданные. В сеансе может создаваться одна или несколько команд;
  •  объект Rowset (результирующий набор) представляет собой данные, извлекаемые в результате выполнения команды или создаваемые в сеансе.

Спецификация OLE DB определяет объект Command (команда), предназначенный для выполнения текстовой команды. В качестве такой команды может выступать и SQL-оператор. При этом выполнение команды может создавать результирующий набор (в случае SQL-оператора - это оператор SELECT).

Некоторые OLE DB провайдеры поддерживают работу со схемой (Schema), которая предоставляет метаданные по базе данных. Метаданные становятся доступны как обычные результирующие наборы. В заголовочном файле oledb.h содержатся уникальные идентификаторы всех доступных типов результирующих наборов схемы данных (например, для получения информации по таблицам базы данных следует указать уникальный идентификатор DBSCHEMA_TABLES). Столбец результирующего набора с именем TABLE_NAME содержит имя таблицы, столбец TABLE_TYPE указывает один из следующих типов таблицы: ALIAS, TABLE, SYNONYM, SYSTEM TABLE, VIEW, GLOBAL TEMPORARY, LOCAL TEMPORARY, SYSTEM VIEW.

Представление (View) определяет подмножество строк и столбцов из набора данных, но само не содержит их. Представления не могут объединять данные из нескольких наборов данных.

Для обеспечения расширенных возможностей управления транзакциями объектная модель OLE DB включает объект Transaction.

OLE DB провайдеры, как и все COM-компоненты, регистрируются в реестре Windows. Для поиска информации о зарегистрированных источниках данных используются специальные объекты, называемые нумераторами. Нумератор — это обычный СОМ-сервер, позволяющий получить информацию об источниках данных в виде результирующего набора. Для создания такого результирующего набора в объектном типе DataSource специфицирован интерфейс IDBEnumerateSources.

Для каждого объектного типа спецификация OLE DB определяет набор интерфейсов, который должен обязательно быть реализован для данного объекта. Такие интерфейсы отмечаются как [mandatory]. Интерфейсы, которые могут отсутствовать, отмечаются как [optional].

Для объекта "источник данных" специфицирован следующий набор интерфейсов:

CoType TDataSource {

  [mandatory]   interface IDBCreateSession;

  [mandatory]   interface IDBInitialize;

  [mandatory]   interface IDBProperties;

  [mandatory]   interface IPersist;

  [optional]    interface IConnectionPointContainer;

  [optional]    interface IDBAsynchStatus;

  [optional]    interface IDBDataSourceAdmin;

  [optional]    interface IDBInfo;

  [optional]    interface IPersistFile;

  [optional]    interface ISupportErrorInfo;

}

Для объекта "сеанс" специфицирован следующий набор интерфейсов:

CoType TSession {

 [mandatory]   interface IGetDataSource;

 [mandatory]   interface IOpenRowset;  // Создание набора данных

 [mandatory]   interface ISessionProperties;

 [optional]    interface IAlterIndex;

 [optional]    interface IAlterTable;

 [optional]    interface IBindResource;

 [optional]    interface ICreateRow;

 [optional]    interface IDBCreateCommand;

 [optional]    interface IDBSchemaRowset;

 [optional]    interface IIndexDefinition;

 [optional]    interface ISupportErrorInfo;

 [optional]    interface ITableCreation;

 [optional]    interface ITableDefinition;  // Для создания таблицы

 [optional]    interface ITableDefinitionWithConstraints;

 [optional]    interface ITransaction;

 [optional]    interface ITransactionJoin;

 [optional]    interface ITransactionLocal;

 [optional]    interface ITransactionObject;

}

Для объекта "результирующий набор" специфицирован следующий набор интерфейсов:

CoType TRowset {

 [mandatory]   interface IAccessor;

  [mandatory]   interface IColumnsInfo;

  [mandatory]   interface IConvertType;

  [mandatory]   interface IRowset;// Последовательное

                                  // чтение таблицы

  [mandatory]   interface IRowsetInfo;

  [optional]    interface IChapteredRowset;

  [optional]    interface IColumnsInfo2;

  [optional]    interface IColumnsRowset;

  [optional]    interface IConnectionPointContainer;

  [optional]    interface IDBAsynchStatus;

  [optional]    interface IGetRow;

  [optional]    interface IRowsetChange;  // Для удаления, изменения и добавления

                  // строк в набор данных

  [optional]    interface IRowsetChapterMember;

  [optional]    interface IRowsetCurrentIndex;

  [optional]    interface IRowsetFind;

  [optional]    interface IRowsetIdentity;

  [optional]    interface IRowsetIndex;

  [optional]    interface IRowsetLocate;  // Прямое

          // позиционирование на запись набора данных

  [optional]    interface IRowsetRefresh;  // Для

       // обновления данных в созданном наборе данных

  [optional]    interface IRowsetScroll; // Поддержка

                       // скроллинга по набору данных

  [optional]    interface IRowsetUpdate;

  [optional]    interface IRowsetView;

  [optional]    interface ISupportErrorInfo;

  [optional]    interface IRowsetBookmark;

}

Все объекты объектного типа Rowset должны реализовывать следующие интерфейсы:

  •  интерфейс IRowset, используемый для извлечения строк;
  •  интерфейс IAccessor, используемый для определения связывания;
  •  интерфейс IColumnsInfo, предоставляющий информацию о столбцах результирующего набора;
  •  интерфейс IRowsetInfo, предоставляющий информацию о самом результирующем наборе;
  •  интерфейс IConvertType, предоставляющий информацию о преобразовании типов данных, поддерживаемых в результирующем наборе.

Создание результирующего набора

При реализации доступа к БД посредством OLE DB провайдера сначала следует создать объект данных и установить соединение с базой данных. Далее необходимо создать объект "сеанс". И только потом можно создавать результирующий набор.

Результирующий набор может быть создан одним из следующих способов:

  •  Для объекта "сеанс" вызывается метод IOpenRowset::OpenRowset, выполняющий непосредственное создание результирующего набора (интерфейс IOpenRowset должен поддерживаться любым провайдером);
  •  Для объекта "сеанс" вызывается метод IDBCreateCommand::CreateCommand, создающий объект Command. Далее для объекта "команда" вызывается метод ICommand::Execute. (при использовании интерфейса IMultipleResults можно работать с несколькими результирующими наборами);
  •  Вызывается один из следующих методов IColumnsRowset::GetColumnsRowset, IDBSchemaRowset::GetRowset, IViewRowset::OpenViewRowset или ISourcesRowset::GetSourcesRowset.

Чтобы результирующий набор, хранимый на сервере, можно было использовать, необходимо выполнить связывание и извлечение данных. Для этого следует определить структуры типа DBBINDING, описывающие столбцы, и создать аксессор. Далее для получения строк результирующего набора можно использовать один из следующих методов:

  •  IRowset::GetNextRows;
  •  IRowsetLocate::GetRowsByBookMarks;
  •  IRowsetLocate::GetRowAt;
  •  IRowsetScroll:: GetRowAtRatio.

В заключение для записи данных в структуру, определенную аксессором, вызывается метод IRowset::GetData.

После получения и обработки строк их следует освободить, вызвав метод IRowset::ReleaseRows.

После просмотра всего результирующего набора следует также освободить аксессор, вызвав метод IRowset::ReleaseAccessor, и освободить сам результирующий набор, вызвав метод IRowset::Release.

Интерфейс IAccessor определяет следующие методы:

  •  AddRefAccessor - увеличивает число ссылок на данный аксессор;
  •  CreateAccessor - создает аксессор из набора связываний;
  •  GetBindings - возвращает связывания, установленные данным аксессором;
  •  ReleaseAccessor - освобождает аксессор.

Для создания аксессора следует запросить интерфейс IAccessor и выполнить следующий код:

HRESULT hr=pIAccessor-> CreateAccessor();

Метод CreateAccessor имеет следующее формальное описание:

HRESULT CreateAccessor (

  DBACCESSORFLAGS  dwAccessorFlags, // Свойства

                   // аксессора и как он используется

  DBCOUNTITEM      cBindings,  // Число связей

                                 // в аксессоре

  const DBBINDING  rgBindings[],  // Описание

                             // столбца или параметра

  DBLENGTH         cbRowSize,  // Число байтов,

         // используемых для одного набора параметров

  HACCESSOR       *phAccessor,  // Указатель

                              //на созданный аксессор

  DBBINDSTATUS     rgStatus[]);  // Массив значений,

                               // определяющий статус

                               // каждого связывания

Каждый столбец формируемого результирующего набора или параметр описывается структурой DBBINDING, которая имеет следующее формальное описание:

typedef struct tagDBBINDING {

DBORDINAL      iOrdinal;     // Порядковый номер

              // столбца или параметра (начиная с 1)

  DBBYTEOFFSET   obValue;  // Сдвиг в байтах для

           // значения столбца или параметра в буфере

      // (указатель на буфер задается при

      // создании аксессора)

  DBBYTEOFFSET   obLength;

  DBBYTEOFFSET   obStatus;

  ITypeInfo     *pTypeInfo;

  DBOBJECT      *pObject;

  DBBINDEXT     *pBindExt;

  DBPART         dwPart;

  DBMEMOWNER     dwMemOwner;

  DBPARAMIO      eParamIO;

  DBLENGTH       cbMaxLen;

  DWORD          dwFlags;

  DBTYPE         wType;

  BYTE           bPrecision;

  BYTE           bScale;

} DBBINDING;

Поле wType определяет тип столбца или параметра, который описывается следующим образом:

typedef WORD DBTYPE;

enum DBTYPEENUM {

// Следующие значения точно соответствуют VARENUM

// при автоматизации и не могут быть использованы

// как VARIANT.

  DBTYPE_EMPTY = 0, // Значение отсутствует,

   // соответствующего типа С нет

  DBTYPE_NULL = 1, // Значение равно NULL,

   // соответствующего типа С нет

  DBTYPE_I2 = 2,     // Двухбайтовое целое со знаком,

      // соответствует С типу short

  DBTYPE_I4 = 3, // Четырехбайтовое целое со знаком,

        // соответствует С типу long

  DBTYPE_R4 = 4,

  DBTYPE_R8 = 5, // Вещественное двойной точности,

      // соответствует С типу Double

  DBTYPE_CY = 6,   // Тип для значения Cyrrency

  DBTYPE_DATE = 7,  // Тип для значения даты

    // (дата хранится в виде вещественного числа:

    // целочисленная часть определяет дату,

    // а дробная - время)

  DBTYPE_BSTR = 8,  // Указатель на строку BSTR

  DBTYPE_IDISPATCH = 9, // Указатель на интерфейс

                        // IDispatch

  DBTYPE_ERROR = 10,   // 32-битовый код ошибки

  DBTYPE_BOOL = 11,   // Для логического значения

  DBTYPE_VARIANT = 12, // Для значения VARIANT

  DBTYPE_IUNKNOWN = 13, // Указатель на интерфейс

                        // IUnknown

  DBTYPE_DECIMAL = 14,

  DBTYPE_UI1 = 17, // Однобайтовое беззнаковое целое,

        // соответствует С типу byte

  DBTYPE_ARRAY = 0x2000,

  DBTYPE_BYREF = 0x4000,

  DBTYPE_I1 = 16,

  DBTYPE_UI2 = 18,

  DBTYPE_UI4 = 19,

// Следующие значения точно соответствуют VARENUM

// при автоматизации, но не могут быть использованы

// как VARIANT.

  DBTYPE_I8 = 20,

  DBTYPE_UI8 = 21,

  DBTYPE_GUID = 72,    // Для уникального

     идентификатора GUID

  DBTYPE_VECTOR = 0x1000,

  DBTYPE_FILETIME = 64,

  DBTYPE_RESERVED = 0x8000,

// Следующие значения недопустимы в VARENUM для OLE.

  DBTYPE_BYTES = 128,

  DBTYPE_STR = 129,

  DBTYPE_WSTR = 130,

  DBTYPE_NUMERIC = 131,

  DBTYPE_UDT = 132,

  DBTYPE_DBDATE = 133,// Для даты, определяемой

             // как структура

  // Typedef struct tagDBDATE {

     //    SHORT      year;

     //    USHORT     month;

     //    USHORT     day;

     //    } DBDATE;

  DBTYPE_DBTIME = 134,

  DBTYPE_DBTIMESTAMP = 135 // Для даты и времени,

     // определяемых как структура

     // Typedef struct tagDBTIMESTAMP {

     //   SHORT   year;

     //   USHORT  month;

     //   USHORT  day;

     //   USHORT  hour;

     //   USHORT  minute;

     //   USHORT  second;

     //   ULONG   fraction;

     } DBTIMESTAMP;

  DBTYPE_HCHAPTER = 136

  DBTYPE_PROPVARIANT = 138,

  DBTYPE_VARNUMERIC = 139

};

Объекты COMMAND

Перед использованием объекта Command следует определить, поддерживается ли данный объект. Для этого с помощью метода QueryInterface следует запросить интерфейс IDBCreateCommand объекта "сеанс".

Объект Command должен реализовывать следующие интерфейсы:

  •  Icommand;
  •  Iaccessor;
  •  IcommandText;
  •  IcolumnInfo;
  •  ICommandProperties.

Для создания команды вызывается метод IDBCreateCommand::CreateCommand объекта "сеанс".

Например:

ICommandText pICommandText;

HRESULT hr= pIDBCreateCommand-> CreateCommand(

  NULL,  // если есть агрегирование, то указатель

                              // на управляющий IUnknown

  IID_ICommandText, // Запрашиваемый интерфейс

    (IUnknown**)& pICommandText); // Указатель

                                              // на запрашиваемый интерфейс

Текст, выполняемый командой, устанавливается при вызове метода ICommandText::SetCommandText. При этом указывается уникальный идентификатор GUID синтаксиса команды (например, DBGUID_SQL (только для версий OLE DB начиная с 1.5)).

Например:

pICommandText->SetCommandText(DBGUID_SQL,

                          "SELECT * FROM TBL1");

Для выполнения команды вызывается метод ICommand::Execute (этот метод наследуется интерфейсом ICommandText).

Например:

ULONG ulRs=0;

IRowset** ppRowsets=NULL;

HRESULT hr= pICommandText->Execute (

  NULL, // если есть агрегирование, то указатель

                              // на управляющий IUnknown

  IID_IRowset, // Запрашиваемый интерфейс

  NULL, // Указатель на структуру типа

   // struct DBPARAMS {

   //   void      *pData;

   //  DB_UPARAMS cParamSets;

    //  HACCESSOR  hAccessor;

   //};

  ulRs, // Количество строк, на которые

                           // воздействовала команда INSERT, UPDATE 

          //или DELETE

  (IUnknown**)& ppRowsets);  // Указатель на

                                      // указатели наборов данных

До выполнения команды можно определить поведение создаваемого результирующего набора вызовом метода ICommandProperties::SetProperties.

Для многократного выполнения запроса и при использовании параметров следует вызвать метод ICommandPrepare::Prepare, а затем определить параметры вызовом метода ICommandWithParameters::SetParameterInfo.

Если в результате выполнения команды возвращается несколько результирующих наборов, то используется метод IMultipleResults::GetResult.

Объекты TRANSACTION

Применение OLE DB позволяет поддерживать простые, вложенные и распределенные транзакции.

Объект Session для работы с транзакциями поддерживает следующие интерфейсы:

  •  интерфейс ITransactionLocal. Для начала транзакции вызывается метод ITransactionLocal::StartTransaction(). Если этот метод вызывается из активной транзакции, то открывается новая вложенная транзакция;
  •  интерфейс ITransaction, поддерживающий методы Abort, Commit и GetTransactionInfo;
  •  интерфейс ITransactionJoin, реализующий поддержку распределенных транзакций.

Объект Transaction позволяет реализовывать более широкие возможности управления транзакциями, поддерживая следующие интерфейсы:

  •  ITransaction, позволяющий выполнить прерывание транзакции (методы Abort, Commit, GetTransactionInfo);
  •  IConnectionPointContainer, поддерживающий управление точками соединения для соединяемых объектов.

  1.  Обращение к базе данных с использованием технологии ADO — до 20 мин.

Технология Active Data Objects (ADO) - это программное расширение технологии активных серверных страниц ASP, реализованное в Web-сервере Internet Information Server (IIS) компании Microsoft с целью организации подключений к базам данных. В технологии ADO поддерживаются следующие основные функции:

  •  независимо создаваемые объекты;
  •  поддержка хранимых процедур с входными, выходными и возвращаемыми параметрами;
  •  курсоры различных типов (включая возможность поддержки разных специальных курсоров конечных пользователей);
  •  пакетное обновление;
  •  поддержка ограничений для числа возвращаемых строк или других параметров запроса;
  •  поддержка нескольких наборов данных, возвращаемых хранимыми процедурами или пакетными операторами.

Основными преимуществами технологии ADO является простота использования, высокая скорость, небольшие потребности в оперативной памяти и незначительные затраты дисковой памяти.

Объектная модель ADO определяет набор (коллекцию) программируемых объектов, которые могут применяться с Visual Basic, Visual C++, VBScript. Объектная модель ADO разработана для выполнения большинства особенностей интерфейса OLE DB.

Если при помощи интерфейса ODBC операционная система осуществляет, как правило, доступ к реляционным БД, использующим структурированный язык запросов SQL, то интерфейс OLE DB (Object Linking and Embedding for DataBases) является более универсальной технологией для доступа к любым источникам данных.

В интерфейс OLE DB включен механизм провайдеров, под которыми понимаются поставщики данных, находящиеся в надстройке над физическим форматом данных. Их называют сервис-провайдерами, они помогают объединять в однотипную совокупность объекты, связанные с разнообразными источниками данных.

Интерфейс OLE DB может использовать для доступа к источникам данных интерфейс ODBC. В этом случае применяется провайдер OLE DB для доступа к ODBC-данным. Таким образом, интерфейс OLE DB не заменяет интерфейс ODBC, а позволяет организовать доступ к источникам данных через различные интерфейсы, и в том числе через ODBC.

ADO содержит семь объектов, которые инкапсулируют в себе большинство операций с базой данных - Connection (соединение), Command (команда), Parameter (параметр), Recordset (набор данных), Field (поле), Property (свойство) и Error (ошибка), - а также четыре набора объектов (коллекции) - Fields (поля), Properties (свойства), Parameters (параметры) и Errors (ошибки).

Объект Connection устанавливает коммуникационную связь между приложением и источником данных, позволяет выполнять команды. Класс Connection включает следующие методы:

  •  Open (Close) - установление (закрытие) физического соединения с источником данных;
  •  Execute - выполнение команды для этого соединения;
  •  BeginTrans, CommitTrans, RollbackTrans - управление транзакциями для текущего подключения, включая вложенные транзакции, если источник данных поддерживает работу с ними.

Объект Command. Команда, направляемая в базу данных, как правило, представляет собой SQL-команду или вызов некоторой хранимой процедуры. Объект Command может настраиваться с помощью параметров, задаваемых посредством создания коллекции объектов класса Parameter. Класс Command включает следующие методы:

  •  Execute - выполнение команды для данного соединения;
  •  CreateParameter - создание нового объекта класса Parameter.

Коллекция Parameters. Содержит любые параметры, которые используются вместе с данным объектом Command. Класс Parameters содержит следующие методы:

  •  Append (Delete) - добавление (удаление) параметра для указанной коллекции;
  •  Item - извлечение определенного объекта Parameter.

На некоторый объект Parameter в коллекции Parameters можно ссылаться, используя его порядковый номер или значение, присвоенное свойству Name этого объекта.

Объект Recordset представляет набор записей, полученный в результате выполнения запроса в базе данных. При создании объекта Recordset указатель текущей записи устанавливается на его первую запись (если таковая имеется), а свойствам BOF и EOF присваивается значение FALSE. Если никаких записей нет, то свойству Recordcount присваивается значение 0, а свойствам BOF и EOF - значение TRUE. Класс Recordset включает следующие методы:

  •  MoveFirst, MoveLast, MoveNext, MovePrevious и Move - производят перемещение указателя текущей записи в предположении, что провайдер поддерживает выполнение соответствующей функции. В однонаправленных объектах Recordset поддерживается только метод MoveNext. При использовании указанных методов для перемещения по записям результирующего набора для обнаружения его начала и конца могут применяться свойства BOF и EOF объекта Recordset;
  •  AddNew, Update, Delete - осуществляют добавление новых записей, обновление и удаление имеющихся записей, связанных с открытым объектом;
  •  Open (Close) - выполняют открытие (закрытие) курсора, представляющего результаты выполнения команды.

Коллекция Fields. Объект Recordset содержит коллекцию Fields, состоящую из объектов класса Field, каждый из которых соответствует столбцу данных объекта Recordset. Как и при работе с объектами Parameter, на отдельный объект Field в коллекции Fields можно ссылаться, используя его порядковый номер или имя.

Рассмотрим возможность соединения с базой данных из языков сценариев. ASP-сценарий, работающий с базой данных, в первую очередь должен подключиться к ней. После этого можно выполнять инструкции SQL и создавать наборы записей. Существует специальный объект Connection, управляющий подключением к базе данных.

Объект Connection позволяет устанавливать сеансы связи с источниками данных; он обеспечивает функционирование механизма для инициализации и установления соединения, выполнения запросов и использования транзакций.

Создание соединения с базой данных включает следующие шаги:

  •  сначала вызывается метод CreateObject() объекта Server, создающий объектную переменную cn типа Connection. Объект Connection определен в библиотеке ADODB:

Dim cn

Set cn=Server.CreateObject("ADODB.Connection")

  •  далее можно использовать метод Open объекта Connection для установки соединения c провайдером ODBC. Провайдер определяется посредством установки свойства Provider. Если оно не определено, то по умолчанию будет использован провайдер MSDASQL - это сокращенное название драйвера OLE DB Microsoft для SQL Server:

cn.provider "MSDASQL"

  •  затем вызывается метод Open() объекта Connection, открывающий соединение с заданным источником данных.

Сослаться на базу данных SQL Server из ASP-сценария возможно двумя способами:

  •  путем создания источника данных (DSN);
  •  с помощью строки соединения (без применения DSN).

В первом случае созданный заранее источник данных с именем mystud используется для соединения с базой данных следующим образом:

cn.open "mystud","user1","123"

Здесь для метода Open указывается DSN базы данных, имя пользователя и пароль.

Во втором случае строки соединения содержат всю информацию, необходимую ADO для того, чтобы создать соединение с внешним источником данных. Пример такой строки:

"uid=user1;driver={SQL Server};server=its; database=basa_user1"

Строка создает соединение с базой данных basa_user1 на MS SQL Server с именем its, используя драйвер для SQL Server и имя пользователя user1. Если нужен пароль, то необходимо добавить подстроку pwd=<пароль>:

"uid=user1;pwd=123;driver{SQL Server}; server=its; database=basa_user1"

Такая строка подойдет для соединения с базой данных в тексте сценария вместо источника данных:

cn.open "uid=user1;driver={SQL Server}; server=its; database=basa_user1"

или

cn.open "uid=user1; pwd=123; driver={SQL Server}; server=its;database=basa_user1"

Опустив некоторые подробности работы с API-интерфейсом, приведем небольшой фрагмент сценария на языке VBScript для серверной стороны, выполняющий выборку и изменение информации в базе данных учебного примера.

Dim cn

Dim rst

Set cn=Server.CreateObject("ADODB.Connection")

Set rst=Server.CreateObject("ADODB.Recordset")

cn.open "uid=user1;pwd=123;

   driver={SQL Server};

   server=its;database=basa_user1"

rst.open "SELECT название, тип, цена

   FROM товар", cn

do until rst.eof

   response.write rst.fields(0)

   response.write rst.fields(1)

   response.write rst.fields(2) & "<br>"

   rst.movenext

loop

Для создания динамического запроса изменения данных на сервере воспользуемся объектом Command с параметрами.

Dim cn

Dim rst

Dim cmd

Set cn=Server.CreateObject("ADODB.Connection")

Set rst=Server.CreateObject("ADODB.Recordset")

Set cmd=Server.CreateObject("ADODB.Command")

cn.open "uid=user1;pwd=123;

   driver={SQL Server};

   server=its;database=basa_user1"

Set cmd.ActiveConnection=cn

Dim prm1, prm2

' создание параметров

prm1=Server.CreateObject("ADODB.Parameter")

prm2=Server.CreateObject("ADODB.Parameter")

' определение динамического запроса

cmd.CommandText="update товар set цена=?

   where название=?"

cmd.CommandType=adCmdText

cmd.Prepared=True

' определение параметра, соответствующего

' первому знаку ? в SQL-запросе

Set prm1=сmd.CreateParameter("par1",

   adInteger, adParamInput, , 160)

' определение параметра, соответствующего

' второму знаку ? в SQL-запросе

Set prm2=сmd.CreateParameter("par2", adChar,

   adParamInput,20 , "Трюфели" )

' добавление параметров в коллекцию параметров

cmd.Parameters.Append prm1

cmd.Parameters.Append prm2

' выполнение SQL-запроса

cmd.Execute


  1.  Лекция № 21. Хранимые процедуры, триггеры и представления в Microsoft SQL Server 

Продолжительность: 2 часа (90 мин.)

  1.  Ключевые вопросы
  •  Хранимые процедуры.
  •  Триггеры.
  •  Виды триггеров.
  •  Представления.

  1.  Текст лекции
    1.  Хранимые процедуры — до 20 мин.

Выполнение операций INSERT, SELECT, UPDATE и DELETE, используемых соответственно для добавления, выборки, изменения и удаления данных, не вызывает особых затруднений. Пользователь может написать запрос непосредственно в окне Query Analyzer и выполнить его. Тем не менее, основными клиентами БД являются приложения, специально созданные для выполнения определенных задач. Эти приложения часто реализуют сложные операции, требующие использования множества команд.

Чтобы выполнить такие операции, приложение отсылает на сервер одну или более команд, которые там выполняются. В ответ сервер отправляет клиенту (приложению) результат обработки запроса. Этим результатом может быть как сообщение об успешном завершении выполнения команды, занимающее всего несколько байт, так и огромный массив данных, включающий тысячи строк и занимающий несколько мегабайт. Клиент может обработать полученный результат и на основе своего полученного результата отослать серверу новый запрос.

В рассмотренной ситуации логика обработки данных реализована на клиенте. Сервер просто принимает набор инструкций и выполняет их. При написании приложения разработчик должен позаботиться о разработке запросов, корректно работающих с данными и выполняющих все нужные действия.

Предложенный подход к обработке данных имеет несколько недостатков. Например, если нужно изменить логику обработки данных, то следует изменять исходный код программы, после чего заново компилировать ее и распространять всем пользователям. Кроме того, если одна и та же логика обработки данных используется в нескольких приложениях, то в худшем случае для каждого из этих приложений нужно будет повторять процесс разработки запросов, а в лучшем -переносить код из уже работающего приложения. Также следует обратить внимание на сам процесс взаимодействия сервера и клиента. По-видимому, алгоритмы обработки данных будут реализованы в виде набора блоков команд, поочередно отправляемых на сервер. После выполнения блока команд приложение получает определенный результат, после обработки которого, решается, какой следующий блок и с какими параметрами должен быть выполнен. В некоторых ситуациях обмен между клиентом и сервером наборами команд и результатами может занимать много времени и генерировать большой сетевой трафик, что отрицательно сказывается на работе приложения в целом и на работе других пользователей сети.

В данном контексте необходимо сказать о безопасности. Для выполнения обработки данных пользователь должен иметь соответствующие права доступа. Предполагается, что эти права будут использованы приложением для доступа к данным. Однако нельзя быть до конца уверенным, что пользователь не сможет обратиться к данным напрямую, например, с помощью Query Analyzer, и выполнить неразрешенные действия. Нельзя быть уверенным и в том, что команды, отправляемые приложением, осуществляют верные действия. Ошибка разработчика при создании запроса может иногда привести к повреждению данных. Кроме того, нельзя не учитывать, что злоумышленник или тот же разработчик способны изменит код запроса для получения несанкционированного доступа к данным или для их повреждения, или даже уничтожения.

Все сказанное выше демонстрирует недостатки подхода к разработке систем, когда логика обработки данных реализуется на клиенте. Описанные проблемы могут быть решены за счет переноса алгоритмов обработки данных на сервер. В этом случае приложение просто сообщает серверу, какой именно набор команд необходимо выполнить. Дополнительно могут быть указаны параметры, которые в зависимости от реализации алгоритма будут влиять на ход выполнения процесса обработки данных. При этом приложение сможет получать только конечный результат выполнения. Промежуточные результаты будут обработаны сервером, что позволяет снизить сетевой трафик. Этот набор команд Transact-SQL, сохраненных специальным образом на сервере и выполняемых как одно целое, называется хранимой процедурой (англ. stored procedure).

Использование хранимых процедур позволяет снизить стоимость сопровождения системы и дает возможность избавиться от необходимости изменять клиентские приложения. Если понадобится изменить логику обработки данных, чтобы она отразилась для всех приложений сети, количество которых может насчитывать десятки и сотни, то достаточно будет изменить только хранимую процедуру.

Кроме того, использование хранимых процедур также позволяет значительно повысить безопасность данных. Приложение или пользователь получают лишь специальное право на выполнение хранимой процедуры, которая и будет обращаться к данным. Доступа же к самим данным пользователь не получает. В хранимой процедуре можно реализовать проверки на правильность выполняемых изменений, что обеспечит логическую целостность данных. Также можно реализовать проверки на права пользователя выполнять те или иные действия.

В SQL Server 2000/2005 различают несколько типов хранимых процедур:

  •  системные хранимые процедуры, предназначенные для работы с системными данными;
  •  расширенные хранимые процедуры, представляющие собой динамически подключаемые программы, которые в операционной среде могут играть роль самостоятельного приложения;
  •  пользовательские хранимые процедуры, создаваемые на уровне алгоритмов обработки данных.

  1.  Создание хранимых процедур — до 20 мин.

Созданию хранимой процедуры предшествует этап предварительной работы, в ходе которой необходимо найти решение следующих задач.

Определение типа создаваемой хранимой процедуры. Необходимо решить, будет ли процедура временной или пользовательской. Кроме этого, можно создать свою собственную системную хранимую процедуру, назначив ей имя с префиксом sp_ и поместив ее в системную базу данных master. Такая процедура будет доступна в контексте любой базы данных локального сервера.

Планирование прав доступа. При создании хранимой процедуры следует учитывать, что она будет иметь те же права доступа к объектам базы данных, что имеет создавший ее пользователь. Таким образом, выдавая пользователям права на выполнение процедуры, следует учитывать, что хранимая процедура будет иметь права доступа не того пользователя, который ее запускает, а того, кто ее создал. Более того, хранимая процедура наследует некоторые параметры, которые были установлены во время ее создания. В частности, если во время создания процедуры был разрешен прямой доступ к системным таблицам, то процедура будет всегда иметь возможность обращения к системным данным, даже если впоследствии он будет запрещен.

Определение параметров хранимой процедуры. Подобно процедурам, входящим в состав большинства языков программирования, хранимые процедуры могут иметь входные и выходные параметры. SQL Server позволяет определить для одной хранимой процедуры до 1024 параметров. Полученные процедурой параметры могут использоваться как обыкновенные переменные Transact-SQL, участвуя в любых операциях наравне с другими переменными. Часто хранимая процедура возвращает какой-то результат. В SQL Server имеется несколько способов передачи хранимой процедурой результата своей работы. При разработке процедуры необходимо решить, какой именно метод будет использоваться, в частности, возможна передача результата через параметры хранимой процедуры. Для того чтобы вернуть значение с помощью параметра, необходимо указать ключевое слово OUTPUT при его определении.

Разработка кода хранимой процедуры. Код процедуры может содержать последовательность любых команд Transact-SQL, включая вызов других хранимых процедур.

Включение создаваемой процедуры в группу. Для удобства управления процедурами вы можете группировать логически однотипные хранимые процедуры. Для этого всем процедурам группы при создании дают одинаковые имена, но разные идентификационные номера. Таким образом, получается несколько хранимых процедур, которые обозначаются следующим образом: <имя_процедуры>;<идентификационный_номер>.

Ссылка на группу осуществляется по имени процедур. Например, в группе процедур ##proced отдельные хранимые процедуры могут иметь имена ##proced;1, ##proced;2 и т. д. Достоинство такого подхода заключается в том, что вы можете одновременно управлять сразу всей группой процедур. При этом, например, можно удалить сразу все процедуры, входящие в состав группы. Когда все эти вопросы решены, можно приступать непосредственно к созданию хранимой процедуры. Как и большинство объектов SQL Server, хранимую процедуру можно создать тремя способами:

  •  с помощью средств Transact-SQL;
  •  с помощью Enterprise Manager (SQL Server 2000);
  •  с помощью SQL Server Management Studio (SQL Server 2005);
  •  с помощью мастера Create Stored Procedure Wizard.

Рассмотрим процесс создания хранимой процедуры средствами Transact-SQL с помощью команды CREATE PROCEDURE, имеющей следующий синтаксис:

CREATE PROC[EDURE] procedure_name [; number]

[ {@parameter datatype} [VARYING] [= default] [OUTPUT]][,...n] [WITH {RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION}]

[FOR REPLICATION] AS sql_statement [ ,...n ]

Рассмотрим аргументы команды создания хранимой процедуры.

  •  procedure_name — имя создаваемой процедуры. Используя префиксы sp_, # и ##, можно определить создаваемую процедуру соответственно как системную или временную. Как видно из синтаксиса команды, не допускается указывать имя владельца, которому будет принадлежать создаваемая процедура, а также имя базы данных, в которой должна быть размещена процедура. Таким образом, чтобы разместить создаваемую хранимую процедуру в конкретной базе данных, необходимо выполнять команду CREATE PROCEDURE в контексте этой базы данных. Напомним, что переключить текущую базу данных можно с помощью команды USE. При обращении из тела хранимой процедуры к объектам той же базы данных, в которой расположена процедура, можно использовать укороченные имена, то есть без указания имени базы данных. Когда же требуется обратиться к объектам, расположенным в других базах данных, то указание имени базы данных обязательно.
  •  number — идентификационный номер хранимой процедуры, однозначно определяющий ее в группе процедур.
  •  @parameter — имя параметра, который будет использоваться создаваемой хранимой процедурой для передачи входных или выходных данных. Как и при работе с локальными переменными, имена параметров хранимой процедуры должны начинаться с символа @. В одной хранимой процедуре можно задавать до 1024 параметров, разделив их запятыми. Параметры, определяемые при создании хранимой процедуры, являются своего рода локальными переменными, поэтому различные хранимые процедуры могут иметь абсолютно идентичные параметры. Однако в хранимой процедуре не разрешается использование переменных с именами, совпадающими с именами параметров.
  •  data_type — тип, данных, который будет иметь соответствующий параметр хранимой процедуры. Для определения параметров можно использовать любые типы данных SQL Server, включая типы данных text, ntext и image; а также определенные пользователем типы данных. Однако заметим, что тип данных cursor может быть использован только как выходной параметр хранимых процедур, то есть с указанием ключевого слова OUTPUT.
  •  OUTPUT — наличие этого ключевого слова означает, что соответствующий параметр может быть использован для возвращения данных из хранимой процедуры. Однако это вовсе не означает, что параметр не подходит для передачи значений в хранимую процедуру. Указание ключевого слова OUTPUT предписывает серверу при выходе из хранимой процедуры присвоить текущее значение параметра локальной переменной, которая была указаны при вызове процедуры в качестве значения параметра. Отметим, что при  указании ключевого слова OUTPUT значение соответствующего параметра при вызове процедуры может быть задано только с помощью локальной переменной. Не разрешается использование любых выражений или констант, допустимое для обычных параметров.
  •  VARYING — ключевое слово, которое используется совместно с параметром OUTPUT, имеющим тип данных cursor. Ключевое слово VARYING определяет, что выходным параметром будет результирующее множество.
  •  default — означает значение, которое будет принимать соответствующий параметр по умолчанию. Таким образом, при вызове процедуры можно будет не указывать явно значение соответствующего параметра.
  •  RECOMPILE — при создании хранимой процедуры сервер кэширует план исполнения запроса и компилированный код. Так что при последующем вызове процедуры будут использоваться уже готовые значения. Однако в некоторых случаях все же требуется выполнять перекомпиляцию кода процедуры. Указание данного ключевого слова предписывает системе создавать план выполнения хранимой процедуры при каждом ее вызове.
  •  FOR REPLICATION — это ключевое слово используется при репликации данных и включении создаваемой хранимой процедуры в качестве статьи в публикацию. Когда процедура, созданная с параметром FOR REPLICATION, копируется механизмами репликации на подписчиков, она не может быть выполнена стандартными средствами. Ее вызов осуществляется только подсистемой репликации. Параметр FOR REPLICATION не может указываться совместно с параметром RECOMPILE.
  •  ENCRYPTON — это ключевое слово предписывает серверу выполнить шифрование кода хранимой процедуры, что может обеспечить защиту от использования авторских алгоритмов, реализующих работу хранимой процедуры. Код, используемый при создании объектов базы данных, хранится в системной таблице syscomments, имеющейся в каждой базе данных. По умолчанию код не шифруется и поэтому может быть просмотрен с помощью обычного запроса SELECT.
  •  AS — это ключевое слово свидетельствует о начале собственно тела хранимой процедуры, то есть набора команд Transact-SQL, с помощью которых и будет реализовываться то или иное действие. В теле процедуры могут использоваться практически все команды Transact-SQL, объявляться транзакции, устанавливаться блокировки и вызываться другие хранимые процедуры. Для выхода из хранимой процедуры можно использовать команду RETURN.

В момент создания хранимой процедуры система осуществляет только проверку синтаксиса команд. Поэтому можно создавать хранимые процедуры в любом порядке, не особенно заботясь о том, что некоторые упоминаемые в них объекты (в том числе и другие хранимые процедуры) пока еще не существуют. Проверка правильности ссылок производится только в процессе компиляции хранимой процедуры, которая выполняется непосредственно перед ее выполнением.

При вызове одной хранимой процедуры из тела другой образуются так называемые вложенные процедуры (nested procedure). При работе с такими процедурами следует учитывать ограничение SQL Server 2000 на количество уровней вложенности — 32. Для определения текущего уровня вложенности можно воспользоваться переменной @@NESTLEVEL.

Существует два способа выполнения хранимой процедуры:

  •  указание только имени процедуры;
  •  использование команды EXECUTE.

В первом варианте вызов хранимой процедуры должен быть единственной командой передаваемого на исполнение пакета. Когда вызов хранимой процедуры не является единственной командой в пакете, то присутствие команды EXECUTE обязательно. Более того, использование этой команды требуется при вызове процедуры из тела другой процедуры или триггера. Синтаксис команды EXECUTE следующий:

[[EXEC[UTE]] {[@return_status = ]

{procedure_name [;number] | @procedure_name_var}

[[©parameter = ] {value | @variable [OUTPUT] | [DEFAULT]}]

[,...n]

[WITH RECOMPILE]

 

Помимо указания полного названия команды — EXECUTE — также допускается и укороченный вариант — EXEC. Обычно для вызова хранимой процедуры используется упрощенный синтаксис:

EXEC procedure_name 

[[@parameter = ] { value | @variable [OUTPUT] | [DEFAULT]}]

[,...n]

Указывая ключевое слово OUTPUT, вы тем самым предписываете присвоить соответствующей локальной переменной (внешней по отношению к процедуре) при завершении хранимой процедуры значение соответствующего параметра. Отметим, что значения параметров могут свободно изменяться в ходе работы процедуры. Использование слова OUTPUT при вызове процедуры разрешается только для параметров, которые были объявлены при создании процедуры с ключевым словом OUTPUT.

Когда же при вызове процедуры для параметра указывается ключевое слово DEFAULT, то для этого параметра будет использовано значение по умолчанию. Естественно, указание слова DEFAULT разрешается только для тех параметров, для которых определено значение по умолчанию.

  1.  Триггеры. Виды триггеров — до 20 мин.

Часто разработчикам приходится реализовывать сложные алгоритмы поддержки целостности данных. Использование ограничений целостности первичного ключа, внешнего ключа и других предоставляют разработчикам достаточно эффективные механизмы обеспечения целостности данных. Однако их бывает недостаточно. Например, с помощью упомянутых механизмов нельзя разрешить изменение данных в том случае, если в одном из столбцов находится определенное значение.

Описанная ситуация является простейшим примером того, какие проверки нередко приходится выполнять перед изменением, удалением или вставкой данных в таблицу. В реальной ситуации применяются гораздо более сложные алгоритмы предварительной проверки данных. Помимо выполнения простых проверок, при модификации данных одной таблицы иногда бывает необходимо соответствующим образом модифицировать данные одной или нескольких таблиц. Решением описанной задачи является использование триггеров.

Триггеры (triggers) в SQL Server представляют собой набор команд Transact-SQL, выполняемых автоматически при осуществлении тех или иных модификаций данных в таблице. Физически триггеры являются ни чем иным, как хранимыми процедурами специального типа. Каждый триггер связан с конкретной таблицей и запускается сервером автоматически каждый раз, когда пользователи пытаются произвести вставку, изменение или удаление данных. Триггер получает всю информацию о выполняемых пользователем изменениях в таблице. Разработчик реализовывает в триггере необходимые проверки и изменения данных в других таблицах базы данных.

Когда пользователь начинает изменение данных, сервер автоматически начинает транзакцию, в которой и выполняется триггер. В теле транзакции разработчик может реализовывать произвольные алгоритмы, которые могут выполнять как проверку, так и изменения данных. В конце концов, работа триггера сводится либо к фиксации, либо к откату транзакции, которая осуществляет изменение данных. Если выполняется откат транзакции, то попытка пользователя изменить данные отменяется. При этом также отменяются все исправления, сделанные самим триггером в различных таблицах (если они выполнялись). При фиксации транзакции производится как фиксирование изменений, выполненных пользователем, так и изменений, сделанных самим триггером.

Триггеры различаются по типу команд, на которые они реагируют:

  •  INSERT TRIGGER — запускаются при попытке вставить данные с помощью команды INSERT;
  •  UPDATE TRIGGER — запускаются при попытке изменения данных с помощью команды UPDATE;
  •  DELETE TRIGGER — запускаются при попытке удаления данных с помощью команды DELETE.

Триггеры не запускаются при выполнении команд обработки текстовых блоков, таких как WRITETEXT, UPDATETEXT, READTEXT.

Параметры FOR, AFTER и INSTEAD OF, указываемые при создании триггера, определяют его поведение следующим образом:

  •  FOR — запуск триггера при выполнении заданной в этом списке команды;
  •  AFTER — запуск триггера после успешного выполнения команд списка, триггеры данного класса могут быть созданы только для таблиц, и не могут быть созданы для представлений;
  •  INSTEAD OF - триггер вызывается вместо выполнения команд списка; такие триггеры могут быть определены как для таблиц, так и для представлений.

Можно определить несколько AFTER - триггеров для каждой операции INSERT, UPDATE и DELETE. По умолчанию все триггеры являются AFTER -триггерами. Триггеры нельзя создавать для временных или системных таблиц. Команда создания триггера должна быть первой в пакете и применяться только к одной таблице. Ее формат следующий:

CREATE TRIGGER Имя триггера ON (Имя таблицы\Имя представления}

[WITH ENCRYPTION] -- шифрование кода триггера;

{{{FOR|AFTER|INSTEAD OF}

{[DELETE] [,] [INSERT] [,] [UPDATE]}

[NOT FOR REPLICATION] -- не для репликации;

AS sql_statement [,...n] —- тело триггера;

}

{{FOR|AFTER|INSTEAD OF}

{[INSERT] [,] [UPDATE]}

[NOT FOR REPLICATION] -- не для репликации;

AS {IF UPDATE (column) -- при изменении столбца;

[{AND|OR} UPDATE (column) [,...n]]}

IF (COLUMNS_UPDATED() {bitwise_operator} Update_bitmask)

{comparison_operator} column_bitmask [,...n]

}

sql_statement [,...n] -— тело триггера.

}

}

Вторая альтернатива команды {IF UPDATE...} используется для детального анализа изменений содержимого колонок с помощью специальных функций, битовых масок, операторов побитовой обработки, оператор сравнения и логических операторов.

Команда ALTER TRIGGER позволяет изменить параметры и тело триггера. С помощью команды DROP TRIGGER можно удалить любой триггер базы данных. Переименовать триггер можно системной хранимой процедурой sp_rename, a получить информацию о триггере можно при помощи системных хранимых процедур sp_helptext и sp_helptrigger.

Внутри триггера допускается использование любых команд языка Transact-SQL с некоторыми ограничениями. Также допускается и вызов хранимых процедур, включая системные хранимые процедуры.




1.  noso logi наука о болезнях 2
2. Реферат- Понятие и характеристика инфляции и антиинфляционной политики Украины
3. МАРКЕТИНГ В ТИ Подходы к определению понятия маркетинг Спрос- сущность и виды1
4. С Файзуллин Э Ф
5. ВВЕДЕНИЕ Все мы хотим видеть наших детей полноценными творческими людьми счастливыми и успешными р
6. вступительных испытаний зачисляются при предъявлении соответствующих документов- дети ~ сироты и дети оста
7. Новое об амерах Демокрита и новое о многих тайнах микромира
8. тема государственного управления 1 Государственное управление как социальное и системное явление Воздей
9. Горюче-смазочные материалы
10. реферат дисертації на здобуття наукового ступеня кандидата технічних наук Київ ~ Дис
11. процессы и аппараты- закон сохранения массы и энергии уравнение материального и энергетического анализа
12. Расчет асинхронного электродвигателя
13. Психофизиологические основы памяти- процесс консолидации следа реверберационные круги возбуждения
14. Реферат- История экономического развития Карачарово
15. Кредит по контокорренту
16. Розробка бази данних діяльності магазину Автозапчастин
17. Реферат- Проблемы урегулирования задолженности предприятий-банкротов
18. антипод добра. Оно вызывает страх и боль и способно уничтожить человека как изнутри так и в общем
19. Реферат- Гипотеза - форма развития знаний
20. тема РФ На тему- Бюджетное финансирование охраны окружающей природной среды Работа допущена к защи