2016-08-02 4 views
0

このカスタムSQLスクリプトをUmbracoデータベースに改善する方法を見つけるのに苦労しています。XMLを高速に解析するこのSQL関数を作成するにはどうすればいいですか?

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> 

これはの唯一のごく一部である。ここ

が取得し、XMLを解析し、正しい値を選択するために、SQLスクリプトですスクリプト。 TechnicalDataには約20個のノードがあり、すべてを解析する必要があります。 here

このカスタムスクリプトの理由は、私がssrsレポートでUmbracoサイトを拡張する必要があったためです。あなたは何度も何度もあなたのXMLのうち、情報の1つのビットを取るため

+2

使用するSQL Serverのバージョンは? 'title'の内容はSQL Server 2016のJSONで、' parseJSON'を使用することができます – gofr1

+0

私は知っていますが、2012年のインストールです。この質問に遭遇する他の人のために+1 –

答えて

1

あなたのアプローチを選択するには、遅いです。

あなたのXMLのすべてのデータ型が1つのsinlgeに入り、文字列の解析が行われません。

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) 

この場合の結果は、すべてのデータを列にまとめた1行です。

私はあなたがよりよいCTEとして上記を使用して、宣言された変数に値を必要とすることを、疑う(セットベース/インライン/アドホックはよりも良好手続きほとんどの場合あり)と、そこからの値を使用します。しかし、収集された情報を宣言された変数に(実際に必要な場合)同様に埋め込むことは容易でした。この場合、正しいタイプの変数を宣言して構文を使用してください。

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

これは確かに少し速いもの。私はまた、ssrsがクエリparamとしてクエリの上にすべての宣言されたvarを自動的にバインドするように見えるので、すべての宣言のためにクエリparamsを作成する必要性を回避するストアドプロシージャにクエリを置くことを終了しました... –

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しかし –

関連する問題