在SQL中查询JSON

在SQL中查询JSON,sql,sql-server,json,tsql,Sql,Sql Server,Json,Tsql,我试图找到一种在SQL中查询JSON的方法,类似于查询XML。有什么想法吗?我还没有保存任何数据,所以我非常开放,尽管我读过保存JSON的最佳方法是使用varcharmax列 谢谢 例如: 假设下面的JSON对象存储在一个varcharmax列中,我想用success flag=False查询该列,以提取所有事务ID {"TransactionID":"sample string 1","Success":true, "Response":"sample string 3","Values":

我试图找到一种在SQL中查询JSON的方法,类似于查询XML。有什么想法吗?我还没有保存任何数据,所以我非常开放,尽管我读过保存JSON的最佳方法是使用varcharmax列

谢谢

例如:

假设下面的JSON对象存储在一个varcharmax列中,我想用success flag=False查询该列,以提取所有事务ID

{"TransactionID":"sample string 1","Success":true,
 "Response":"sample string 3","Values":"sample string 4"}

这个故事的寓意是:不要使用SQL。CLR和JSON包装器是最好的选择。但如果你真的很好奇,你可以做如下的事情。可能发生的问题太多了,很难一一列举。在谷歌上快速搜索一下这个话题,很容易就能找到原因。如果您能够确保JSON对象的格式完美,那么这可能是您可以研究的内容。大概不要用这个

/*
JSON to XML Parser TSQL
Compatibility: TEsted on SQL Server 2014
Assumptions:    -Perfectly formed JSON as declared below.
                -Charecters for formatting are ok but will be removed
*/

--Imagine @JSONDATA would be the parameter to your function
DECLARE @JSONDATA VARCHAR(MAX) = '{"transactions":[
                                        {"TransacitonID":"transaction1","Success":true,"Response":"sample string 1","Values":"sample string 1"},
                                        {"TransactionID":"transaction2","Success":false,"Response":"sample string 2","Values":"sample string 2"}
                                ]}'

DECLARE @ObjectArrayNameStart INT
DECLARE @ObjectArrayNameEnd INT
DECLARE @ObjectArray VARCHAR(MAX)
DECLARE @ObjectArrayName VARCHAR(MAX)
DECLARE @ObjectArrayBracketStart INT
DECLARE @ObjectArrayBracketEnd INT
DECLARE @ObjectArraySingleton VARCHAR(MAX)
DECLARE @ObjectXML XML



--Replace All CR and LF charecters and HT chars
SET @JSONDATA = REPLACE(REPLACE(REPLACE(@JSONDATA,CHAR(10),''),CHAR(13),''),CHAR(9),'') --LF

--Get the ObjectArrayName
SELECT @ObjectArrayNameStart = PATINDEX('%{["]transactions["]:[[]%',@JSONDATA), @ObjectArrayNameEnd = PATINdEX('%[[]%',@JSONDATA)
SET @ObjectArrayName = SUBSTRING(@JSONDATA,@ObjectArrayNameStart,@ObjectArrayNameEnd)

--Get the ObjectArray name
SET @ObjectArray = REPLACE(@JSONDATA,@ObjectArrayName,'')

----Trim out the word of the object array and get the single word and singleton item
SET @ObjectArrayName = LEFT(@ObjectArrayName,@ObjectArrayNameEnd - 3)
SET @ObjectArrayName = RIGHT(@ObjectArrayName, LEN(@ObjectArrayName) - 2)
SET @ObjectArraySingleton = 'node'

--PREP THE JSON OBJECT DOWN TO INDIVIDUAL OBJECTS AND SET AS XML DOCUMENT
SET @ObjectArray = LTRIM(RTRIM(REPLACE(@ObjectArray,']}','')))
SET @ObjectArray = REPLACE(@ObjectArray,'},{','</' + @ObjectArraySingleton + '><' + @ObjectArraySingleton + '>')
SET @ObjectArray = REPLACE(@ObjectArray,'{','<' + @ObjectArraySingleton + '>')
SET @ObjectArray = REPLACE(@ObjectArray,'}','</' + @ObjectArraySingleton + '>')
SET @ObjectArray = '<root>' + @ObjectArray + '</root>'
SET @ObjectXML =  CAST(@ObjectArray AS XML)

--Query for line data
;WITH XMLObjectData AS (
    SELECT  Item.value('text()[1]','nvarchar(max)') AS ObjectLine
    FROM    @ObjectXML.nodes('/root/node') AS Items(Item)
), CommaSplit AS (
    SELECT  '<pair><key>' + REPLACE(X.ObjectLine,',','</value></pair><pair><key>') + '</value></pair>' AS ObjectLine
    FROM    XMLObjectData AS X
), ColonSplit AS (
    SELECT  REPLACE(X.ObjectLine,':','</key><value>') AS ObjectLine
    FROM    CommaSplit AS X
), QuoteReplace AS (
    SELECT  REPLACE(X.ObjectLine,'"','') AS ObjectLine
    FROM    ColonSplit AS X
)
SELECT  CAST(F.ObjectLine AS XML)
FROM    QuoteReplace AS F
FOR     XML PATH('object'), ROOT('root')


--COMMENTED OUT FOR TESTING
--SELECT    @JSONDATA AS JSONData, 
--      @ObjectArrayName AS ObjArrayName, 
--      @ObjectArrayNameStart AS ObjArrayNameStart, 
--      @ObjectArrayNameEnd AS ObjArrayNameEnd,
--      @ObjectArray AS ObjArray,
--      @ObjectArraySingleton AS ObjSingleton
--      --,CAST(@ObjectArray AS XML) AS XMLObjectArray

SQL Server目前没有本机JSON支持,因此您必须将此列作为字符串读入例如C,然后使用JSON库将JSON解析为对象,然后进行处理。2005版及更高版本的SQL Server具有本机XML支持…谢谢@marc_s。所以我的另一个想法是在插入之前将其转换为XML。在VB或C中有没有简单的方法将JSON字符串转换为XML?也许这应该是一个完全不同的问题?我记得,有一个选项可以用C语言编写存储过程和/或函数-那就简单了:@JoshuaHarris你考虑过JSON.NET吗?它可以将json转换为XML或从XML转换为json。用C语言编写,然后将结果插入SQL。@ZoffDino-这是我目前选择的解决方案。一段代码并不是一个很好的答案,特别是如果你想尝试回答一些古老的问题。给我们一些背景,让我们相信,对于任何一个偶然发现这一点的人来说,这解决了眼前的问题。我只是试图回答这个问题。即使这个问题由来已久,用户也可能随时面临这种情况。所以,不管问题是旧的还是新的,用哪种方式回答问题都无关紧要。你们读过了吗?我是说一堆代码并不是一个完整的答案。这与它的年龄无关。如果你花时间回答这个古老的问题,至少要花时间把它变成一个好的答案。
    select ca.TransactionID, ca.Success, ca.Response, cs.Values from 
    table_name tn with(NOLOCK)
    CROSS APPLY(select * from OPENJSON(tn.JSONColumnName) WITH(
    [TransactionID] nvarchar(50) '$.TransactionID',
    [Success] bit '$,Success',
    [Response] nvarchar(50), '$.Response',
    [Values] nvarchar(50) '$.Values'
    )) ca
    Where ca.Success = 0