2009-07-29 3 views
6

В настоящее время мы определим список констант (в основном они соответствуют перечислениям мы определили в бизнес-слое) в верхней части хранимой процедуры, как так:Каковы различные способы обработки «перечислений» на SQL-сервере?

DECLARE @COLOR_RED INT = 1 
DECLARE @COLOR_GREEN INT = 2 
DECLARE @COLOR_BLUE INT = 3 

Но они часто получают повторены для многих хранимых процедур так есть много дублирования.

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

Каковы мои другие варианты?

Я использую SQL Server 2008 и C#, если это имеет значение.

Обновление Поскольку я использую .Net, есть ли способ, которым могут быть определены пользовательские типы (CLR)?

ответ

2

я могу предложить два различных подхода:

1) определяют таблицу Перечисление с колонке tinyint идентичности в качестве первичного ключа и значение перечисления в качестве уникального индекса; например

CREATE TABLE [dbo].[Market](
     [MarketId] [smallint] IDENTITY(1,1) NOT NULL, 
     [MarketName] [varchar](32) COLLATE Latin1_General_CS_AS NOT NULL, 
CONSTRAINT [PK_Market] PRIMARY KEY CLUSTERED 
(
     [MarketId] ASC 
) ON [PRIMARY] 
) ON [PRIMARY] 

Тогда либо:

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

2) Согласно (1), но определяйте каждое значение первичного ключа как мощность 2. Это позволяет другой таблице ссылаться на несколько значений перечисления непосредственно без необходимости в дополнительной таблице сопоставления. Например, предположим, что вы определяете таблицу перечисления цвета со значениями: {1, 'Red'}, {2, 'Blue'}, {4, 'Green'}. Другая таблица может ссылаться на значения красного и зеленого значений, включая внешний ключ 5 (то есть бит-бит ИЛИ 1 и 4).

+0

Внешний ключ на перечислениях хорош, но как значения используются в хранимой процедуре? – tpower

+0

@tpower: Не совсем уверен, что я понимаю ваш вопрос, но я обычно передавал значения строки перечисления в sproc и сразу же переводил их в внешние ключи, используя указанную функцию. Следовательно, приложение использует только значения перечисления, код БД использует только значения внешнего ключа. – Adamski

+0

Что я имею в виду, если хранимая процедура содержит некоторую бизнес-логику, например, «IF @MyVariable = @ MY_ENUMERATION_VALUE_2 THEN», где нам нужно указать значение, которое внешние ключи здесь не помогают. – tpower

2

Скалярный пользователь определяет функцию? Не идеально, но функциональные ...

CREATE FUNCTION dbo.ufnRGB (
    @Colour varchar(20) 
) 
RETURNS int 
AS 
BEGIN 
    DECLARE @key int 

    IF @Colour = 'BLue' 
     SET @key = 1 
    ELSE IF @Colour = 'Red' 
     SET @key = 2 
    ELSE IF @Colour = 'Green' 
     SET @key = 3 

    RETURN @KEy 
END 
1

мне не нравится идея определения того, что эффективно константа для хранимых процедур в нескольких местах - это похоже на кошмар обслуживания и легко подвержены ошибкам (опечатки и т.д.). На самом деле, я не могу видеть много обстоятельств, когда вам нужно будет что-то делать?

Я бы определенно сохранил все определения перечисления в одном месте - на ваших классах C#. Если это означает, что нужно каждый раз передавать их в свои процедуры, пусть будет так. По крайней мере, так они определяются только в одном месте.

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

3

Это может быть противоречиво: мой прием не использует перечисления в T-SQL. T-SQL на самом деле не разработан таким образом, чтобы сделать перечисления полезными, как на других языках. Для меня, в T_SQL, они просто добавляют усилие и сложность без выгоды, видимой в другом месте.

+1

Я согласен, это база данных. Сопоставление между именем и значением должно выполняться в таблице. – nocache

1

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

CREATE FUNCTION COLOR_RED() 
RETURNS INT 
AS 
BEGIN 
    RETURN 1 
END 

CREATE FUNCTION COLOR_GREEN() 
RETURNS INT 
AS 
BEGIN 
    RETURN 2 
END 

...