2009-06-26 2 views
5

В коде можно указать глобально доступные константы/перечисления/etc, которые затем могут быть повторно использованы через приложение. Это дает возможность использовать значащие имена типа «Мазда» вместо чисел типа «2».Избавление от «магических» чисел в SQL Server

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

Например, для следующих таблиц (Пресловутый автомобиль схема):

Car  ManufacturerId 
350Z  1 
Hilux  2 
Yaris  2 

ManufacturerId Name 
1    Nissan 
2    Toyota 

Таким образом, вместо того, чтобы писать

SELECT * FROM Car WHERE ManufacturerId = 1 -- Nissan 

Мы хотели бы написать что-то вроде

SELECT * FROM Car WHERE ManufacturerId = @Nissan 

Одно ограничения мы имеем то, что мы не можем полагаться на имя Manufacturer.Name, оставаясь неизменным для жизни приложения. Мы думали о том, столбец «Код», который никогда не меняется, и стыки ищутся так:

SELECT * 
FROM Car c 
    INNER JOIN Manufacturer m ON c.ManufacturerId = m.ManufacturerId 
WHERE m.Code = 'Nissan' 

Я немного колеблющимся на это, как он использует дополнительные соединения и сравнения строк, которые могут быть с ошибками ,

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

ответ

4

Мы сделали это несколько способов:

  • определяемые пользователем функции, которая возвращает «магическое число» по имени.
  • Используйте столбец nchar (4) вместо столбца int и придумайте несколько менее непостижимых кодов. Таким образом, Nissan будет «NISN» вместо 1. Немного приятнее.
+0

Игрушка с первым предложением, но это слишком поздно для второго. Возможно, в следующий раз. –

+0

Дело в том, что магическое число обычно соответствует перечислению в вашем клиентском коде. В какой-то момент вы закроете синхронизацию вашего SQL-запроса с помощью перечисления клиента. MS SQL Server предлагает очень аккуратную точку интеграции здесь: вы можете закодировать CLR UDF, чтобы вернуть значение перечисления, существенно обеспечив безопасность определенного типа. Вам все равно нужно убедиться, что ваши запросы получают имена значений перечисления, хотя я никогда не нашел пути вокруг этой части проблемы. –

1

Вам не нужно хранить номера в базе данных. Есть администраторы базы данных, которые все еще любят идею «естественных ключей». Вместо использования идентификатора они просто используют естественный ключ, который однозначно определяет производителя. Часто это может привести к нескольким основным ключам. Возможно, вам понадобится «Mazda» «Канада» в качестве уникального идентификатора производителя.

Лично мне не нравится этот метод и предпочитаю иметь уникальный идентификатор для каждого идентифицируемого объекта, хранящегося в моих таблицах. Это означает создание новой таблицы, которая является поиском. 2, «Мазада». Затем вы можете создать представление, которое вытаскивает «Мазда», где есть 2 в базе данных, а затем запускает запрос против представления. SELECT * from v_cars, где производитель = 'Mazda'

+0

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