2016-08-02 36 views
0

我很難找到一種方法將此自定義SQL腳本改進爲Umbraco數據庫。如何使這個SQL函數更快地解析XML

下面是sql腳本獲取並解析XML,並選擇正確的值:

DECLARE @Title nvarchar(1000) 
SET @Title = 
(SELECT @NodeXml.query('//TechnicalData/title').value('.', 'nvarchar(max)') Title 
FROM cmsContentXml xt JOIN umbracoNode un ON un.id = xt.NodeId 
WHERE xt.nodeId = @NodeId) 

SELECT iif(CHARINDEX('"values":null', @Title,0) > 0,'',Substring(@Title, 21, CHARINDEX('}', @Title) - 22)) Title 

的部分XML如下:

<?xml version="1.0"?> 
<TechnicalData id="1261" key="b6a2f67a-0f0f-40dd-a3c6-c5fb9d8b78b9" parentID="1092" level="3" creatorID="0" sortOrder="12" createDate="2016-07-14T13:56:37" updateDate="2016-07-15T12:06:25" nodeName="Rioolkolken Type 1 Drainerend via de zijwanden" urlName="rioolkolken-type-1-drainerend-via-de-zijwanden" path="-1,1089,1092,1261" isDoc="" nodeType="1154" creatorName="admin" writerName="Karl" writerID="1" template="1085" nodeTypeAlias="TechnicalData"> 
    <title>{"values":{"nl-BE":"Rioolkolken Type 1 Drainerend via de zijwanden"},"dtdGuid":"f2dfa88e-63b9-4913-80cd-64d770cef90e"}</title> 
</TechnicalData> 

這只是一個小部分腳本。 TechnicalData包含大約20個節點,所有節點都必須解析。可以找到完整的腳本here

此自定義腳本的原因是因爲我需要使用ssrs報告來擴展Umbraco站點。

+2

您使用的是哪個版本的SQL Server? 'title'的內容是SQL Server 2016中的JSON,你可以使用'parseJSON' – gofr1

+0

我知道,但它是2012年的安裝。 +1爲其他人絆倒這Q –

回答

1

你的方法是緩慢的,因爲你一遍又一遍採取的信息的一個單比特出你的XML。

使用此功能,您將獲得所有數據類型安全從一個sinlge去掉你的XML並且沒有任何字符串解析。

DECLARE @NodeXml XML= 
N'<?xml version="1.0"?> 
<TechnicalData id="1261" key="b6a2f67a-0f0f-40dd-a3c6-c5fb9d8b78b9" parentID="1092" level="3" creatorID="0" sortOrder="12" createDate="2016-07-14T13:56:37" updateDate="2016-07-15T12:06:25" 
nodeName="Rioolkolken Type 1 Drainerend via de zijwanden" urlName="rioolkolken-type-1-drainerend-via-de-zijwanden" path="-1,1089,1092,1261" isDoc="" nodeType="1154" creatorName="admin" writerName="Karl" writerID="1" template="1085" nodeTypeAlias="TechnicalData"> 
    <title>{"values":{"nl-BE":"Rioolkolken Type 1 Drainerend via de zijwanden"},"dtdGuid":"f2dfa88e-63b9-4913-80cd-64d770cef90e"}</title> 
</TechnicalData>'; 

SELECT td.value('@id','int') AS id 
     ,td.value('@key','uniqueidentifier') AS [key] 
     ,td.value('@parentID','int') AS parentID 
     ,td.value('@level','int') AS [level] 
     ,td.value('@creatorID','int') AS creatorID 
     ,td.value('@sortOrder','int') AS sortOrder 
     ,td.value('@createDate','datetime') AS createDate 
     ,td.value('@updateDate','datetime') AS updateDate 
     ,td.value('@nodeName','nvarchar(max)') AS nodeName 
     ,td.value('@urlName','nvarchar(max)') AS urlName 
     ,td.value('@path','nvarchar(max)') AS [path] 
     ,td.value('@isDoc','nvarchar(max)') AS isDoc 
     ,td.value('@nodeType','int') AS nodeType 
     ,td.value('@creatorName','nvarchar(max)') AS creatorName 
     ,td.value('@writerName','nvarchar(max)') AS writerName 
     ,td.value('@writerID','int') AS writerID 
     ,td.value('@template','int') AS template 
     ,td.value('@nodeTypeAlias','nvarchar(max)') AS nodeTypeAlias 

     ,td.value('title[1]','nvarchar(max)') AS Title 

FROM @NodeXml.nodes('TechnicalData') AS A(td) 

在這種情況下的結果是一行,所有數據在列中。

我懷疑,你需要自己的價值觀聲明的變量,更好地運用上述的CTE(一套基於/在線/特設在大多數情況下比程序),並從那裏使用的值。但是:很容易將收集的信息填充到已聲明的變量中(如果確實需要的話)。在這種情況下,只需聲明正確類型的變量並使用語法

SELECT @MyVariable=td.value('@id','int') 
     ,@OtherVariable= ... 
... same for the rest... 
+0

這確實加快了一點。我還最終將查詢放入存儲過程以繞過爲每個聲明創建查詢參數的需要,因爲ssrs似乎將查詢頂部的每個聲明var自動綁定爲查詢參數。 –

1

解析在一個單一的所有節點選擇

DECLARE @NodeXml xml; 

-- sample data 
SET @NodeXml ='<TechnicalData id="1261" key="b6a2f67a-0f0f-40dd-a3c6-c5fb9d8b78b9" parentID="1092" level="3" creatorID="0" sortOrder="12" createDate="2016-07-14T13:56:37" updateDate="2016-07-15T12:06:25" nodeName="Rioolkolken Type 1 Drainerend via de zijwanden" urlName="rioolkolken-type-1-drainerend-via-de-zijwanden" path="-1,1089,1092,1261" isDoc="" nodeType="1154" creatorName="admin" writerName="Karl" writerID="1" template="1085" nodeTypeAlias="TechnicalData"> 
    <title>{"values":{"nl-BE":"Rioolkolken Type 1 Drainerend via de zijwanden"},"dtdGuid":"f2dfa88e-63b9-4913-80cd-64d770cef90e"}</title> 
</TechnicalData>'; 

DECLARE @Title nvarchar(1000); 
DECLARE @Subtitle nvarchar(1000) 
DECLARE @Company int; 
DECLARE @Date Datetime; 

SELECT @Date = @NodeXml.value('(/TechnicalData/@createDate)[1]', 'datetime') 
,@Title = td.node.value('title[1]','nvarchar(max)') 
,@Subtitle = td.node.value('subtitle[1]','nvarchar(max)') 
,@Company = td.node.value('bedrijf[1]','int') 
-- and so on 
FROM @NodeXml.nodes('TechnicalData') td(node); 

--check it 
SELECT @Date,@Title,@Subtitle,@Company ; 
+0

您的回答是正確的,但Snugo的更詳細。 +1雖然 –