Làm cách nào để bao gồm null trong khi so sánh trong SQL Server?


9

Vì vậy, về cơ bản trong SQL Server, NULL có nghĩa là không có giá trị và do đó không thể so sánh được sẽ trả về một số kết quả không mong muốn.

Ví dụ: truy vấn sau không trả về các hàng trong đó giá trị IS NULL nhưng tôi muốn nó:

SELECT *
FROM table
WHERE
  (value != 26)
  AND date IS NULL
  AND last_modified >= '5/21/2014'

Tôi hiểu tôi có thể làm như sau một cách giải quyết nhưng nghiêm túc? Phải thêm dấu ngoặc đơn và kiểm tra xem có phải là null cho mỗi trường đơn lẻ mỗi lần tôi muốn đưa nó vào không? Có vẻ xấu xí, không trực quan và điên rồ.

SELECT *
FROM table
WHERE
  (value != 26 OR value is null)
  AND date IS NULL
  AND last_modified >= '5/21/2014'

Ý tôi là tôi biết NULL không phải là một giá trị và do đó không thể so sánh được nhưng bạn không thể suy luận rằng trên thực tế, chắc chắn không phải 26? Nếu 26 là một cái gì đó và NULL không là gì và không có gì không phải là một cái gì đó thì NULL không phải là 26. Có vẻ hợp lý với tôi.

Có ai biết làm thế nào tôi có thể, theo cách sạch hơn, bao gồm null trong kết quả của tôi khi sử dụng so sánh mà không phải bao gồm kiểm tra rõ ràng mỗi lần. Ngoài ra, tắt null trên bàn của tôi chắc chắn không phải là một lựa chọn.

Biên tập:

Vấn đề thực sự của tôi về lý do tại sao tôi không muốn làm theo cách tôi thể hiện không bị lộ. Vì vậy, ở đây đi. Tôi đang viết một chương trình cho phép bạn xây dựng các truy vấn vào các bảng cơ sở dữ liệu và để người dùng tự động tạo các bộ lọc và về cơ bản vào cuối ngày sẽ xây dựng một câu lệnh SQL và hiển thị kết quả cho người dùng. Các trường được người dùng chọn có thể là bất kỳ và / hoặc tất cả các trường trong cơ sở dữ liệu nhất định và nếu tôi phải đặt ISNULL theo nghĩa đen trên mọi trường duy nhất thực sự không hiệu quả và làm cho SQL trở nên cực kỳ xấu. Chương trình của tôi là định nghĩa không xác định bảng có nghĩa là tôi không quan tâm những gì trong bảng của bạn và không muốn biết định nghĩa của bảng là gì. Tôi chỉ muốn bạn chọn một bảng, chọn một số trường để lọc với bằng, không bằng, trong, không trong, v.v ...


Tôi không có quyền kiểm soát bảng, đó là bảng kế thừa và tôi đang viết mã sử dụng nó.
Brian T Hannan

Re. "Phải thêm dấu ngoặc đơn và ...? Có vẻ xấu, không trực quan và điên rồ.": Bạn nên - LUÔN "thêm dấu ngoặc đơn". "Mã được đọc nhiều hơn so với nó được viết." Đừng làm cho mọi người đọc (dễ mắc lỗi) phải biết a) biết ưu tiên, b) nhớ nó và c) áp dụng chính xác mỗi khi họ đọc mọi Biểu hiện, và do đó vi phạm Nguyên tắc DRY thường xuyên hơn (so với bạn bằng cách thêm dấu ngoặc đơn "không cần thiết". "Chỉ vì bạn có thể (bỏ chúng ra), không có nghĩa là bạn shouuuld (bỏ chúng ra) ..."
Tom

Câu hỏi này về cơ bản là một bản sao của Câu hỏi StackOverflow từ 8 tháng trước đó đã có câu trả lời tốt hơn nhiều ở đây (bản thân nó dựa trên một bài viết 2 năm trước đó): stackoverflow.com/questions/19682956/,
Tom

Câu trả lời:


9

Để bắt đầu, NULL không có nghĩa là "không có giá trị" mà nó có nghĩa là "Giá trị không xác định" trong SQL Server. Có một cài đặt phiên gọi là ANSI_NULLS có thể khiến các truy vấn của bạn hoạt động như bạn muốn, tuy nhiên, nó không được chấp nhận và sẽ bị buộc phải BẬT (mà bạn dường như không thích) trong phiên bản tương lai: http: // msdn .microsoft.com / en-us / library / ms188048.aspx

Tôi hiểu những gì bạn đang cố gắng thực hiện và để đưa ra quan điểm tôi sẽ hỏi liệu bạn đã thấy bất kỳ truy vấn nào được tạo bởi các dịch vụ báo cáo hoặc một cái gì đó như Cognos chưa? Nếu vậy, bạn sẽ thấy chính xác những gì bạn mô tả bạn không muốn làm. Tại sao? Vâng, với một lược đồ cho phép null, đó là cách để làm điều đó. Tôi không nói rằng đó là một ý tưởng tuyệt vời và tuyệt vời nhưng nó luôn hoạt động.

Những gì nhà thiết kế của bạn có thể làm là kiểm tra xem liệu cột đó thậm chí có thể là null hay không và nếu vậy logic phù hợp có thể bước nó và tạo truy vấn chính xác. Bạn cũng có thể có các tùy chọn như "Cột này có thể là null, bạn có muốn các giá trị đó không?". Tôi không biết phần cuối trò chơi và viết công cụ truy vấn động của riêng bạn khá là giả dối khi tất cả các tính nhất quán logic đều được tính đến (chẳng hạn như điều này).

Tôi sẽ tiếp tục thực hiện kiểm tra null rõ ràng trên các cột có thể là null, chắc chắn rằng nó không trông tốt nhất nhưng nó hoạt động mọi lúc.

Tùy chọn thiết lập ANSI_NULL sẽ hoạt động ngay bây giờ nhưng KHÔNG phải là ý tưởng hay, đặc biệt nếu bạn không kiểm soát môi trường, cộng với việc nó sẽ bị buộc BẬT sau đó và gây ra lỗi khi bạn cần phải viết lại logic ứng dụng của mình. Đây là cách SQL Server hoạt động với NULL.


9

Các NULLvấn đề là một vấn đề hóc búa với SQL. Về cơ bản, đó là một lỗi hiện đang bị đốt cháy trong tất cả các phần mềm SQL trên hành tinh. Chúng ta phải đối phó với nó.

value <> 26 or value is nulllà một cách tốt để thực hiện logic này. Có các công thức khác của cùng một ngữ nghĩa.

Nếu bạn biết rằng giá trị đó không bao giờ -1(ví dụ) bạn có thể nói ISNULL(value, -1) <> 26. Tôi không nghĩ rằng tốt hơn từ quan điểm dễ đọc. Nó cũng có thể gây ra sự cố tối ưu hóa vì vị từ này có thể không phải là SARGable. value is null một vị từ SARGable và có thể lập chỉ mục trái với niềm tin phổ biến.

SQL có IS DINSTINCT FROMtoán tử nhưng T-SQL không hỗ trợ nó. Vui lòng dành một giây để bỏ phiếu cho yêu cầu thực hiện! Đây là một vấn đề hoàn toàn cú pháp. Trình tối ưu hóa hoàn toàn không cần thay đổi. Nó đã hỗ trợ nhà điều hành nội bộ.

TL; DR: Cách bạn đang làm ngay bây giờ là cách đúng đắn. Sống với nó.


1
"Về cơ bản là một sai lầm". Tôi thấy điều này khác nhau. Mô hình quan hệ dựa trên lý thuyết tập hợp và logic vị ngữ. SQL triển khai logic vị ngữ ba giá trị bằng cách hỗ trợ NULL để biểu thị khái niệm chung về một giá trị còn thiếu. Hỗ trợ cho NULL và logic vị ngữ ba giá trị đã là một phần của tiêu chuẩn ANSI và ISO trong một thời gian dài. Đáng buồn thay, cuộc tranh luận và sự nhầm lẫn ngự trị ...
Dave Mason

3
@DMason Tôi hiểu lý do đằng sau mô hình đó (mặc dù nó không liên quan gì đến các tập hợp. Đây là vấn đề vô hướng.). Chỉ là không ai muốn mô hình đó. Nó không hữu ích trong thực tế. Có vẻ như là một ý tưởng tốt vào thời điểm đó nhưng 30 năm sau chúng ta biết rằng đó không phải là một ý tưởng. Có một lý do gần như tất cả các ngôn ngữ lập trình coi null như bất kỳ giá trị nào khác. C # với các loại giá trị nullable cũng làm điều đó.
usr

Gây tranh cãi? Thật! Bạn không đơn độc, @usr. Nhiều người khác nghĩ rằng một mô hình quan hệ hợp lệ nên tuân theo logic hai giá trị và phản đối mạnh mẽ khái niệm NULL trong SQL. EF Codd, người tạo ra mô hình quan hệ tin tưởng vào ý tưởng hỗ trợ các giá trị và vị từ bị thiếu vượt ra ngoài logic hai giá trị. Tôi tình cờ đồng ý với anh. Bạn có một ý kiến ​​khác. C'est la vie. Tôi là ai để từ chối ý kiến ​​của bạn?
Dave Mason

@DMason Tôi tôn trọng bạn.
usr
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.