Лучшие практики для значений констант SQL - PullRequest
2 голосов
/ 31 марта 2012

В C # или любых других подобных языках, если мы используем магическое число, это плохая практика. Как насчет SQL? Я много видел этот тип SQL:

CREATE PROCEDURE ProcessOrder
    @productTypeId   INT
    , @productName   NVARCHAR(50)  
AS
BEGIN

    IF (@productType = 3) -- Electronic product type 
        -- Handle electronic
    ELSE IF (@productType = 4) -- Other product type     

END     

Пользователь вызывает это с ENUM, который преобразован в INT. Предполагая, что таблица ProductType (3, «Электронная») существует. Какой должна быть лучшая практика здесь?

Ответы [ 4 ]

2 голосов
/ 31 марта 2012

Вы всегда можете использовать функции.

CREATE FUNCTION
    [dbo].PRODUCT_ELECTRO()
RETURNS INT
AS
BEGIN
        RETURN 3
END


-- This returns the value 3
SELECT
    dbo.PRODUCT_ELECTRO()

IF @MyValue = dbo.PRODUCT_ELECTRO()
BEGIN
    PRINT 'The value is tres'
END
0 голосов
/ 31 марта 2012

Магические числа, безусловно, плохой антипаттерн. Однако константы, которые отображаются на магические числа, являются паттерном. Как

if (productType == 3) //Bad
if (productType == PRODUCT_ELECTRO) //Good even while PRODUCT_ELECTRO=3

Хорошей практикой в ​​SQL является использование lookup tables!

   PRODUCT TABLE
 TYPE       DESCRIPTION
 1          FOOD
 2          ELECTRONIC
 3          HOUSE

А затем определите свои сущности с FOREIGN KEY для этой таблицы.

Пример

CREATE TABLE PRODUCT_TYPES (PRODUCT_TYPE_ID NUMBER PRIMARY KEY, PRODUCT_TYPE_DESCRIPTION VARCHAR2);

CREATE TABLE PRODUCTS (PRODUCT_ID NUMBER PRIMARY KEY, PRODUCT_TYPE NUMBER NOT NULL REFERENCES PRODUCT_TYPES(PRODUCT_TYPE_ID), BLA BLA BLA..........);

В вашем коде вы можете определить константы, такие как

public class ProductTypes {
    public const int FOOD_PRODUCT = 1;
    ......
}

Пример запроса (не напоминайте мне, что этот шаблон небезопасен:))

публичный продукт [] getElectronicProducts () { ... // инициализация соединения бла бла бла Command.CommandText = String.Format ("ВЫБРАТЬ * ИЗ ПРОДУКТОВ ГДЕ PRODUCT_TYPE = {0}", ProductTypes.ELECTRONIC_PRODUCT);

//Produces "SELECT * FROM PRODUCTS WHERE PRODUCT_TYPE = 3"

... //do the query and return
* *} Тысяча двадцать-один
0 голосов
/ 31 марта 2012

Использование перечислений со значениями - хороший дизайн.

Добавление справочной таблицы дает два преимущества:

1: вы можете добавить ссылочную целостность

2: кто-то пытается угадать, какие магические числа найдут таблицу поиска и очистит его от сомнений

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

Итак, позвольте мне порекомендовать использовать таблицу, в которой вместо "магических чисел" есть несколько менее значимых строк. (4 символа = 4 байта, точно так же, как клавиша int - 1 символ равен 1 байту, точно как tinyint)

Вы могли бы иметь справочную таблицу следующим образом:

Key      Value
'Elec'   'Electronic'
'Othr'   'Other'

используя тот же пробел, как если бы у вас был ключ int.

это облегчает чтение ваших запросов SQL.

0 голосов
/ 31 марта 2012

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

IF (@productTypeCode = 'ELE_PROD_TYPE')
...