Есть ли способ передать контекст приложения на соединение с БД на серверах БД, отличных от Sybase (аналогично set_appcontext в Sybase)? - PullRequest
4 голосов
/ 24 января 2011

Sybase позволяет приложению передавать данные "контекста" - например, имя конечного пользователя приложения и т. Д. - в сеанс подключения к базе данных.Контекстные данные - это просто набор пар ключ-значение, которые сохраняются / извлекаются с помощью set_appcontext / get_appcontext сохраненных процедур.

ВОПРОС :

Имеют ли другие основные серверы БД (MSSQL / Oracle / MySQL) средство для передачи контекста приложения в сеанс, аналогичный Sybase set_appcontext?

Подробности :

Одним конкретным практическим использованием контекста приложения является случай, когда у вас есть приложение со средним уровнем, подключающееся к базе данных в качестве очень специфического универсального пользователя базы данных (примеры включают «webuser» / «http» для серверной части веб-приложения, работающей в сети)пользователь сервера или «myappserver» для сервера приложений).

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

Обратите внимание, что информация установлена ​​на уровне сеанса, что означает, что любые вставки / обновления/ delete, выполненные в этом сеансе, могут использовать данные контекста, не передавая их в каждый отдельный оператор SQL - это ОЧЕНЬ важно, скажем, для триггера.

В качестве очень конкретного примера того, почему это полезно,допустим, у вас есть сервер приложений, запускающий сеанс БД от имени клиента, в который вы вставляете / обновляете / удаляете строки в 5 различных таблицах.Вы хотите иметь контрольные таблицы для каждой из этих 5 таблиц, которые включают информацию «какой конечный пользователь внес каждое изменение».

Используя данные контекста, вы можете просто извлечь данные «конечного пользователя» из контекста приложения, используя триггер, и сохранить их как часть записи таблицы аудита.Без использования контекста приложения вам необходимо будет (1) добавить столбец «конечный пользователь» в каждую из этих 5 таблиц (а не только в таблицы аудита) и (2) изменить сервер приложений для вставки или установки при обновлениизначение этого столбца в КАЖДОМ SQL-выражении, которое выдает сервер приложений.О, и это даже не касается того, как это можно сделать, если вы удаляете строку.

Ответы [ 2 ]

5 голосов
/ 24 января 2011

У Oracle есть несколько разных способов сделать это.Во-первых, у вас есть пакет DBMS_APPLICATION_INFO .Хотя вы можете использовать это для установки произвольной контекстной информации, она обычно используется для отслеживания приложения.Обычно вы устанавливаете модуль как имя приложения, а действие - как описание конкретного бизнес-процесса.Затем вы можете ссылаться на эту информацию из V $ SESSION и отслеживать длительные операции через V $ SESSION_LONGOPS.

Oracle также может создавать объект базы данных, называемый контекстом .Это более гибкий способ заполнения контекста уровня сеанса.Вы можете создать новый контекст, а затем создать любые атрибуты, которые вы хотите в этом контексте.И весь ваш код может просто ссылаться на контекст.Например

SQL> create context my_ctx
  2    using pkg_ctx;

Context created.

SQL> create package pkg_ctx
  2  as
  3    procedure set_context;
  4  end;
  5  /

Package created.

SQL> create or replace package body pkg_ctx
  2  as
  3    procedure set_context
  4    as
  5    begin
  6      dbms_session.set_context( 'MY_CTX', 'USERNAME', 'Justin Cave' );
  7    end;
  8  end;
  9  /

Package body created.

SQL> exec pkg_ctx.set_context;

PL/SQL procedure successfully completed.

SQL> select sys_context( 'MY_CTX', 'USERNAME' )
  2    from dual;

SYS_CONTEXT('MY_CTX','USERNAME')
-------------------------------------------------------------------------------
Justin Cave
2 голосов
/ 25 января 2011

Для PostgreSQL вы можете создать пользовательский класс переменных, который является параметром конфигурации в postgresql.conf. Примерно так:

custom_variable_classes = 'myvars'

(Установка этого параметра требует перезагрузки сервера, если я не ошибаюсь)

Теперь через SQL вы можете прочитать и написать это следующим образом:

set myvars.some_flag = 'true';
select current_setting('myvars.some_flag');

Обратите внимание, что вы можете "динамически" определять новые "переменные", для которых все имеют префикс myvars. Отдельные значения не должны быть объявлены в postgresql.conf

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

...