我很难找到一种方法来改进这个自定义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>
这只是脚本的一小部分。 TechnicalData包含大约20个节点,所有节点都必须进行解析。完整的脚本可以找到here
这个自定义脚本的原因是因为我需要使用ssrs报告扩展Umbraco站点。
答案 0 :(得分: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 ;
答案 1 :(得分:1)
您的方法很慢,因为您一遍又一遍地从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(基于集合/内联/ ad-hoc 在大多数情况下优于程序)并使用那里的值。但是:很容易将收集的信息填充到声明的变量中(如果真的需要)。在这种情况下,只需使用正确的类型声明变量并使用语法
SELECT @MyVariable=td.value('@id','int')
,@OtherVariable= ...
... same for the rest...