Sql server 高效分解以元素为中心的XML TSQL
我正在尝试拆分具有多个嵌套元素级别的XML文档:Sql server 高效分解以元素为中心的XML TSQL,sql-server,xml,performance,tsql,xquery-sql,Sql Server,Xml,Performance,Tsql,Xquery Sql,我正在尝试拆分具有多个嵌套元素级别的XML文档: <server> <name>111.111.11.11</name> <displayName>EVIL SERVER</displayName> <comment /> <logonCredentials inherit="None">
<server>
<name>111.111.11.11</name>
<displayName>EVIL SERVER</displayName>
<comment />
<logonCredentials inherit="None">
<userName>user</userName>
<domain>DOMAIN</domain>
<password storeAsClearText="True">xxxxxxx</password>
</logonCredentials>
<connectionSettings inherit="FromParent" />
<gatewaySettings inherit="FromParent" />
<remoteDesktop inherit="FromParent" />
<localResources inherit="None">
<audioRedirection>2</audioRedirection>
<audioRedirectionQuality>2</audioRedirectionQuality>
<audioCaptureRedirection>0</audioCaptureRedirection>
<keyboardHook>2</keyboardHook>
<redirectClipboard>True</redirectClipboard>
<redirectDrives>True</redirectDrives>
<redirectPorts>False</redirectPorts>
<redirectPrinters>False</redirectPrinters>
<redirectSmartCards>False</redirectSmartCards>
</localResources>
<securitySettings inherit="FromParent" />
<displaySettings inherit="FromParent" />
</server>
<server>
<name>111.12.11.11</name>
<displayName>NICE SERVER</displayName>
<comment />
<logonCredentials inherit="None">
<userName>user2</userName>
<domain>DOMAIN2</domain>
<password storeAsClearText="True">xxxxxxx</password>
</logonCredentials>
<connectionSettings inherit="FromParent" />
<gatewaySettings inherit="FromParent" />
<remoteDesktop inherit="FromParent" />
<localResources inherit="FromParent" />
<securitySettings inherit="FromParent" />
<displaySettings inherit="FromParent" />
</server>
然而,我只是开始构建这个查询,很明显,它将永远无法运行
我也尝试过OPENXML,但我只能得到一个级别 我不会在Transact-SQL中这样做。虽然您可以在SQL Server中处理XML,但只有在无法在更高级别上处理XML时,您才希望在SQL Server中处理XML,因为您有更好(更快)的工具 如果我是你,我会在C#中编写一组简单的类,该类是XElement的子类,并公开一个名为StuffParameters()的方法,以方便使用insert/update语句。因为XML分解在.Net中非常简单
// Typed in the editor -- code needs to be eval'd before attempting to compile!
public class ServerData: XElement
{
public ServerData(string strServer): base(strServer)
{
// Base class initializes XElement with XML, throws error if XML not well-formed
}
// Properties
public string Name // One example of the two dozen properties you'll need
{
get()
{
return GetAttribute("name");
}
}
// StuffParameters
public bool StuffParameters(SqlCommand objCommand)
{
// In real life you'd use try...catch, but this is prototype code, right?
objCommand.Parameters["@ServerName"].Value = Name;
// ... and so forth
}
}
从服务器XDocuments列表开始;为每个类创建该类的实例。创建到数据库的连接,并使用存储过程创建SqlCommand对象。迭代这些类的列表,将命令传递给每个类实例的StuffParameters()方法
当函数返回时,对命令调用ExecuteNonQuery(),您就已经将记录插入到表中了
更少的编码,更正统的处理XML的方法——因此,如果您不得不更改它,您不会得到一个需要花费数小时思考的令人头痛的方法
希望这对您有所帮助……这实际上比您预期的要简单得多。通过使用单个
.nodes()
函数,然后在.value()
函数中指定子路径,可以轻松地遍历XML:
SELECT n.value('(./name/text())[1]','varchar(15)') AS [name],
n.value('(./displayName/text())[1]','varchar(15)') AS [displayName],
n.value('(./comment/text())[1]','varchar(15)') AS [comment],
n.value('(./logonCredentials/userName/text())[1]','varchar(15)') AS [userName],
n.value('(./logonCredentials/domain/text())[1]','varchar(15)') AS [domain],
n.value('(./logonCredentials/password/text())[1]','varchar(15)') AS [password],
n.value('(./connectionSettings/text())[1]','varchar(15)')
AS [connectionSettings],
n.value('(./gatewaySettings/text())[1]','varchar(15)') AS [gatewaySettings],
n.value('(./remoteDesktop/text())[1]','varchar(15)') AS [remoteDesktop],
n.value('(./localResources/audioRedirection/text())[1]','varchar(15)')
AS [audioRedirection],
n.value('(./localResources/audioRedirectionQuality/text())[1]','varchar(15)')
AS [audioRedirectionQuality],
n.value('(./localResources/audioCaptureRedirection/text())[1]','varchar(15)')
AS [audioCaptureRedirection],
n.value('(./securitySettings/text())[1]','varchar(15)') AS [securitySettings],
n.value('(./displaySettings/text())[1]','varchar(15)') AS [displaySettings]
FROM @RDCM.nodes('/group/server') AS s(n)
全面测试:
DECLARE @RDCM XML
SET @RDCM = N'<group>
<server>
<name>111.111.11.11</name>
<displayName>EVIL SERVER</displayName>
<comment />
<logonCredentials inherit="None">
<userName>user</userName>
<domain>DOMAIN</domain>
<password storeAsClearText="True">xxxxxxx</password>
</logonCredentials>
<connectionSettings inherit="FromParent" />
<gatewaySettings inherit="FromParent" />
<remoteDesktop inherit="FromParent" />
<localResources inherit="None">
<audioRedirection>2</audioRedirection>
<audioRedirectionQuality>2</audioRedirectionQuality>
<audioCaptureRedirection>0</audioCaptureRedirection>
<keyboardHook>2</keyboardHook>
<redirectClipboard>True</redirectClipboard>
<redirectDrives>True</redirectDrives>
<redirectPorts>False</redirectPorts>
<redirectPrinters>False</redirectPrinters>
<redirectSmartCards>False</redirectSmartCards>
</localResources>
<securitySettings inherit="FromParent" />
<displaySettings inherit="FromParent" />
</server>
<server>
<name>111.12.11.11</name>
<displayName>NICE SERVER</displayName>
<comment />
<logonCredentials inherit="None">
<userName>user2</userName>
<domain>DOMAIN2</domain>
<password storeAsClearText="True">xxxxxxx</password>
</logonCredentials>
<connectionSettings inherit="FromParent" />
<gatewaySettings inherit="FromParent" />
<remoteDesktop inherit="FromParent" />
<localResources inherit="FromParent" />
<securitySettings inherit="FromParent" />
<displaySettings inherit="FromParent" />
</server>
</group>'
SELECT n.value('(./name/text())[1]','varchar(15)') AS [name],
n.value('(./displayName/text())[1]','varchar(15)') AS [displayName],
n.value('(./comment/text())[1]','varchar(15)') AS [comment],
n.value('(./logonCredentials/userName/text())[1]','varchar(15)') AS [userName],
n.value('(./logonCredentials/domain/text())[1]','varchar(15)') AS [domain],
n.value('(./logonCredentials/password/text())[1]','varchar(15)') AS [password],
n.value('(./connectionSettings/text())[1]','varchar(15)')
AS [connectionSettings],
n.value('(./gatewaySettings/text())[1]','varchar(15)') AS [gatewaySettings],
n.value('(./remoteDesktop/text())[1]','varchar(15)') AS [remoteDesktop],
n.value('(./localResources/audioRedirection/text())[1]','varchar(15)')
AS [audioRedirection],
n.value('(./localResources/audioRedirectionQuality/text())[1]','varchar(15)')
AS [audioRedirectionQuality],
n.value('(./localResources/audioCaptureRedirection/text())[1]','varchar(15)')
AS [audioCaptureRedirection],
n.value('(./securitySettings/text())[1]','varchar(15)') AS [securitySettings],
n.value('(./displaySettings/text())[1]','varchar(15)') AS [displaySettings]
FROM @RDCM.nodes('/group/server') AS s(n)
DECLARE@RDCM-XML
设置为@RDCM=N'
111.111.11.11
邪恶服务器
使用者
领域
xxxxxxx
2.
2.
0
2.
符合事实的
符合事实的
错误的
错误的
错误的
111.12.11.11
好服务器
用户2
域2
xxxxxxx
'
选择n.value(“(./name/text())[1]”,'varchar(15)”作为[name],
n、 值(“(./displayName/text())[1]”,'varchar(15)”作为[displayName],
n、 值(“(./comment/text())[1]”,'varchar(15)”作为[comment],
n、 值(“(./logonCredentials/userName/text())[1]”,'varchar(15)”作为[userName],
n、 值(“(./logonCredentials/domain/text())[1]”,'varchar(15)”作为[domain],
n、 值(“(./logonCredentials/password/text())[1]”,'varchar(15)”作为[password],
n、 值('(./connectionSettings/text())[1]','varchar(15)'
作为[连接设置],
n、 值(“(./gatewaySettings/text())[1]”,“varchar(15)”作为[gatewaySettings],
n、 值(“(./remoteDesktop/text())[1]”,'varchar(15)”作为[remoteDesktop],
n、 值('(./localResources/audioRedirection/text())[1],'varchar(15)'
作为[音频重定向],
n、 值(“(./localResources/audioRedirectionQuality/text())[1]”,'varchar(15)'
作为[音频重定向质量],
n、 值(“(./localResources/audioCaptureRedirection/text())[1]”,'varchar(15)'
作为[音频捕获重定向],
n、 值(“(./securitySettings/text())[1]”,“varchar(15)”作为[securitySettings],
n、 值(“(./displaySettings/text())[1]”,“varchar(15)”作为[displaySettings]
将@RDCM.nodes('/group/server')作为s(n)从
永远是一段很长的时间。您的XML有多大?您必须解析多少个服务器节点?需要多长时间?而且看起来你根本不需要交叉申请。在values()函数中使用路径表达式完全可以。openxml也是如此。您正在服务器上分解,其余的只是为了找到您需要的值。
DECLARE @RDCM XML
SET @RDCM = N'<group>
<server>
<name>111.111.11.11</name>
<displayName>EVIL SERVER</displayName>
<comment />
<logonCredentials inherit="None">
<userName>user</userName>
<domain>DOMAIN</domain>
<password storeAsClearText="True">xxxxxxx</password>
</logonCredentials>
<connectionSettings inherit="FromParent" />
<gatewaySettings inherit="FromParent" />
<remoteDesktop inherit="FromParent" />
<localResources inherit="None">
<audioRedirection>2</audioRedirection>
<audioRedirectionQuality>2</audioRedirectionQuality>
<audioCaptureRedirection>0</audioCaptureRedirection>
<keyboardHook>2</keyboardHook>
<redirectClipboard>True</redirectClipboard>
<redirectDrives>True</redirectDrives>
<redirectPorts>False</redirectPorts>
<redirectPrinters>False</redirectPrinters>
<redirectSmartCards>False</redirectSmartCards>
</localResources>
<securitySettings inherit="FromParent" />
<displaySettings inherit="FromParent" />
</server>
<server>
<name>111.12.11.11</name>
<displayName>NICE SERVER</displayName>
<comment />
<logonCredentials inherit="None">
<userName>user2</userName>
<domain>DOMAIN2</domain>
<password storeAsClearText="True">xxxxxxx</password>
</logonCredentials>
<connectionSettings inherit="FromParent" />
<gatewaySettings inherit="FromParent" />
<remoteDesktop inherit="FromParent" />
<localResources inherit="FromParent" />
<securitySettings inherit="FromParent" />
<displaySettings inherit="FromParent" />
</server>
</group>'
SELECT n.value('(./name/text())[1]','varchar(15)') AS [name],
n.value('(./displayName/text())[1]','varchar(15)') AS [displayName],
n.value('(./comment/text())[1]','varchar(15)') AS [comment],
n.value('(./logonCredentials/userName/text())[1]','varchar(15)') AS [userName],
n.value('(./logonCredentials/domain/text())[1]','varchar(15)') AS [domain],
n.value('(./logonCredentials/password/text())[1]','varchar(15)') AS [password],
n.value('(./connectionSettings/text())[1]','varchar(15)')
AS [connectionSettings],
n.value('(./gatewaySettings/text())[1]','varchar(15)') AS [gatewaySettings],
n.value('(./remoteDesktop/text())[1]','varchar(15)') AS [remoteDesktop],
n.value('(./localResources/audioRedirection/text())[1]','varchar(15)')
AS [audioRedirection],
n.value('(./localResources/audioRedirectionQuality/text())[1]','varchar(15)')
AS [audioRedirectionQuality],
n.value('(./localResources/audioCaptureRedirection/text())[1]','varchar(15)')
AS [audioCaptureRedirection],
n.value('(./securitySettings/text())[1]','varchar(15)') AS [securitySettings],
n.value('(./displaySettings/text())[1]','varchar(15)') AS [displaySettings]
FROM @RDCM.nodes('/group/server') AS s(n)