2010-08-11 3 views
2

У меня есть столбец, который должен содержать одно из значений 2 power n: 2,4,8,16,32 и т. Д. Я хочу обеспечить, чтобы на уровне схемы схемы - это есть способ указать такое ограничение столбца?Установка ограничения столбца на таблицу (SQL Server)

Спасибо!

+0

Можете ли вы объяснить причину, почему вы это делаете? – JonH

+0

Хорошо, мне просто пришло в голову, что я должен хранить n, чем 2 power n :) Дело решено! – Andrey

ответ

4

В SQL Server:

ALTER TABLE [dbo].[PowerOfTwo] 
WITH CHECK ADD CONSTRAINT [CK_PowerOfTwo] 
CHECK ((log([Value])/log(2)=round(log([Value])/log(2), 0, 1))) 
1

Предположим, ваше имя столбца N. Попробуйте что-то вроде

CHECK(LOG(N)/LOG(2) = TRUNC(LOG(N)/LOG(2))) 

Цель состоит в том, чтобы убедиться в том, что двоичный логарифм величины N представляет собой целое число, которое означало бы, что N является степенью 2. Не конечно, если SQL Server поддерживает функции LOG и TRUNC - замените нужными именами по мере необходимости.

Редактировать: как я перечитал это, я понял, что округление может вызвать проблему (я забыл вторую заповедь плавающей точки, которая: никогда не будет сравнивать значения плавающей точки для равенства!). Хорошо, как насчет

CHECK(ABS(LOG(N)/LOG(2) - TRUNC(LOG(N)/LOG(2))) < 0.00001) 

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

Делитесь и наслаждайтесь.

+0

Хорошо, спасибо! – Andrey

0

Создать проверку колонки:

CHECK (column_name IN (2, 4, 8, 16, 32, ..., 2147483648)) 
+0

Причины ниспровержения? – GSerg

+1

Вы серьезно? – Andrey

+0

Да, я серьезно. Как этот ответ концептуально отличается от принятого ответа? Да, я подумал, что было бы лучше использовать простой список значений, так как их немного, вместо того, чтобы называть «журнал» 4 раза, но кроме этого (нерелевантного) различия, больше ничего нет. Или вы подразумеваете, что ваш столбец имеет тип 'double', а не' int'? В этом случае принятый ответ ошибочен, потому что существует конечная точность с плавающей точкой, из-за чего сравнение, вероятно, будет менее достоверным, чем вы ожидали. – GSerg

2

как об определении столбца быть N. тогда все виды использования этого столбца будет 2^п по определению, а не ограничения.

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

+0

Я уже подумал об этом пару минут назад :) Я все равно выберу тебя, потому что это хорошая идея – Andrey

5

Бесстыдно краже из this answer вы могли бы использовать битовые операции, чтобы сделать это довольно эффективно.

ALTER TABLE tablename ADD CONSTRAINT 
    ckname CHECK (colName > 0 AND (colName & (colName - 1) =0)) 
+0

Но не так эффективно, как ответ Рэнди ... –

Смежные вопросы