Каков наилучший способ определить именованную константу в SQL? - PullRequest
3 голосов
/ 09 декабря 2011

Если «постоянное» значение требуется в нескольких хранимых процедурах и функциях в базе данных, существует ли стандартный способ определить его в одном месте, чтобы оно было доступно везде?

Например, предположим, что я использую xp_logevent в блоке CATCH для записи чего-либо в журнал событий, когда происходит RAISERROR, но я хочу сгруппировать серьезность в информацию, предупреждение и ошибку на основе RAISERROR тяжесть.

Я мог бы установить постоянную EventSeverity так, чтобы:

  • если RAISERROR серьезность = 0, тогда xp_logevent является информационным.
  • если RAISERROR серьезность <= <code>EventSeverity, то xp_logevent является предупреждением.
  • если RAISERROR серьезность> EventSeverity, чем xp_logevent является ошибкой.

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

Я думал об этих возможностях:

  • Используйте ' @@ variable ' для сохранения значения.

    • Преимущества: низкий уровень доступа. Легко получить доступ к коду.
    • Недостатки: накладывает порядок выполнения, переменная должна быть объявлена ​​и установлена ​​до того, как другие процедуры и функции смогут получить к ней доступ. Изменение значения означает изменение кода.

      DECLARE @@EventSeverity INT = 9
      ...
      BEGIN CATCH
          IF ERROR_SEVERITY() < @@EventSeverity
              ...
          ELSE
              ...
      END CATCH
      
  • Используйте функцию для возврата значения.

    • Преимущества: довольно низкие издержки доступа. Легко получить доступ в коде.
    • Недостатки: изменение значения означает изменение кода.

      CREATE FUNCTION dbo.EventSeverity()
      RETURNS INT
      AS
      BEGIN
          RETURN 9
      END
      ...
      BEGIN CATCH
          IF ERROR_SEVERITY() < dbo.EventSeverity()
              ...
          ELSE
              ...
      END CATCH
      
  • Используйте таблицу «настройки» для сохранения значения.

    • Преимущества: изменение значения означает изменение данных.
    • Недостатки: высокая нагрузка на доступ. Трудно получить доступ в коде. Сложно использовать в качестве параметра. Пользователь может изменить значение.

      CREATE TABLE dbo.Settings
      (
          Name VARCHAR(...),
          Value VARCHAR(...)
      )
      ...
      INSERT INTO dbo.Settings (Name, Value)
      VALUES ('EventSeverity', CAST(9 AS VARCHAR))
      ...
      BEGIN CATCH
          IF ERROR_SEVERITY() < (SELECT CAST(Value AS INT) FROM dbo.Settings WHERE Name = 'EventSeverity')
              ...
          ELSE
              ...
      END CATCH
      
  • Используйте таблицу «настройки» с функцией для упрощения доступа.

    • Преимущества: легко изменить значение. Легко получить доступ в коде.
    • Недостатки: высокие накладные расходы. Пользователь может изменить значение.

      CREATE TABLE dbo.Settings
      (
          Name VARCHAR(...),
          Value VARCHAR(...)
      )
      ...
      INSERT INTO dbo.Settings (Name, Value)
      VALUES ('EventSeverity', CAST(9 AS VARCHAR))
      ...
      CREATE FUNCTION dbo.EventSeverity()
      RETURNS INT
      AS
      BEGIN
          DECLARE @result INT
          SET @result = (SELECT CAST(Value AS INT) FROM dbo.Settings WHERE Name = 'EventSeverity')
          IF @result IS NULL
              SET @result = 9
          RETURN @result
      END
      ...
      BEGIN CATCH
          IF ERROR_SEVERITY() < dbo.EventSeverity()
              ...
          ELSE
              ...
      END CATCH
      

Есть ли лучший способ сделать это?

1 Ответ

2 голосов
/ 21 декабря 2011

При прочих равных условиях я бы согласился на жестко закодированную ФУНКЦИЮ для производительности. В целях безопасности эту функцию следует поместить в отдельную схему SCHEMA, например MyDatabase.CONF.SettingsFunc, вместо обычной DBO; с разрешениями, установленными для этой схемы, так что только администраторы будут иметь право изменять данные.

Если вам необходимо централизовать различные параметры конфигурации для множества разных применений, тогда последний подход (FUNCTION + TABLE) будет более привлекательным, если вы создадите индекс для каждого варианта использования. Аналогично, эта таблица «настроек» должна быть в ограниченной схеме, в отличие от функции, которая может оставаться в схеме по умолчанию для простоты кодирования.

Но если обязательно использовать схему по умолчанию, становится интересным настроить триггер «INSTEAD OF UPDATE» в этой таблице «настроек», чтобы пользователь не мог легко изменять данные; не забывайте, что этот последний подход нельзя назвать «безопасностью», поскольку пользователь все еще может изменить (или отбросить!) триггер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...