0

有點背景,這是我的第一篇文章,但我從這個網站得到了很多解決方案。如果這是轉發,我表示歉意,但我一直無法找到一個好的解決方案,並且難以從其他地方拼湊出我想要的東西。如何根據條件從SQL Server寫入XML文件

我發現了一些有關從SQL讀取/導出XML的解決方案(在此處和Google上)。但我有一個具體的問題:我如何從表格中修改XML格式的文件?

我有一個臨時表,其中包含來自我的SQL 2012 STIG查詢的所有發現。我一直在將它導出到一個.csv文件,但我還想添加功能將結果導出到一個.xml文件。

這裏的.XML的例子:

<CHECKLIST> 
    <ID> 
    <SOME_DATA> 
     <ID_ATTRIBUTE>ID_Num</ID_ATTRIBUTE> 
     <ATTRIBUTE_DATA>123</ATTRIBUTE_DATA> 
    </SOME_DATA> 
    <SOME_DATA> 
     <ID_ATTRIBUTE>REF</ID_ATTRIBUTE> 
     <ATTRIBUTE_DATA>54</ATTRIBUTE_DATA> 
    </SOME_DATA> 
    <STATUS>Not_Reviewed</STATUS> 
    <FINDING_DETAILS></FINDING_DETAILS> 
    <COMMENTS></COMMENTS> 
    </ID> 
    <ID> 
    <SOME_DATA> 
     <ID_ATTRIBUTE>ID_Num</ID_ATTRIBUTE> 
     <ATTRIBUTE_DATA>124</ATTRIBUTE_DATA> 
    </SOME_DATA> 
    <SOME_DATA> 
     <ID_ATTRIBUTE>REF</ID_ATTRIBUTE> 
     <ATTRIBUTE_DATA>145</ATTRIBUTE_DATA> 
    </SOME_DATA> 
    <STATUS>Not_Reviewed</STATUS> 
    <FINDING_DETAILS></FINDING_DETAILS> 
    <COMMENTS></COMMENTS> 
    </ID> 

我想要做的是值得的效果:

IF <CHECKLIST/ID/SOME_DATA/ID_ATTRIBUTE> = 'ID_Num' 
    AND <CHECKLIST/ID/SOME_DATA/ID_DATA> = @variable 
     FROM 'e:\stuff\test.xml' 
SET <CHECKLIST/ID/COMMENTS> = @comments_variable 

我認識到,上面的代碼塊一個完整的不正確的查詢迭代,但我希望你能得到我想要做的。

我很感激任何幫助。

自定義存儲過程(不是MS SQL本機)是HIGHLY不鼓勵。

回答

0

你可以用一個變量更新註釋節點的值,像這樣:

declare @x xml = '<CHECKLIST> 
    <ID> 
    <SOME_DATA> 
     <ID_ATTRIBUTE>ID_Num</ID_ATTRIBUTE> 
     <ATTRIBUTE_DATA>123</ATTRIBUTE_DATA> 
    </SOME_DATA> 
    <SOME_DATA> 
     <ID_ATTRIBUTE>REF</ID_ATTRIBUTE> 
     <ATTRIBUTE_DATA>54</ATTRIBUTE_DATA> 
    </SOME_DATA> 
    <STATUS>Not_Reviewed</STATUS> 
    <FINDING_DETAILS></FINDING_DETAILS> 
    <COMMENTS></COMMENTS> 
    </ID> 
    <ID> 
    <SOME_DATA> 
     <ID_ATTRIBUTE>ID_Num</ID_ATTRIBUTE> 
     <ATTRIBUTE_DATA>124</ATTRIBUTE_DATA> 
    </SOME_DATA> 
    <SOME_DATA> 
     <ID_ATTRIBUTE>REF</ID_ATTRIBUTE> 
     <ATTRIBUTE_DATA>145</ATTRIBUTE_DATA> 
    </SOME_DATA> 
    <STATUS>Not_Reviewed</STATUS> 
    <FINDING_DETAILS></FINDING_DETAILS> 
    <COMMENTS></COMMENTS> 
    </ID> 
    </CHECKLIST>'; 



declare @AttributeData int = 123; 
declare @Comments varchar(100) = 'yak yak yak...'; 

set @x.modify('insert text{sql:variable("@Comments")} into (/CHECKLIST/ID/SOME_DATA[ID_ATTRIBUTE = "ID_Num"][ATTRIBUTE_DATA = sql:variable("@AttributeData")]/../COMMENTS)[1]'); 

select @x; 

至於從磁盤讀取XML數據到一個變量,它可能不建議在T-SQL做的,但我已經使用這個有時:

declare @x xml; 

set @x = (
    select * from openrowset(bulk 'C:\temp\yak.xml', single_blob 
) as d; 

在這裏更多信息:https://msdn.microsoft.com/en-us/library/ms191184.aspx

編寫XML變量的文件也是一個任務我可能會做到萬無一失(SSIS,控制檯應用程序等),但有可能在T-SQL:

create table dbo.xStage (x xml); 

insert into dbo.xStage(x) 
    select @x; 

declare @cmd varchar(max), 
     @fileName varchar(max) 

set @fileName = 'c:\temp\myXML.xml' 

set @cmd = 'bcp "select x from YourDB.dbo.xStage" queryout ' + @fileName + ' -w -T -S' + @@servername 

execute master..xp_cmdshell @cmd; 

使用BCP導出XML在此處瞭解詳情:https://sqlsouth.wordpress.com/2014/05/23/export-xml-from-sql-server-using-bcp/

+0

我可以很容易地從@x變量導出到文件?或者它需要從一個表使用bcp? – blackmuttracing

+0

是的,如果這是一次性的事情,你可以直接從t-sql寫入文件,但是如果SSIS的核心組件是你的系統,那麼SSIS可能就是這樣做的地方。 –

+0

我將它發送到全局臨時表,然後通過BCP導回到.xml文件。這不是一件普通的事情。這是一年一度的事情,我有一整個7000k +查詢來檢查系統是否存在漏洞(180多項)。我只是想將它導出爲我們使用的DISA STIG Viewer可以讀取的.xml格式(因爲這最終是我們的IA導入到他們的系統中的東西)。根據你的回答,我能夠把它工作到我想要的。非常感謝你。 – blackmuttracing

1

尤其是考慮一個通用的編程解決方案因爲XML文件原本不在數據庫內,例如BLOB字段中。 SQL是一種專用語言,主要用於管理(更新,附加,刪除)和檢索DML and DDL過程中的數據庫內容。建議不要做更多的事情,例如外部處理文件。但是爲了您的需要,幾乎任何通用語言(包括Java,C#,Perl,PHP,Python和VB)都可以動態解析和操作XML內容。以下是使用您的日常MS Excel的VBA宏示例。實際上,它使用另一種聲明式專用語言XSLT,主要用於修改,重新構造和重新格式化XML文檔。是的大多數編程語言保持XSLT處理器:

XSLT保存爲文件名爲.xsl及以下宏引用的;也可以嵌入在微距字符串)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" /> 

<xsl:param name="var" select="123"/> 

<!-- IdentityTransform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="COMMENTS"> 
    <COMMENTS> 
    <xsl:if test="../SOME_DATA/ID_ATTRIBUTE='ID_Num' and ../SOME_DATA/ATTRIBUTE_DATA = $var"> 
     yak yak yak... 
    </xsl:if> 
    </COMMENTS> 
</xsl:template>  

</xsl:transform> 

要更改變量,評論,只需調整參數值'123'和yak yak yak上面的節點文本。

Excel宏使用微軟的MSXML對象

Sub TransformXML() 
On Error GoTo ErrHandle 
    Dim xmldoc As Object, xsldoc As Object, newdoc As Object 

    Set xmldoc = CreateObject("MSXML2.DOMDocument") 
    Set xsldoc = CreateObject("MSXML2.DOMDocument") 
    Set newdoc = CreateObject("MSXML2.DOMDocument") 

    ' LOAD XML 
    xmldoc.async = False 
    xmldoc.Load "e:\stuff\test.xml" 

    ' LOAD XSL 
    xsldoc.async = False 
    xsldoc.Load "e:\stuff\XSLT-SCRIPT.xsl" 

    ' TRANSFORM 
    xmldoc.transformNodeToObject xsldoc, newdoc 
    newdoc.Save "e:\stuff\Output.xml" 

    MsgBox "XML successfully modified!", vbInformation, "SUCCESSFUL OUTPUT" 

    Set xmldoc = Nothing 
    Set xsldoc = Nothing 
    Set newdoc = Nothing 
    Exit Sub 

ErrHandle: 
    MsgBox Err.Number & " - " & Err.Description, vbCritical 
    Set xmldoc = Nothing 
    Set xsldoc = Nothing 
    Set newdoc = Nothing 
    Exit Sub  
End Sub 

輸出

<?xml version="1.0" encoding="UTF-8"?> 
<CHECKLIST> 
    <ID> 
     <SOME_DATA> 
      <ID_ATTRIBUTE>ID_Num</ID_ATTRIBUTE> 
      <ATTRIBUTE_DATA>123</ATTRIBUTE_DATA> 
     </SOME_DATA> 
     <SOME_DATA> 
      <ID_ATTRIBUTE>REF</ID_ATTRIBUTE> 
      <ATTRIBUTE_DATA>54</ATTRIBUTE_DATA> 
     </SOME_DATA> 
     <STATUS>Not_Reviewed</STATUS> 
     <FINDING_DETAILS> 
     </FINDING_DETAILS> 
     <COMMENTS>yak yak yak...</COMMENTS> 
    </ID> 
    <ID> 
     <SOME_DATA> 
      <ID_ATTRIBUTE>ID_Num</ID_ATTRIBUTE> 
      <ATTRIBUTE_DATA>124</ATTRIBUTE_DATA> 
     </SOME_DATA> 
     <SOME_DATA> 
      <ID_ATTRIBUTE>REF</ID_ATTRIBUTE> 
      <ATTRIBUTE_DATA>145</ATTRIBUTE_DATA> 
     </SOME_DATA> 
     <STATUS>Not_Reviewed</STATUS> 
     <FINDING_DETAILS> 
     </FINDING_DETAILS> 
     <COMMENTS/> 
    </ID> 
</CHECKLIST> 
+0

我喜歡它,萬歲xslt! +1 –

+0

欣賞回覆。我只是想在我的查詢結束時導出一些內容。這不是正常的事情(漏洞掃描一年一次)。但我會保留這個以備將來參考!謝謝回覆。 – blackmuttracing