我正在尝试在SQL server中执行以下查询:
declare @queryWord as nvarchar(20) = 'asdas'
SELECT * FROM TABLE_1
WHERE (ISDATE(@queryWord) = 1)
AND TABLE_1.INIT_DATE = CONVERT(Date, @queryWord)
这显然会导致错误,因为'asdas'无法转换为Date
。虽然,我期待一种不同的行为。也就是说,因为ISDATE(@queryWord) = 1
是假的,我期待SQL不检查第二个条件,但显然,它确实如此。
我知道还有其他一些方法可以执行此查询,但这不是我的问题。我想知道是否有一些方法不检查第二个条件是第一个不满足。我很好奇,因为我认为SQL已经做到了。
答案 0 :(得分:11)
SQL Server不会做短路(也不应该)。
如果您在某些情况下需要尝试某些内容,则需要以编写查询的方式强制执行此操作。
对于此查询,最简单的解决方法是在CASE
子句中使用WHERE
表达式。
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)
副作用,CASE
和查询嵌套是我能想到的唯一两种支持的方法,可以强制在SQL中强制执行依赖条件的评估顺序。
答案 1 :(得分:2)
我猜你可以在2次传球中完成:
declare @queryWord as nvarchar(20) = 'asdas'
select
*
from
(
SELECT * FROM TABLE_1
WHERE (ISDATE(@queryWord) = 1) ) t1
where t1.INIT_DATE = CONVERT(Date, @queryWord)
因此,您的内部查询运行第一个测试,外部查询运行第二个。在单个查询中,我认为没有任何方法可以强制任何评估条件的顺序。
答案 2 :(得分:1)
为什么不在WHERE条件下执行CASE?
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
答案 3 :(得分:1)
在SQL语句中没有定义的评估顺序 - 除了大小写表达式之外,甚至那里的顺序没有定义为保证的结果。理论上,where子句中的条件可以并行或交替顺序完成。
案例表达式的不同之处不在于具有已定义的顺序,而在于具有保证的结果。 IOW,case when 1=1 then 0 When longrunningfunction() = 1 then 2 end
保证返回零,但没有承诺不运行longrunning函数。
答案 4 :(得分:1)
可以"模拟"使用CASE
语句。但是你必须使第一个条件给出TRUE
值,以避免检查第二个条件:
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