2013-10-17 20 views
8

Tôi cố gắng để thực hiện các truy vấn sau đây trong SQL server:Làm thế nào để ngắn mạch SQL đâu khoản

declare @queryWord as nvarchar(20) = 'asdas' 

SELECT * FROM TABLE_1 
WHERE (ISDATE(@queryWord) = 1) 
AND TABLE_1.INIT_DATE = CONVERT(Date, @queryWord) 

Điều này rõ ràng gây ra một lỗi vì 'asdas' không thể được chuyển đổi sang Date. Mặc dù, tôi đã mong đợi một hành vi khác. Đó là, bởi vì ISDATE(@queryWord) = 1 là sai, tôi đã mong đợi SQL để không kiểm tra điều kiện thứ hai, nhưng rõ ràng, nó không.

Tôi biết có một số cách khác để thực hiện truy vấn này nhưng đây không phải là câu hỏi của tôi. Tôi tự hỏi nếu có một số cách để không kiểm tra điều kiện thứ hai là điều đầu tiên không thỏa mãn. Tôi tò mò vì tôi nghĩ rằng SQL đã làm điều này.

+2

Bạn không thể ép buộc một thứ tự cụ thể trong việc đánh giá điều kiện AFAIK. –

+1

Có thể trùng lặp: http://stackoverflow.com/questions/381224/sql-server-query-short-circuiting – seekerOfKnowledge

+0

Trả lời cho câu hỏi tôi đã liên kết: http://weblogs.sqlteam.com/mladenp/archive/2008/02 /25/How-SQL-Server-short-circuits-WHERE-condition-evaluation.aspx – seekerOfKnowledge

Trả lời

11

Máy chủ SQL không thực hiện đoản mạch (cũng không nên thực hiện).

Nếu bạn cần nó không phải hãy thử điều gì đó trong một số trường hợp, bạn cần ép buộc theo cách bạn viết truy vấn của mình.

Đối với truy vấn này, cách khắc phục dễ nhất sẽ là sử dụng biểu thức CASE trong mệnh đề WHERE của bạn.

declare @queryWord as nvarchar(20) = 'asdas' 

SELECT * FROM TABLE_1 
WHERE TABLE_1.INIT_DATE = (CASE WHEN ISDATE(@queryWord) = 1 
           THEN CONVERT(Date, @queryWord) 
          ELSE NULL END) 

Off-tay, CASE và truy vấn làm tổ là chỉ có hai cách hỗ trợ mà tôi có thể nghĩ ra để buộc một trật tự thẩm định các điều kiện phụ thuộc trong SQL.

+1

Không thực sự. Điều này sẽ trả lại các hàng từ TABLE_1 trong đó INIT_DATE là null.Tôi biết cách thực hiện truy vấn nhưng câu hỏi của tôi không phải là câu hỏi này. – nachovall

+1

@nachovall Câu hỏi của bạn là "* là một cách nào đó để không kiểm tra điều kiện thứ hai là điều đầu tiên không thỏa mãn? *" Tôi đã trả lời câu hỏi đó. – RBarryYoung

+1

@nachovall Ngoài ra, không đúng là "* Điều này sẽ trả về các hàng từ TABLE_1 trong đó INIT_DATE là null *". Trong SQL thích hợp 'NULL = NULL' trả về *** False ***. Chỉ có 'NULL IS NULL' mới có thể trả về True. – RBarryYoung

2

Tôi đoán bạn có thể làm điều đó trong 2 đèo:

declare @queryWord as nvarchar(20) = 'asdas' 


    select 
    * 
    from 
    (
    SELECT * FROM TABLE_1 
    WHERE (ISDATE(@queryWord) = 1)) t1 
    where t1.INIT_DATE = CONVERT(Date, @queryWord) 

Vì vậy, truy vấn bên trong của bạn chạy thử nghiệm đầu tiên và truy vấn bên ngoài thứ hai. Trong một truy vấn, tôi không tin có bất kỳ cách nào để buộc bất kỳ thứ tự đánh giá điều kiện nào.

+0

Nên hoạt động, nhưng không phải câu hỏi của tôi. – nachovall

+1

Bạn có muốn sử dụng "Không" đơn giản không? – Andrew

+0

:) Lỗi của tôi. Đó chỉ là một ví dụ, tôi đã không cố gắng để giải quyết nó, nhưng nhờ anyway – nachovall

1

Tại sao không thực hiện CASE trong điều kiện WHERE?

DECLARE @tester TABLE (
    theDate DATE, 
    theValue INT 
    ) 

INSERT INTO @tester VALUES ('2013-10-17', 35) 
INSERT INTO @tester VALUES ('2013-10-16', 50) 
INSERT INTO @tester VALUES ('2013-10-15', 2) 

declare @queryWord as nvarchar(20) = 'asdas' 
SELECT * 
FROM @tester 
WHERE theDate = 
    CASE 
     WHEN ISDATE(@queryWord) = 1 THEN CONVERT(Date, @queryWord) 
     ELSE theDate 
    END 

SET @queryWord = '2013-10-17' 
SELECT * 
FROM @tester 
WHERE theDate = 
    CASE 
     WHEN ISDATE(@queryWord) = 1 THEN CONVERT(Date, @queryWord) 
     ELSE theDate 
    END 
+0

Không câu hỏi của tôi – nachovall

+0

Câu hỏi của bạn là để có nó kiểm tra điều kiện đầu tiên (rằng @queryWord là một loại DATE hợp lệ) và sau đó tiến hành để làm điều kiện 2 nếu nó là sự thật - điều này hiện nó. – wergeld

1

Không có thứ tự đánh giá được xác định trong câu lệnh SQL - ngoại trừ trường hợp biểu thức trường hợp và thậm chí có thứ tự không được định nghĩa nhiều như kết quả được đảm bảo. Các điều kiện trong mệnh đề where của bạn về mặt lý thuyết có thể được thực hiện theo thứ tự song song hoặc xen kẽ.

Biểu thức trường hợp khác nhau không theo thứ tự được xác định, nhưng bằng cách đảm bảo kết quả. IOW, case when 1=1 then 0 When longrunningfunction() = 1 then 2 end được đảm bảo trả về 0, nhưng không có lời hứa nào không chạy hàm longrunning.

1

Nó có thể được "mô phỏng" với tuyên bố CASE. Nhưng bạn phải làm điều kiện đầu tiên đưa ra một giá trị TRUE để tránh kiểm tra các điều kiện 2:

declare @queryWord as nvarchar(20) = 'asdas' 

SELECT * 
FROM TABLE_1 
WHERE (CASE 
     WHEN ISDATE(@queryWord) = 0 THEN 0 
     WHEN TABLE_1.INIT_DATE = CONVERT(Date, @queryWord) THEN 1 
     ELSE 0 END) = 1 
Các vấn đề liên quan