2011-04-13 59 views
1

我目前正在使用存储过程生成报告。查询存储过程中的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 
存储过程从文件的表,类似于以下 (simplfied为了简洁)收集关于未处理文件的信息

我想输出两个额外的字段,在FILE_CONTENTS(或FILE_CONTENTS_STRING),这是在XML /字符串都发现在地区这样的:

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> 

我想什么来完成是输出这两个值(文件标题)和所有者名称(Last,First)作为存储过程调用的一部分。

输出:

[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> 

是它有可能使XML文件(FILE_CONTENTS)或字符串形式(FILE_CONTENTS_STRING)XML文件使用存储过程中的SQL查询这种类型的信息?

编辑:第一次尝试(不成功)

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] 

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

更新:(!问题解决)

我不得不额外部分添加到XML,因为所提供的部分本来是一个更大的XML文档的片段。

回答

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有一个适当的根元素,你很可能使这更好的(在性能方面) - 使用适当的XPath在CROSS APPLY条件来从XML中获取所需的重复节点位。

+0

嗨马克,我感谢您的答案,当我试图使用它时,我收到了File_Header和File_Owner字段中的NULL值。我会继续尝试一些微小的变化,希望取得一些进展。 – 2011-04-14 15:58:41

+0

只是一个更新马克 - 我能够让我的原始方法工作(只是使用该值),显然我不得不进一步看,并添加一个额外的水平到Node.value部分。我感谢您的帮助 :) – 2011-04-14 16:13:52