json 字段上的“where”导致算术溢出错误

Ami*_*mir 1 json sql-server-2016

我有一张桌子:

当我从表中选择所有内容时:

 SELECT JSON_VALUE(LastReadings, '$.lastReadings."7-temp".value') as x FROM
(VALUES    
(2,N'{"groups": [],"lastReadings": {"amir": {"name": "Ink","value":12.0},"7-temp": {"name": "Temperature","value":12}},"customId":null}'),
(3,N'{"groups": [],"lastReadings": {"amir": {"name": "Ink","value":12.0},"7-temp": {"name": "Temperature","value":32}},"customId":null}'),
(4,N'{"groups": [],"lastReadings": {"amir": {"name": "Ink","value":12.0},"7-temp": {"name": "Temperature","value":22}},"customId": null}'),
(5,N'{"groups": [],"lastReadings": {"amir": {"name": "Ink","value": 12.0},"7-temp": {"name": "Temperature","value":123}},"customId": null}')    
)
[AmirTestTable](Id,LastReadings )
Run Code Online (Sandbox Code Playgroud)

我得到

+-----+
|  x  |
+-----+
|  12 |
|  32 |
|  22 |
| 123 |
+-----+
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试添加 where 子句时:

 SELECT JSON_VALUE(LastReadings, '$.lastReadings."7-temp".value') as x 
 FROM
(VALUES
  (2,N'{"groups": [],"lastReadings": {"amir": {"name": "Ink","value":12.0},"7-temp": {"name": "Temperature","value":12}},"customId":null}'),
  (3,N'{"groups": [],"lastReadings": {"amir": {"name": "Ink","value":12.0},"7-temp": {"name": "Temperature","value":32}},"customId":null}'),
  (4,N'{"groups": [],"lastReadings": {"amir": {"name": "Ink","value":12.0},"7-temp": {"name": "Temperature","value":22}},"customId": null}'),
  (5,N'{"groups": [],"lastReadings": {"amir": {"name": "Ink","value": 12.0},"7-temp": {"name": "Temperature","value":123}},"customId": null}')
)
[AmirTestTable](Id,LastReadings )
where JSON_VALUE(LastReadings, '$.lastReadings."7-temp".value') > 12.0
Run Code Online (Sandbox Code Playgroud)

我收到错误:

将 nvarchar 转换为数据类型数字时出现算术溢出错误。

如果我将 123 值更改为 99,则查询有效,或者如果我将 where 子句更改为 > 12。如果我将其显式转换为数字,它也有效。

我不明白为什么它不能直接工作。

Mar*_*ith 5

这与 JSON 没有任何关系。你看到同样的

SELECT 1
WHERE  '123' > 12.0;
Run Code Online (Sandbox Code Playgroud)

JSON_VALUE有一个返回类型nvarchar(4000)

文字12.0的数据类型为numeric(3,1).

因为numeric/decimal数据类型优先级高于nvarchar函数调用的结果被强制转换为numeric(3,1)

在此处输入图片说明

您可以使用显式强制转换来控制自己使用的比例和精度。

例如

 CAST(JSON_VALUE(LastReadings, '$.lastReadings."7-temp".value') AS NUMERIC(4,1)) > 12.0
Run Code Online (Sandbox Code Playgroud)

适用于您的示例数据。