查询存储过程中的XML字符串

时间:2011-04-13 21:03:39

标签: sql xml

我目前正在使用存储过程生成报告。存储过程从类似于以下(简称为简洁)的文件表中收集有关未处理文件的信息:

表格结构:

//File Table Fields
FILE_ID (int)
FILE_DATE (string)
FILE_CONTENTS (XML)
FILE_CONTENTS_STRING (string)
PROCESSED (bool)

存储过程:

//Grabs the ID and Date for each of the Unprocessed Files
SELECT [FILE_ID],
       [FILE_DATE]
  FROM [tbFILES]
 WHERE [PROCESSED] = 0

我想输出FILE_CONTENTS(或FILE_CONTENTS_STRING)中的两个附加字段,这两个字段都可以在XML / String中找到,如下所示:

XML结构的一部分:

    <FID.4>
      <FID.4.1>TESTING</FID.4.1>     //File Header
    </FID.4>
    <FID.5>
      <FID.5.1>TEST</FID.5.1>        //Owner Last Name
      <FID.5.2>TEST</FID.5.2>        //Owner First Name
      <FID.5.3 />
      <FID.5.4 />
      <FID.5.5 />
      <FID.5.6 />
      <FID.5.7 />
      <FID.5.8 />
    </FID.5>

我想要完成的是输出这两个值(文件头)和所有者名称(上一个,第一个)作为存储过程调用的一部分。

输出:

[FILE_ID]      //From Table
[FILE_DATE]    //From Table
[FILE_HEADER]  //From FILE_CONTENTS in <FID.4.1></FID.4.1>
[FILE_OWNER]   //From FILE_CONTENTS in <FID.5.1></FID.5.1>,<FID.5.2></FID.5.2>

是否可以使用SQL存储过程从XML文件(FILE_CONTENTS)或字符串形式的XML文件(FILE_CONTENTS_STRING)查询此类信息?

编辑:首次尝试(失败)

SELECT FILE_ID,
       FILE_DATE,
       FILE_CONTENTS.value('(/PID.4/PID.4.1)[1]', 'varchar(16)') as FILE_HEADER,
       FILE_CONTENTS.value('(/PID.5/PID.5.1)[1]', 'varchar(16)') + ', ' +     
       FILE_CONTENTS.value('(/PID.5/PID.5.2)[1]', 'varchar(16)') as FILE_OWNER
  FROM [tbFILES]

FILE_HEADERFILE_OWNER字段产生了NULL。我认为需要更复杂的东西?

再次更新:(问题已解决!)

我不得不在XML中添加一个额外的部分,因为提供的部分最初是一个更大的XML文档的片段。

1 个答案:

答案 0 :(得分:1)

在这里尝试这个问题 - 这样做a)有效吗?b)做你正在寻找的事情吗?

-- test data setup
DECLARE @test TABLE (FILE_ID INT, FILE_DATE DATETIME, FILE_CONTENTS XML)

INSERT INTO @test VALUES(4711, '20110414', 
'<FID.4>
      <FID.4.1>TESTING</FID.4.1>     //File Header
    </FID.4>
    <FID.5>
      <FID.5.1>TEST_LN</FID.5.1>        //Owner Last Name
      <FID.5.2>TEST_FN</FID.5.2>        //Owner First Name
      <FID.5.3 />
      <FID.5.4 />
    </FID.5>')

-- select the values from the table and cross apply bits from the XML   
SELECT 
     FILE_ID ,
     FILE_DATE ,
     Node.value('(/FID.4/FID.4.1/text())[1]', 'varchar(50)') AS 'File_Header',
     Node.value('(/FID.5/FID.5.1/text())[1]', 'varchar(50)') + ', ' +
     Node.value('(/FID.5/FID.5.2/text())[1]', 'varchar(50)') AS 'File_Owner'
FROM
    @test
CROSS APPLY
    FILE_CONTENTS.nodes('/*') AS Content(Node)

我的输出如下:

FILE_ID   FILE_DATE                File_Header   File_Owner
 4711     2011-04-14 00:00:00.000   TESTING      TEST_LN, TEST_FN
 4711     2011-04-14 00:00:00.000   TESTING      TEST_LN, TEST_FN

如果你的XML有一个合适的根元素,你可能会更好(在性能方面) - 在CROSS APPLY条件中使用正确的XPath从XML中获取那些重复节点想。