2016-08-08 56 views
4

我想從數據類型爲ntext的列中讀取XML結構中的SQL Server查詢中的值。使用SQL Server從複雜的XML結構中讀取值

這是我想提取VALUE TO READ!!! XML結構:

<PrinterProcessDef xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://dev.docuware.com/settings/workflow/processdef" Id="3e62848d-040e-4f4c-a893-ed85a7b2878a" Type="PrinterProcess" ConfigId="c43792ed-1934-454b-a40f-5f4dfec933b0" Enabled="true" PCId="2837f136-028d-47ed-abdc-4103bedce1d2" Timestamp="2016-08-08T09:44:38.532415"> 
    <Configs> 
    <Config xmlns:q1="http://dev.docuware.com/settings/workflow/processconfig" xsi:type="q1:PrinterProcessConfig" Id="c43792ed-1934-454b-a40f-5f4dfec933b0" /> 
    <Config xmlns:q2="http://dev.docuware.com/settings/workflow/processconfig" xsi:type="q2:RecognizeActConfig" Id="b89a6fc2-5573-4034-978a-752c6c0de4cf"> 
     <q2:Header DefaultRecognitionTechnology="OCR" DefaultOCRSettingsGuid="00000000-0000-0000-0000-000000000000"> 
     </q2:Header> 
     <q2:Body> 
     <q2:AnchorDefs /> 
     <q2:ZoneDefs /> 
     <q2:TableDefs /> 
     <q2:FaceLayouts> 
     </q2:FaceLayouts> 
     <q2:FaceSamples> 
     </q2:FaceSamples> 
     <q2:SampleDocument> 
      <MetaData xmlns="http://dev.docuware.com/settings/common" FileName="Test - Editor" MimeType="application/pdf" PageCount="1" SourceAppName="C:\Windows\system32\NOTEPAD.EXE" DocumentTitle="Test - Editor" PdfCreator="DocuWare Printer" /> 
      <Data xmlns="http://dev.docuware.com/settings/common">!!!VALUE TO READ!!!</Data> 
     </q2:SampleDocument> 
     </q2:Body> 
     <q2:AllPagesRequired>false</q2:AllPagesRequired> 
    </Config> 
    <Config xmlns:q3="http://dev.docuware.com/settings/workflow/processconfig" xsi:type="q3:RecognizeActConfig" Id="db5b195d-79e4-4804-bd38-f4fc7e8d5a8d"> 
    </Config> 
    <Config xmlns:q4="http://dev.docuware.com/settings/workflow/processconfig" xsi:type="q4:AddOverlayActConfig" Id="023aab08-c6e3-4f08-9d26-0175d1564ef2"> 
     <q4:Overlays /> 
    </Config> 
    <Config xmlns:q5="http://dev.docuware.com/settings/workflow/processconfig" xsi:type="q5:PrintActConfig" Id="4a4ec06a-8652-4777-84d2-53cb862b3328"> 
    </Config> 
    <Config xmlns:q6="http://dev.docuware.com/settings/workflow/processconfig" xsi:type="q6:SignActConfig" Id="8c030961-e68e-4c2f-83f1-cac20f51d4d6"> 
    </Config> 
    <Config xmlns:q7="http://dev.docuware.com/settings/workflow/processconfig" xsi:type="q7:EmailActConfig" Id="5dbd144b-5c33-407a-b638-e062f9045fb4"> 
    </Config> 
    <Config xmlns:q8="http://dev.docuware.com/settings/workflow/processconfig" xsi:type="q8:IndexActConfig" Id="f2a70e07-d76e-4e82-9313-7c665df4c311"> 
    </Config> 
    <Config xmlns:q10="http://dev.docuware.com/settings/workflow/processconfig" xsi:type="q10:StoreActConfig" Id="ff8aec66-608e-4dde-a4b6-de65ada39bb0"> 
    </Config> 
    <Config xmlns:q11="http://dev.docuware.com/settings/workflow/processconfig" xsi:type="q11:NotifyUserActConfig" Id="7ffb0437-6b8c-4f5f-8f40-434f4a6d609a" /> 
    </Configs> 
    <Activities> 
    </Activities> 
</PrinterProcessDef> 

這是SQL查詢我所用:

SELECT 
    CAST([Table].[settings] as xml) 
     .value('declare namespace q2="http://dev.docuware.com/settings/workflow/processconfig"; 
     (/PrinterProcessDef/Configs/Config[@xsi:type="q2:RecognizeActConfig"]/q2:Body/q2:SampleDocument/Data/text())[1]', 
     'varchar(max)') 
FROM 
    [DB].[dbo].[Table] 

我得到的返回是一個NULL,而不是希望 - 對於VALUE TO READ!!!

我應該怎麼做才能使查詢工作?

我也試過不同的版本沒有名稱空間聲明和其他人,但我總是得到NULL。

+0

'ntext', 'text'和'image'數據類型將在未來版本的SQL Server中刪除。避免在新的開發工作中使用這些數據類型,並計劃修改當前正在使用它們的應用程序。改爲使用'nvarchar(max)','varchar(max)'和'varbinary(max)'。 [在此處查看詳細信息](http://msdn.microsoft.com/en-us/library/ms187993.aspx) - 或者在這種情況下,如果您要存儲XML - 那麼**使用** XML數據類型!這就是它的原因! –

回答

3

所有元素都有名稱空間定義。您需要根據定義聲明並指定它們

SELECT CAST([Table].[settings] as xml).value(
    'declare namespace top="http://dev.docuware.com/settings/workflow/processdef"; 
    declare namespace q2="http://dev.docuware.com/settings/workflow/processconfig"; 
    declare namespace nd="http://dev.docuware.com/settings/common"; 
    (/top:PrinterProcessDef/top:Configs/top:Config[@xsi:type="q2:RecognizeActConfig"]/q2:Body/q2:SampleDocument/nd:Data)[1]', 
     'varchar(max)') 
FROM [DB].[dbo].[Table] 
+0

由於在這種情況下給出了奇怪的命名空間,我寧願建議避免(掩蓋)它們... – Shnugo

1

您忘記了使用xmlns屬性聲明的名稱空間。看看下面的例子:

DECLARE @xml xml = 'yourXml' 

SELECT @xml.value(' 
declare namespace q2="http://dev.docuware.com/settings/workflow/processconfig"; 
declare namespace g="http://dev.docuware.com/settings/workflow/processdef"; 
declare namespace qd="http://dev.docuware.com/settings/common"; 
(//g:PrinterProcessDef/g:Configs/g:Config[@xsi:type="q2:RecognizeActConfig"]/q2:Body/q2:SampleDocument/qd:Data/text())[1]', 
    'varchar(max)') 
+0

在這種情況下,我給出了奇怪的命名空間,我寧願建議避免(掩蓋)它們... – Shnugo

1

但是生成此XML,命名空間是很奇怪......你有相同的命名空間中聲明瞭個遍......如果我沒有得到這個錯誤,命名空間是不是真正的事情應該是這樣,所以我會忽略它們:

SELECT 
    CAST([Table].[settings] as xml as xml) 
     .value('(/*:PrinterProcessDef/*:Configs/*:Config[@*:type="q2:RecognizeActConfig"]/*:Body/*:SampleDocument/*:Data/text())[1]', 
     'varchar(max)') 
FROM 
    [DB].[dbo].[Table] 

反正我勸你申報WITH XMLNAMESPACE內的命名空間,而不是.value -function內。如果你需要一個以上的值超出這個,你可以創建更好的閱讀查詢:

WITH XMLNAMESPACES(DEFAULT 'http://dev.docuware.com/settings/workflow/processdef' 
        ,'http://dev.docuware.com/settings/workflow/processconfig' AS q2 
        ,'http://dev.docuware.com/settings/common' AS nd) 
SELECT 
    CAST([Table].[settings] as xml) 
     .value('(/PrinterProcessDef/Configs/Config[@xsi:type="q2:RecognizeActConfig"]/q2:Body/q2:SampleDocument/nd:Data)[1]', 
     'varchar(max)') 

BTW:使用DEFAULT避免了虛擬命名空間像在其他的答案top: ...