Boolean 'NOT' trong T-SQL không hoạt động trên kiểu dữ liệu 'bit'?


81

Cố gắng thực hiện một thao tác boolean NOT, có vẻ như trong MS SQL Server 2005, khối sau không hoạt động

DECLARE @MyBoolean bit;
SET @MyBoolean = 0;
SET @MyBoolean = NOT @MyBoolean;
SELECT @MyBoolean;

Thay vào đó, tôi ngày càng thành công hơn với

DECLARE @MyBoolean bit;
SET @MyBoolean = 0;
SET @MyBoolean = 1 - @MyBoolean;
SELECT @MyBoolean;

Tuy nhiên, điều này có vẻ hơi khó khăn khi diễn đạt một điều gì đó đơn giản như một sự phủ định.

Tui bỏ lỡ điều gì vậy?


Câu trả lời:


151

Sử dụng toán tử ~:

DECLARE @MyBoolean bit
SET @MyBoolean = 0
SET @MyBoolean = ~@MyBoolean
SELECT @MyBoolean

11
Đó là bởi vì bạn đang sử dụng một int, không phải một bit.
Jonas Lincoln

4
Cột là một chút ... phiên bản DB có quan trọng không?
Martin

Tôi biết rằng điều này hoạt động trong SQL Server 2008. Tôi làm điều này mọi lúc. Câu hỏi dành cho SQL Server 2005, mà tôi không chắc liệu nó có hoạt động ở đó hay không.
Dan VanWinkle 14/12/11

3
Đính chính: Theo MS, điều này cũng sẽ hoạt động trong năm 2005. Thông tin thêm ở đây .
Dan VanWinkle 14/12/11

3
Nice câu trả lời, tôi chỉ thử nghiệm nó và hoạt động tốt, ngay cả trong SQL Server 2000.
Alberto Martinez

25

Giải pháp của bạn là một giải pháp tốt ... bạn cũng có thể sử dụng cú pháp này để chuyển đổi một chút trong SQL ...

DECLARE @MyBoolean bit;
SET @MyBoolean = 0;
SET @MyBoolean = @MyBoolean ^ 1; 
SELECT @MyBoolean;

1
Chỉ đối với FYI, điều này hoạt động vì nó hoạt động độc quyền theo bit. Giống như toán tử XOR trong nhiều ngôn ngữ. Điều này về cơ bản giống như làm SET @MyBoolean = 1 - @MyBooleanngoại trừ nó đang sử dụng toán học bit chứ không phải toán học số nguyên. Mặc dù điều này là phù hợp và hiệu quả, nó có thể gây nhầm lẫn cho những người không hiểu toán học. Thông tin thêm ở đây . @Jonas Lincoln giải pháp tốt hơn.
Dan VanWinkle 14/12/11

1
Là một FYI, giải pháp này hoạt động cho các trường được tính toán trong khi câu lệnh trường hợp thì không. Cảm ơn!
anyeone

22

Trừ giá trị cho 1 có vẻ như nó sẽ thực hiện được một mẹo nhỏ, nhưng về mặt thể hiện ý định, tôi nghĩ tôi muốn chọn:

SET @MyBoolean = CASE @MyBoolean WHEN 0 THEN 1 ELSE 0 END

Nó dài dòng hơn nhưng tôi nghĩ nó dễ hiểu hơn một chút.


10

Để gán một bit đảo ngược, bạn sẽ cần sử dụng toán tử NOT bitwise. Khi sử dụng toán tử NOT bitwise, '~', bạn phải đảm bảo rằng cột hoặc biến của bạn được khai báo dưới dạng bit.

Điều này sẽ không cho bạn số không:

Select ~1 

Điều này sẽ:

select ~convert(bit, 1)

Điều này sẽ:

declare @t bit
set @t=1
select ~@t

9

Trong SQL 2005 không có giá trị boolean thực, giá trị bit thực sự là thứ khác.

Một bit có thể có ba trạng thái, 1, 0 và null (vì nó là dữ liệu). SQL không tự động chuyển đổi những điều này thành true hoặc false (mặc dù, người quản lý doanh nghiệp SQL sẽ khó hiểu)

Cách tốt nhất để nghĩ về các trường bit trong logic là một số nguyên là 1 hoặc 0.

Nếu bạn sử dụng logic trực tiếp trên một trường bit, nó sẽ hoạt động giống như bất kỳ biến giá trị nào khác - tức là logic sẽ đúng nếu nó có một giá trị (bất kỳ giá trị nào) và sai nếu ngược lại.


5

BIT là kiểu dữ liệu số, không phải kiểu boolean. Đó là lý do tại sao bạn không thể áp dụng toán tử boolean cho nó.
SQL Server không có kiểu dữ liệu BOOLEAN (không chắc chắn về SQL SERVER 2008) vì vậy bạn phải gắn bó với một cái gì đó như giải pháp của @Matt Hamilton.


4

Sử dụng ABSđể nhận giá trị tuyệt đối (-1 trở thành 1) ...

DECLARE @Trend AS BIT
SET @Trend = 0
SELECT @Trend, ABS(@Trend-1)

2
Bạn đã bỏ lỡ việc giải thích tại sao -1lại nảy sinh ngay từ đầu. Đó là: sẽ không xảy ra, nếu phép trừ được thể hiện ở dạng logic / trực quan hơn mà OP đã sử dụng. Đây là một cách vô nghĩa và khó hiểu để làm điều đó.
underscore_d
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.