强制条件执行顺序——where 子句

问题描述 投票:0回答:1

有没有办法强制条件执行顺序(在where子句中) 我想先强制mssql过滤行

ISJSON(Data)=1
,然后
JSON_VALUE...

我有这个疑问:

SELECT *,
       ISJSON(Data) p
FROM dbo.Table
WHERE  ISJSON(Data)  = 1  AND JSON_VALUE(Data, '$.F1.F2') IS NOT NULL;

并且我在“数据”列中没有有效 json 的行中遇到错误

JSON text is not properly formatted. Unexpected character '.' is found at position 12.

我尝试过滤子查询中的行,但没有帮助,因为查询计划改变了执行顺序:

SELECT *,
       ISJSON(Data) p
FROM
(SELECT * FROM dbo.Table WHERE ISJSON(Data) = 1) q
WHERE JSON_VALUE(Data, '$.F1.F2') IS NOT NULL;

临时解决方案是:

SELECT *,
       ISJSON(Data) p
FROM
(SELECT *,IIF(ISJSON(Data) =1,Data,'{}') JData FROM dbo.Table WHERE ISJSON(Data) = 1) q
WHERE JSON_VALUE(JData, '$.F1.F2') IS NOT NULL;

但这不是最佳解决方案

sql sql-server t-sql where-clause
1个回答
0
投票

记住这一事实: 服务器可以根据需要自由地重新排序

WHERE
JOIN
条件,包括推送子查询

因此,您第一次尝试使用子查询只不过是侥幸,并且可能随时中断。

保证不会发生重新排序的唯一方法是使用

CASE
表达式或派生词,例如
NULLIF
IIF
。 (即便如此,您也只能使用标量表达式,而不能使用聚合函数。)

这就是您的最终选择有效的原因。这是唯一有保证的方法。您可以将其简化如下:

SELECT *,
       ISJSON(Data) p
FROM dbo.Table
WHERE JSON_VALUE(CASE WHEN ISJSON(Data) = 1 THEN Data END, '$.F1.F2') IS NOT NULL;

NULL
传递给
JSON_VALUE
只会让你返回
NULL
,所以这应该总是有效。

© www.soinside.com 2019 - 2024. All rights reserved.