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

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

ВОПРОС:

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

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

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

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

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

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

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


person DVK    schedule 24.01.2011    source источник
comment
@OMG Ponies - как вы 9или решили проблему, описанную в подробностях в Oracle?   -  person DVK    schedule 24.01.2011
comment
Мы предоставили идентификатор пользователя хранимым процедурам, фактически самому запросу. Идентификатор пользователя хранился в сеансе веб-приложения, сохранялся при входе пользователя в систему. Очень немногие таблицы не имели столбцов аудита — идентификатор пользователя, который добавил и когда (дата), и идентификатор пользователя, который обновил и когда (дата).   -  person OMG Ponies    schedule 24.01.2011
comment
@OMG Ponies - как вы решаете, кто удалил строку? Единственный метод, который я знаю, - это бесполезность первого обновления столбца who_did до того, кто удалил, и удаления   -  person DVK    schedule 24.01.2011
comment
Удалить флаги, также известные как мягкое удаление, когда запись существует, но не видна другим.   -  person OMG Ponies    schedule 24.01.2011


Ответы (2)


У 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
person Justin Cave    schedule 24.01.2011

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

custom_variable_classes = 'myvars'

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

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

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

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

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

person a_horse_with_no_name    schedule 24.01.2011