2013-06-28 41 views
11

Khi tôi chạy một truy vấn trong MS Access Tôi hạnh phúc có thể sử dụng một truy vấn như thế này:Tại sao truy cập MS boolean đúng -1 chứ không phải 1 hoặc đúng?

SELECT clients.* FROM clients WHERE active=True; 

hoặc

SELECT clients.* FROM clients WHERE active=-1; 

nhưng không

SELECT clients.* FROM clients WHERE active=1; 

Bên cạnh đó, nói rằng tôi muốn truy vấn cơ sở dữ liệu bằng PDO Tôi có thể sử dụng câu lệnh đã chuẩn bị:

$db->prepare('SELECT clients.* FROM clients WHERE active=:isactive;'); 
$db->bindValue(':isactive', True); //Does not work 
$db->bindValue(':isactive', 1); //Does not work 
$db->bindValue(':isactive', -1); //Does work 

Vì vậy, mặc dù true hoạt động khi gửi truy vấn đơn giản tới Access, nếu chỉ ràng buộc -1 hoặc 0 sẽ hoạt động cho boolean.

Tại sao điều này và tại sao là -1 đại diện của true khi 1 thường có nghĩa là true bằng ngôn ngữ/cơ sở dữ liệu khác?

Trả lời

6

tôi dường như không thể tìm ra nguồn gốc chính xác này là từ, nhưng tôi nhớ đọc về việc này một thời gian trước đó tôi nghĩ MSDN. answer này có mô tả kỹ thuật về boolean true của Visual Basic, cũng áp dụng cho Truy cập.

Nếu tôi nhớ chính xác, đó là vì -1 được biểu diễn bằng nhị phân với mỗi bit được đặt thành 1 (1111 1111), trong khi +1 chỉ có bit ít nhất được đặt là 1 với tất cả 0 (0000 0001) còn lại. Bởi vì false được biểu thị bằng 0 (0000 0000), rất dễ dàng để thay đổi giữa truefalse bằng cách sử dụng bitwise NOT, nhưng nếu true là bất kỳ thứ gì khác, thì KHÔNG được kết quả là không phải là false. Ngoài ra, sử dụng bitwise AND để kiểm tra sự thật trên bất kỳ giá trị trung thực nào sẽ hoạt động, trong khi nếu đúng là 0000 0001 thì nó sẽ không.

+0

Điều đó có vẻ rất hợp lý. Rõ ràng Access có thể đối phó với việc được cung cấp một 'true' trong một câu lệnh bình thường nhưng các truy vấn ràng buộc không thể tạo ra một vấn đề trừ khi bạn cho nó giá trị thích hợp. '<> 0' có vẻ giống như một cách giải quyết tốt cho' true' như @ChristianSpecht được đề cập – harryg

+0

Yea, Christian là chính xác về điều đó. Tôi chỉ nghĩ rằng tôi sẽ trả lời phần thứ hai của câu hỏi của bạn. – jonhopkins

+1

+1 Một cách khác để xem xét nó là một [hai bổ sung] (http://en.wikipedia.org/wiki/Two%27s_complement) số nguyên đã ký chỉ dài một bit chỉ có thể là một trong hai giá trị: 0 hoặc -1. –

0

Không cố gắng để được facetious, nhưng câu trả lời là "bởi vì đó là cách họ đã làm nó." Tuyên bố của bạn rằng 1 thường có nghĩa là đúng trong các ngôn ngữ khác là không chính xác. Ví dụ, trong C/C++, false được định nghĩa là == 0 và true được định nghĩa là! = 0.

Đó là lý do tại sao bạn có thể nói if (con trỏ) {...}

+0

Đủ công bằng nhưng '1! = 0' vì vậy chắc chắn phải trả về giá trị đúng. Đây không phải là trường hợp trong câu hỏi của tôi - không có kết quả được đưa ra, cho dù đúng hay sai. Về cơ bản 1! = True hoặc false – harryg

+0

Quy tắc của ngón tay cái: Kiểm tra giá trị boolean, không so sánh chúng. Ví dụ, không nói nếu (testFunction() == true), chỉ cần nói nếu (testFunction()) Điều này sẽ lộn xộn khi bạn đang cố gắng để mô phỏng độc quyền hoặc (if (function1()! = Function2()) và cách chính xác để làm điều này hơi tiết hơn: nếu function1() thì!function2() else function2() được đảm bảo để gọi mỗi hàm một lần và cung cấp cho bạn độc quyền hoặc kết quả. –

4

Tôi không biết một câu trả lời tốt hơn để "Tại sao điều này" hơn Dale Wilson đã nói trong his answer, nhưng nó khá đơn giản để phá vỡ vấn đề này:

Chỉ cần làm quen với sử dụng WHERE active <> 0 trong các truy vấn của bạn.

Tôi đang sử dụng MS Access (nơi True-1) và MS SQL Server (nơi True1) và kiểm tra <> 0 là cách dễ nhất mà luôn luôn làm việc.

+1

Hoặc chỉ 'WHERE Active' (Tôi chưa thử nghiệm điều này với các bảng SQL Server của tôi, nhưng' WHERE ACTIVE' và 'WHERE NOT ACTIVE' sẽ thực hiện thủ thuật, tôi nghĩ rằng – Scotch

+0

@Scotch Có, vừa thử nghiệm, có vẻ như nếu bạn có một trường boolean bạn có thể truy vấn nó chỉ bằng cách đi 'SELECT * FROM table WHERE booleanfield' sẽ cung cấp cho bạn tất cả các hàng nơi' booleanfield = true'. – harryg

Các vấn đề liên quan