由于它取决于您安装的 SQL Server 版本,并且由于您有不同的实例(甚至比 SQL Server 2016 更旧的实例),您只需检查您尝试查询的数据库的兼容性级别是否相等到 130。
您可以执行以下操作:
declare @compatibility_level int
select @compatibility_level= compatibility_level from sys.databases where name = 'TestDB'
if (@compatibility_level >= 130)
begin
declare @jsoninfo nvarchar(max)
set @jsoninfo=N'{
"info":{
"type":1,
"address":{
"town":"bristol",
"county":"avon",
"country":"england"
},
"tags":["sport", "water polo"]
},
"type":"basic"
}'
select json_value(@jsoninfo,'$.info.address.town') as town
end
OPENJSON 函数仅在兼容级别 130 下可用
(或更高)。
您可以在documentation 中阅读。
编辑:
您得到的结果是因为显然“SQL Server 不知道或不关心将输入条件的哪个分支;它无论如何都会验证批处理中的所有语句。”正如这篇文章的答案所述:T-Sql appears to be evaluating “If” statement even when the condition is not true。
因此,解决方法是将整个语句创建为动态字符串。
像这样:
declare @compatibility_level int
select @compatibility_level= compatibility_level from sys.databases where name = 'TradingDWH'
if (@compatibility_level >= 130)
begin
declare @sql nvarchar(max);
set @sql = ' declare @jsoninfo nvarchar(max) ' + ' set @jsoninfo=N''{ "info":{' + ' "type":1, "address":{ "town":"bristol", "county":"avon", "country":"england" }, "tags":["sport", "water polo"] }, "type":"basic" }'
set @sql = @sql + 'select json_value(@jsoninfo,''$.info.address.town'') as town'
select @sql
--exec sp_executesql @sql
-- or your own query, like this:
declare @sql2 nvarchar(max);
declare @MyProperty nvarchar(100) = 'YourProperty'
set @sql2 = ' SELECT JSON_VALUE([Value], ''$.MyPath'') '
set @sql2 = @sql2 + 'FROM [dbo].[MyTable] WHERE [Name] = @MyProperty '
select @sql2
--exec sp_executesql @sql2, N'@MyProperty nvarchar(100)', @MyProperty
end
else
begin
select 'Version prior to 130!' as [message]
end
Don’t Fear Dynamic SQL 是您可以详细了解动态 SQL 的众多资源之一。