2013-12-12 3 views
13

У меня есть тип столбца INT, я хочу выбрать 1, если он содержит 1 и 0 в противном случае. Я знаю только способ сделать это, используя CASE:Лучший способ конвертировать INT в BIT

CASE WHEN val=1 THEN 1 ELSE 0 

Какие еще существуют подходы к достижению такого же результата?

+1

'ЗАЯВЛЯЮ @r VARCHAR (10) = '1' SELECT CAST (@r AS BIT)' –

+0

@RoyiNamir: ** ** INT но строковые;) – danihp

+0

@danihp также будет работать, если val is int :-) –

ответ

26

SQL SERVER 2012:

SELECT CAST(IIF (field = 1, 1, 0) AS BIT) FROM table 

В противном случае:

SELECT CAST(CASE field WHEN 1 THEN 1 ELSE 0 END AS BIT) From table 
+2

Я считаю, что наилучшей практикой является проверка того, является ли вместо этого 'field' = 0 – Greg

1

Вот еще одно решение. Без case или iif:

select ~cast(sign(abs(@i - 1)) as bit) 

Но это не работает, если @i = -2147483648. Затем вы должны преобразовать его в bigint.

3

Для преобразования просто, до тех пор, как это 1 или 0, вы можете просто присвоить его, не нужно, чтобы бросить что-нибудь

вы делаете то же самое, когда вы объявляете переменную право?

@declare @myBit bit =1; 

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

00000001=1 
    00000010=2 
    00000011=3 
============== 
    FFFFFFTT 

так, если у вас есть 1 значение становится истинным,

На самом деле это сравнение растровый с 2 ​​значений как отображение растра, вы можете иметь несколько или даже группируйте их, используя 0 + 1 на уровне байта.

Выше Вы можете видеть, что 1 «в» 3, а также, что 2 «в» 3

взгляд на тест TSQL блок ниже примере

declare @notSet  int =0 
     , @CanView int =1 
     , @CanEdit int =2 
     , @CanSubmit int =4 
     , @CanApprove int =8 
     , @CanDelete int =16; 

declare @contributor int = @CanView | @CanEdit | @CanSubmit  --> Can't delete 
     , @moderator int = @CanView | @CanEdit | @CanDelete  --> not allowed to sumbit 
     , @admin  int = @CanView | @CanEdit | @CanSubmit | @CanApprove | @CanDelete;--> can do all 

SELECT TEST='A admin can Submit'   , RESULT= iif(@admin  & @CanSubmit = @CanSubmit,'TRUE','FALSE') 
UNION ALL 
SELECT TEST='A Moderator may not Submit' , RESULT= iif(@moderator & @CanSubmit = @CanSubmit,'FALSE','TRUE') 
UNION ALL 
SELECT TEST='A Contributer may not delete' , RESULT= iif(@contributor & @CanDelete = @CanDelete,'FALSE','TRUE') 
UNION ALL 
SELECT TEST='A Moderator may delete'  , RESULT= iif(@moderator & @CanDelete = @CanDelete,'TRUE','FALSE') 

Вы можете объединить значения вместе с использованием оператора бит | вот так 1 | 2 = 3 и 1 | 1 = 1, не смешивайте «|» с «+» здесь, как это не всегда будет хорошо работать ;-)

пример, ошибка будет @CanView + @CanView будет @CanEdit,

, когда вы ожидаете @CanView | @canView еще будет @canView

Попробуйте в SQL

SELECT (1|1), (1+1) 

Ниже какой-то C#, Надеюсь, что это помогает тем, кто хотел бы сохранить и работать с перечислениями в коде и базе данных.

Скажем, у вас есть Enum и класс вроде этого: [Flags] общественного перечисляемые права { notSet = 0 , CanView = 1 , CanEdit = 2 , CanSubmit = 4 , CanApprove = 8 , CanDelete = 16 }

public class User 
{ 
    public Rights Permission {get;set} 
} 

... 
// user can change his own posts 
var user = new User(); 
user.Permission = Rights.CanView | Rights.CanEdit | Rights.CanDelete ; 

Теперь вы можете хранить разрешение в базе данных и считывать значение с помощью одного из перечисленных ниже способов, в которых вы сравните один или сравнить несколько

var result = user.Permission & Rights.CanView == Rights.CanView; 
var canChange = ((user.Permission & (Rights.CanView | Rights.CanEdit | Rights.CanDelete)) != 0); 

Так, Round Tripped в базу данных и обратно, надеюсь, у вас есть то, что вы ищете

Днем кодирования,

Walter

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