OLAP.ru OLAP, data mining, analysis, данные, СУБД, генераторы отчетов, проектирование, принятие решений, оптимизация, хранилише, извлечение, поиск, Crystal, Business Objects, Cognos, SAS...
Полный список »
Business intelligence - effective data mining & analysis
Вход Регистрация Новости сайта Карта сайта/поиск RSS
 
OLAP и Business Intelligence
SUBSCRIBE.RU
 
 

Использование CONTEXT_INFO

olontsev

SQL Server обладает широким набором интересных функций. Одной из них является возможность реализовать передачу определенной информации в пределах одной сессии. Когда это может быть нужно? Например, с одной таблицей в базе данных работает несколько приложений и каждое вводит или изменяет данные с помощью своей хранимой процедуры, а триггер в таблице на изменение данных должен это учитывать и вести себя по-разному для всех приложений. В этом случае как раз можно использовать следующий сценарий: хранимая процедура сохраняет определенное значение в переменной сессии, а триггер считывает это значение и выполняет нужной действие в зависимости от контекста. Также эту технику можно применять при использовании вложенных триггеров (nested triggers).

Переменная сессии CONTEXT_INFO позволяет сохранять данные переменной длины размером до 128 байт. Это немного, но для большинства задач должно хватить. Чтобы установить значение переменной сессии нужно воспользоваться командой SET CONTEXT_INFO, а чтобы получить текущее значение - функцией CONTEXT_INFO(). Ну и сразу приведу небольшой пример.

DECLARE @context_info varbinary(128) SET @context_info = CAST('MyApplicationID1' AS varbinary(128)) SET CONTEXT_INFO @context_info GO   SELECT CONTEXT_INFO() SELECT CAST(CONTEXT_INFO() AS varchar(128)) GO

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

Также переменную сессии можно посмотреть в следующих системных представлениях в столбце context_info.

  • sys.dm_exec_requests
  • sys.dm_exec_sessions
  • sys.sysprocesses

Также можно использовать технику, когда в CONTEXT_INFO мы будем хранить не одно, а несколько значений, но в разных местах. Например, мы договариваемся, что в позиции с 1 по 20 мы храним идентификатор процесса, а 21 по 28 - дату и время. Тогда процесс формирования нашей строки будет выглядеть примерно следующим образом.

DECLARE @process_id char(20) = 'MyProcessID2' DECLARE @date_time datetime = GETDATE() DECLARE @context_info varbinary(128)   SET @context_info = CAST(@process_id AS binary(20)) + CAST(@date_time AS binary(8))   SET CONTEXT_INFO @context_info   SELECT CAST(SUBSTRING(CONTEXT_INFO(), 1, 20) AS char(20)) AS process_id, CAST(SUBSTRING(CONTEXT_INFO(), 21, 8) AS datetime) AS date_time

И еще одна небольшая деталь, о которой необходимо помнить: если вы используете CONTEXT_INFO внутри транзакции, то при откате значение не возвращается к исходному. Пример:

DECLARE @context_info varbinary(128) SET @context_info = CAST('Value before transaction' AS varbinary(128)) SET CONTEXT_INFO @context_info SELECT CAST(CONTEXT_INFO() AS varchar(128)) AS [Value before transaction] BEGIN TRAN SET @context_info = CAST('Value inside transaction' AS varbinary(128)) SET CONTEXT_INFO @context_info SELECT CAST(CONTEXT_INFO() AS varchar(128)) AS [Value inside transaction] ROLLBACK SELECT CAST(CONTEXT_INFO() AS varchar(128)) AS [Value after transaction]

Финальным результатом вернется значение, которое мы установили внутри транзакции, несмотря на то, что транзакцию мы откатили. Это нужно учитывать или можно использовать.

Ссылки по теме

Рекомендовать Обсудить материал Написать редактору Распечатать   Дата публикации: 17.04.2014  
Хостинг: SiliconTaiga    Поддержка: Interface Ltd. Обратиться по техническим вопросам     
Rambler's Top100 TopList