web-dev-qa-db-ja.com

SQLクエリによるJSON関数があるかどうかを確認する方法

JSON_VALUE、JSON_QUERYなどの SQL 2016のJSON関数 があります。

クエリで使用したいのですが、たとえばSQL 2014を搭載した古いサーバーがまだあり、新機能の使用が許可されていません。

JSON_VALUEのような関数があるかどうかをクエリで確認できますか?何かのようなもの

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

ありがとう。

[〜#〜]更新[〜#〜]

私がこのようにチェックを使うと(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」は認識されている組み込み関数名ではありません

enter image description here

2014年5月のMSSQLインタプリタは、コードのすべてのブロックを解析しようとし、JSON_VALUEが何であるかを理解できません。

6
double_a

これは、インストールした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は、条件がtrueでない場合でも「If」ステートメントを評価しているようです

したがって、回避策は、ステートメント全体を動的文字列として作成することです。このような:

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 

動的SQLについて詳しく読むことができる多くのリソースの1つは Do n’t Fear Dynamic SQL です。

5
Rigerta Demiri