XML查询交叉应用将返回数据作为单行

时间:2018-07-31 14:14:59

标签: sql xml

我正在尝试使用SQL Server Express 2017解析某些XML。我无法发布XML样本,因为它包含患者数据。当我使用交叉应用函数尝试将多个XML数据元素与左侧对齐时,我将XML中的所有内容作为单个字符字符串获取。我已经尝试了在StackOverflow和Google上可以找到的所有内容,但没有任何效果。我尝试了多个选择语句,外部应用,不同,并且所有语法都不正确或产生相同的结果。这是我尝试使用的查询。

USE PatientSurvey
CREATE TABLE PG_Questions(Survey_ID int, Client_ID int, Service2 varchar(6),
RecDate date, DisDate date, Varname3 varchar(200), [Value] int);
GO

Declare @fileData XML

-- import the file contents into the variable
Select @fileData=BulkColumn from 
OpenRowSet(Bulk'C:\path_here\XML_test.txt',Single_blob) x;

insert into PG_Questions
  (Survey_ID, Client_ID, Service2, RecDate, DisDate, Varname3) 
select

Data.xData.query('SURVEY_ID').value('.','int'),
Data.xData.query('CLIENT_ID').value('.','int'),
Data.xData.query('SERVICE').value('.','varchar(6)'),
Data.xData.query('RECDATE').value('.','date'),
Data.xData.query('DISDATE').value('.','date'),
Data.xData.query('ANALYSIS/RESPONSE/VARNAME').value('.','varchar(200)')
--  Data.xData.query('VALUE').value('.','int')
from @fileData.nodes('/DATA_EXPORT/PATIENTLEVELDATA') as Data(xData)
CROSS APPLY Data.xData.nodes('/DATA_EXPORT/PATIENTLEVELDATA/ANALYSIS/RESPONSE/VARNAME') 
as Data2(xData2)
--CROSS APPLY @fileData.nodes('/DATA_EXPORT/PATIENTLEVELDATA/ANALYSIS/RESPONSE/VALUE')
   as Data3(xData3)


SELECT * FROM PG_Questions;
GO

DROP TABLE PG_Questions;
GO

这就是我得到的。 Varname3列仅重复XML中的所有数据,而不会对其进行分解。是否有可能让十字架申请正确地做到这一点?忽略“值”列,我正在等着使该列开始工作。每个单元格应该是两个字符的代码,但是SQL会同时运行它们。如何将其分解为单列中的行?

Data

示例XML:

<DATA_EXPORT>
<PATIENTLEVELDATA>
    <SURVEY_ID>00000001</SURVEY_ID>
    <CLIENT_ID>0000002</CLIENT_ID>
    <SERVICE>IN</SERVICE>
    <RECDATE>2018-01-12</RECDATE>
    <DISDATE>2017-06-16</DISDATE>
<ANALYSIS>
    <RESPONSE>
        <VARNAME>A1</VARNAME>
        <VALUE>4</VALUE>
    </RESPONSE>
    <RESPONSE>
        <VARNAME>A2</VARNAME>
        <VALUE>4</VALUE>
    </RESPONSE>
    <RESPONSE>
        <VARNAME>D1</VARNAME>
        <VALUE>4</VALUE>
    </RESPONSE>
    <RESPONSE>
        <VARNAME>D2</VARNAME>
        <VALUE>5</VALUE>
    </RESPONSE>
    <RESPONSE>
        <VARNAME>D3</VARNAME>
        <VALUE>4</VALUE>
    </RESPONSE>
    <RESPONSE>
        <VARNAME>I1</VARNAME>
        <VALUE>5</VALUE>
</ANALYSIS>
</PATIENTLEVELDATA>
</DATA_EXPORT>

2 个答案:

答案 0 :(得分:1)

您需要类似的东西吗?

DECLARE @xml XML=
'<DATA_EXPORT>
  <PATIENTLEVELDATA>
    <SURVEY_ID>00000001</SURVEY_ID>
    <CLIENT_ID>0000002</CLIENT_ID>
    <SERVICE>IN</SERVICE>
    <RECDATE>2018-01-12</RECDATE>
    <DISDATE>2017-06-16</DISDATE>
    <ANALYSIS>
      <RESPONSE>
        <VARNAME>A1</VARNAME>
        <VALUE>4</VALUE>
      </RESPONSE>
      <RESPONSE>
        <VARNAME>A2</VARNAME>
        <VALUE>4</VALUE>
      </RESPONSE>
      <RESPONSE>
        <VARNAME>D1</VARNAME>
        <VALUE>4</VALUE>
      </RESPONSE>
      <RESPONSE>
        <VARNAME>D2</VARNAME>
        <VALUE>5</VALUE>
      </RESPONSE>
      <RESPONSE>
        <VARNAME>D3</VARNAME>
        <VALUE>4</VALUE>
      </RESPONSE>
      <RESPONSE>
        <VARNAME>I1</VARNAME>
        <VALUE>5</VALUE>
      </RESPONSE>
    </ANALYSIS>
  </PATIENTLEVELDATA>
</DATA_EXPORT>';

SELECT @xml.value('(/DATA_EXPORT/PATIENTLEVELDATA/SURVEY_ID/text())[1]','nvarchar(100)') AS Survey_Id
      ,@xml.value('(/DATA_EXPORT/PATIENTLEVELDATA/CLIENT_ID/text())[1]','nvarchar(100)') AS Client_Id
      ,@xml.value('(/DATA_EXPORT/PATIENTLEVELDATA/SERVICE/text())[1]','nvarchar(100)') AS [Service]
      ,@xml.value('(/DATA_EXPORT/PATIENTLEVELDATA/RECDATE/text())[1]','date') AS RecDate
      ,@xml.value('(/DATA_EXPORT/PATIENTLEVELDATA/DISDATE/text())[1]','date') AS DisDate
      ,@xml.value('(/DATA_EXPORT/PATIENTLEVELDATA/ANALYSIS/RESPONSE[(VARNAME/text())[1]="A1"]/VALUE/text())[1]','int') AS Response_A1
      ,@xml.value('(/DATA_EXPORT/PATIENTLEVELDATA/ANALYSIS/RESPONSE[(VARNAME/text())[1]="A2"]/VALUE/text())[1]','int') AS Response_A2
      ,@xml.value('(/DATA_EXPORT/PATIENTLEVELDATA/ANALYSIS/RESPONSE[(VARNAME/text())[1]="D1"]/VALUE/text())[1]','int') AS Response_D1
      --more of them

这将是一个更表格化的查询:

SELECT ld.value('(SURVEY_ID/text())[1]','nvarchar(100)') AS Survey_Id
      ,ld.value('(CLIENT_ID/text())[1]','nvarchar(100)') AS Client_Id
      ,ld.value('(SERVICE/text())[1]','nvarchar(100)') AS [Service]
      ,ld.value('(RECDATE/text())[1]','date') AS RecDate
      ,ld.value('(DISDATE/text())[1]','date') AS DisDate
      ,r.value('(VARNAME/text())[1]','nvarchar(100)') VarName
      ,r.value('(VALUE/text())[1]','int') VarValue
FROM @xml.nodes('/DATA_EXPORT/PATIENTLEVELDATA') A(ld)
CROSS APPLY ld.nodes('ANALYSIS/RESPONSE') B(r);

答案 1 :(得分:0)

由于我的回答太慢,因此我仍将其发布给操作员以表明他离预期的结果还差得很远:

select
Data.xData.query('SURVEY_ID').value('.','int'),
Data.xData.query('CLIENT_ID').value('.','int'),
Data.xData.query('SERVICE').value('.','varchar(6)'),
Data.xData.query('RECDATE').value('.','date'),
Data.xData.query('DISDATE').value('.','date'),
Data2.xData2.query('VARNAME').value('.', 'varchar(200)'),
Data2.xData2.query('VALUE').value('.','int')
from @fileData.nodes('/DATA_EXPORT/PATIENTLEVELDATA') as Data(xData)
CROSS APPLY @fileData.nodes('/DATA_EXPORT/PATIENTLEVELDATA/ANALYSIS/RESPONSE') as Data2(xData2)