函数在返回所有结果之前结束

时间:2011-05-29 09:28:14

标签: sql-server xml function dotnetnuke

我正在使用此函数,它允许我查询MS SQL 2005中大型XML表中保存的列表值。

CREATE FUNCTION dbo.KB_XMod_ExtractListFieldValue 
( 
@InstanceData ntext, 
@FieldName nvarchar(80) 
) 
RETURNS nvarchar(255) 
AS 
BEGIN 
DECLARE @Return nvarchar(255) 
DECLARE @Start int 
DECLARE @End int 
DECLARE @FieldValueLength int 
DECLARE @FieldNameLength int 

SELECT @Return=dbo.KB_XMod_ExtractFieldValue(@InstanceData,@FieldName)     
SELECT @Start = CHARINDEX('<value>', @Return) 
SELECT @FieldNameLength = LEN('<value>') 
SELECT @End = CHARINDEX('</value>', @Return) 
SELECT @FieldValueLength = (@End - (@Start + @FieldNameLength)) 


IF @FieldValueLength > 0 
SELECT @Return = SUBSTRING(@Return, @Start + @FieldNameLength, @FieldValueLength) 
ELSE 
SELECT @Return = '' 

RETURN @Return 

END 

这允许我构造一个查询,例如:

SELECT dbo.KB_XMod_ExtractFieldValue(InstanceData,'Name')
FROM KB_XMod_Modules 
WHERE FormID=18

问题是该函数只返回任何记录中的第一个集合。因此,如果XML记录看起来像这样......

<Name>
            <items>
              <item>
                <label>Jimmy</label>
                <value>960</value>
              </item>
              <item>
                <label>John</label>
                <value>938</value>
              </item>
              <item>
                <label>Robert</label>
                <value>989</value>
              </item>
    </items>
</Name>

我只收到第一个项目 - 即<label>Jimmy</label><value>960</value>。 功能对我来说仍然是一个谜,但似乎我的一个停在第一个值而没有循环其余的。如何让它归还所有物品?

感谢您的光临。

1 个答案:

答案 0 :(得分:0)

您通常在SQL Server中使用XPath解析XML,如此

DECLARE @xml xml = '<Name>
            <items>
              <item>
                <label>Jimmy</label>
                <value>960</value>
              </item>
              <item>
                <label>John</label>
                <value>938</value>
              </item>
              <item>
                <label>Robert</label>
                <value>989</value>
              </item>
    </items>
</Name>'

SELECT
   x.item.value('label[1]', 'varchar(100)'),
   x.item.value('value[1]', 'int')
FROM
   @xml.nodes('/Name/items/item') x(item)

在这种情况下,我会尝试这样的假设你从KB_XMod_ExtractFieldValue得到xml

DECLARE @xml xml;

SELECT @xml = dbo.KB_XMod_ExtractFieldValue(InstanceData,'Name')
FROM KB_XMod_Modules 
WHERE FormID=18;

SELECT
   x.item.value('label[1]', 'varchar(100)'),
   x.item.value('value[1]', 'int')
FROM
   @xml.nodes('/Name/items/item') x(item);

但是,您遇到了更大的问题:您正在尝试使用截断xml数据的标量函数来获取类似表的数据

  • 如果你想要一张桌子,你需要使用RETURNS TABLE。请参阅CREATE FUNCTION
  • 你有@Return为nvarchar(255),无论如何都会截断

注意:这是一个函数,而不是启动CREATE PROCEDURE

的存储过程