在SQL Server 2012中使用JSON

时间:2017-02-07 12:58:31

标签: sql sql-server json

我正在开展一个项目,我需要能够从收到的JSON中接收和使用(即提取信息)。我正在使用的当前版本的SQL Server(并且在接下来的几年内不会改变)是2012年,它不包括对此的支持(与2016版本相反)。

我确实记得看过某人的帖子,他轻轻地为此提供了源代码,但遗憾的是无法再找到它。

有没有人知道或知道有效的解决方案?

想法是这样的:

拥有以下JSON:

{
    "Obj1": {
        "Obj1_S_1": [{
            "Obj1_S_1_S_1": "Blabla_1"
        }, {
            "Obj1_S_1_S_1": "Blabla_2"
        }, {
            "Obj1_S_1_S_1": "Blabla_3"
        }, {
            "Obj1_S_1_S_1": "Blabla_4"
        }, {
            "Obj1_S_1_S_1": "Blabla_5"
        }, {
            "Obj1_S_1_S_1": "Blabla_6"
        }]
    },
    "Obj2": "This is a simple string",
    "Obj3": "456.33"
}

我可以使用以下调用:

SET @My_Param = GET_JSON(@Source_JSON, '*.Obj1.Obj1_S_1[3].Obj1_S_1_S_1') ;

我会将值'Blabla_4'放入变量@My_Param

顺便说一句,这与Oracle和MySQL中使用的语法完全相同。

非常感谢满足特定需求的建议。

2 个答案:

答案 0 :(得分:0)

可以通过一些策略性分析/拆分操作来完成

示例数据

Declare @S varchar(max) ='
{
    "Obj1": {
        "Obj1_S_1": [{
            "Obj1_S_1_S_1": "Blabla_1"
        }, {
            "Obj1_S_1_S_1": "Blabla_2"
        }, {
            "Obj1_S_1_S_1": "Blabla_3"
        }, {
            "Obj1_S_1_S_1": "Blabla_4"
        }, {
            "Obj1_S_1_S_1": "Blabla_5"
        }, {
            "Obj1_S_1_S_1": "Blabla_6"
        }]
    },
    "Obj2": "This is a simple string",
    "Obj3": "456.33"
}
'

示例

--Clean-up JSON String and add '|||' as a standard delimeter
Select @S = Replace(@S,MapFrm,MapTo)
 From (values ('"'     ,'')
             ,(char(13),'|||')
             ,(char(10),'|||')
             ,('}'     ,'|||')
             ,('{'     ,'|||')
             ,('['     ,'|||')
             ,(']'     ,'|||')
       ) b (MapFrm,MapTo)

具有解析/拆分UDF的选项

Select Item  = left(RetVal,charindex(':',RetVal+':')-1)
      ,Value = ltrim(right(RetVal,len(RetVal)-charindex(':',RetVal+':')))
 From  [dbo].[udf-Str-Parse](@S,'|||')
 Where Len(IsNull(RetVal,' '))>1
 Order By RetSeq

没有解析/拆分UDF的选项

Select Item  = left(RetVal,charindex(':',RetVal+':')-1)
      ,Value = ltrim(right(RetVal,len(RetVal)-charindex(':',RetVal+':')))
 From  (
        Select RetSeq = Row_Number() over (Order By (Select null))
              ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
        From  (Select x = Cast('<x>' + replace((Select replace(@S,'|||','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
        Cross Apply x.nodes('x') AS B(i)
       ) A
 Where Len(IsNull(RetVal,' '))>1
 Order By RetSeq

返回

Item            Value
Obj1    
Obj1_S_1    
Obj1_S_1_S_1    Blabla_1
Obj1_S_1_S_1    Blabla_2
Obj1_S_1_S_1    Blabla_3
Obj1_S_1_S_1    Blabla_4
Obj1_S_1_S_1    Blabla_5
Obj1_S_1_S_1    Blabla_6
Obj2            This is a simple string,
Obj3            456.33

UDF(如果需要)

CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table 
As
Return (  
    Select RetSeq = Row_Number() over (Order By (Select null))
          ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
    From  (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
    Cross Apply x.nodes('x') AS B(i)
);
--Thanks Shnugo for making this XML safe
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
--Select * from [dbo].[udf-Str-Parse]('this,is,<test>,for,< & >',',')

答案 1 :(得分:0)

请参阅我的回复here,在其中我创建了一个与SQL 2012兼容的函数,该函数提取给定JSON和列名的值。

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:      Isaac Adams
-- Create date: 7/12/2018
-- Description: Give the JSON string and the name of the column from which you want the value
-- =============================================
CREATE FUNCTION JSON_VALUE
(
    @JSON NVARCHAR(3000),
    @column NVARCHAR(3000)
)
RETURNS NVARCHAR(3000)
AS
BEGIN

DECLARE @value NVARCHAR(3000);
DECLARE @trimmedJSON NVARCHAR(3000);

DECLARE @start INT;
DECLARE @length INT;

SET @start = PATINDEX('%' + @column + '":"%',@JSON) + LEN(@column) + 3;
SET @trimmedJSON = SUBSTRING(@JSON, @start, LEN(@JSON));
SET @length = PATINDEX('%", "%', @trimmedJSON);
SET @value = SUBSTRING(@trimmedJSON, 0, @length);

RETURN @value
END
GO