【问题标题】:How to check are there JSON Functions by SQL query?如何通过 SQL 查询检查是否有 JSON 函数?
【发布时间】:2017-06-22 12:16:38
【问题描述】:

还有JSON Function in SQL 2016,如JSON_VALUE、JSON_QUERY等。

我想在我的查询中使用它,但我仍然有旧的服务器,例如 SQL 2014,不允许使用新功能。

我可以通过查询检查是否有类似 JSON_VALUE 的函数?类似的东西

IF operator_exists('JSON_VALUE')
    SELECT JSON_VALUE([Value], '$.MyPath')
      FROM [dbo].[MyTable] 
      WHERE [Name] = 'MyProperty'
ELSE
    SELECT ''

谢谢。

更新

如果我像这样使用 ckecking(感谢 Rigerta Demiri)

DECLARE @compatibility_level int
SELECT @compatibility_level= compatibility_level FROM sys.databases WHERE name = 'MyDbName'
IF (@compatibility_level >= 130)
BEGIN
    SELECT JSON_VALUE([Value], '$.MyPath')
    FROM [dbo].[MyTable] 
    WHERE [Name] = 'MyProperty'
END
    SELECT 'not allowed'

...我收到以下 SQL 异常(在 2014 SQL Studio 上):

'JSON_VALUE' 不是可识别的内置函数名称

可能是 2014 年 MSSQL 解释器尝试解析 所有代码块,但无法理解 JSON_VALUE 是什么?

【问题讨论】:

    标签: sql sql-server json sql-server-2016


    【解决方案1】:

    由于它取决于您安装的 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 的众多资源之一。

    【讨论】:

    • 感谢您的回复。但是,当我在 begin/end 中使用 JSON_VALUE 时,我得到“'JSON_VALUE' 不是可识别的内置函数名称”
    • 如果您检查更新的答案,我还添加了对该函数的调用,对其进行了测试,它可以工作。请将数据库名称 (TestDB) 替换为您的数据库名称。
    • 嗯..很奇怪。
    • SQL 解析整个过程并失败...因此您必须在与检查不同的过程中创建可能支持的过程。
    • @RigertaDemiri 非常感谢!它工作得很好,但您的代码中只有一个错字:我使用 代替 (末尾有 3 个单引号而不是 1)。
    猜你喜欢
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多