2015-02-24 63 views
2

我試圖找到一種查詢SQL中查詢JSON的方法,類似於查詢XML。有任何想法嗎?我還沒有保存任何數據,所以我非常開放,儘管我已經閱讀了保存JSON的最佳方式是使用varchar(max)的列。在SQL中查詢JSON

感謝

例子:

比方說,下面的JSON對象存儲在一個varchar(max)列,我想查詢柱拉出的「成功」標誌的所有事務ID =假。

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

SQL Server當前沒有本機JSON支持,因此您必須將此列作爲字符串讀入例如C#,然後將JSON解析爲對象(使用JSON庫),然後進行處理。 SQL Server(從版本2005和更新版本)具有本機** XML **支持.... – 2015-02-24 15:48:11

+0

謝謝@marc_s。所以我的另一個想法是在插入之前將其轉換爲XML。有沒有一種簡單的方法在VB(或C)中將JSON字符串轉換爲XML?也許這應該是一個完全不同的問題? – jharris8567 2015-02-24 15:52:19

+0

我記得,有一個在C#中編寫存儲過程和/或函數的選項 - 它會很簡單:) – Gerino 2015-02-24 15:56:02

回答

0

道德故事:不要使用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