2011-04-07 143 views
0

我需要将int的集合传递给sql过程。Sql Server - 将数组传递给过程

alter PROC PrCustomerServicesUpd(
            @CustomerId UNIQUEIDENTIFIER, 
            @ServicesIdXml NVARCHAR(1000), 
            @ServicesIdCount INT =1 
) 
AS 
DECLARE @XmlDocHanle INT 
EXEC sp_Xml_PrepareDocument @XmlDocHanle OUTPUT, @ServicesIdXml 

SELECT * FROM OPENXML(@XmlDocHanle, '/ROOT/Services/ServicesId',@ServicesIdCount) 
WITH (ServiceId INT) 


EXEC sp_Xml_RemoveDocument @XmlDocHanle 



go 
PrCustomerServicesUpd '443c293e-fc78-4562-97f8-ee1f2b54f813' 
,'<Services><ServiceId>12</ServiceId><ServiceId>156</ServiceId></Services>',22 

该脚本返回一个名为'ServiceId'而不是2行的空字段。

回答

3

假设这是SQL Server 2000的(否则就没有理智的理由使用OPENXML),你需要得到text()在节点内,否则它试图在节点“ServiceId”内找到属性“ServiceId”。另外你的参数XML与proc期望的内容完全不同步。

alter PROC PrCustomerServicesUpd(
            @CustomerId UNIQUEIDENTIFIER, 
            @ServicesIdXml NVARCHAR(1000), 
            @ServicesIdCount INT =1 
) 
AS 
DECLARE @XmlDocHanle INT 
EXEC sp_Xml_PrepareDocument @XmlDocHanle OUTPUT, @ServicesIdXml 

SELECT * FROM OPENXML(@XmlDocHanle, '/ROOT/Services/ServicesId',@ServicesIdCount) 
WITH (ServiceId INT 'text()') 


EXEC sp_Xml_RemoveDocument @XmlDocHanle 
GO 

PrCustomerServicesUpd '443c293e-fc78-4562-97f8-ee1f2b54f813' 
,'<ROOT><Services><ServicesId>12</ServicesId><ServicesId>156</ServicesId></Services></ROOT>',3 

使用XML数据类型

alter PROC PrCustomerServicesUpd 
@CustomerId UNIQUEIDENTIFIER, 
@ServicesIdXml xml, 
@ServicesIdCount INT =1 
AS 
select service.id.value('.','int') 
from @ServicesIdXml.nodes('/ROOT/Services/ServicesId') service(id) 
GO 
+0

它正常工作。你推荐什么用于SQL Server 2008 R2而不是openxml? – Alexandre 2011-04-07 07:37:53

+0

@Alex /请参阅答案中的xml数据类型用法 – RichardTheKiwi 2011-04-07 07:40:07

+0

您的意思是'text()'?这是什么意思? – Alexandre 2011-04-07 07:45:05

1

可以传递与逗号分隔符设定为int在VARCHAR(1000)

所以int值传递为 “1223,12,254,5545,8787,8787,787,78,45475,45,45”

而在存储过程中,您可以使用fnSplit函数(表格)逐个获取ID。

ALTER function [dbo].[fnSplit](
@String nvarchar (4000), 
@Delimiter nvarchar (10) 
) 
returns @ValueTable table ([Value] nvarchar(4000)) 
begin 
declare @NextString nvarchar(4000) 
declare @Pos int 
declare @NextPos int 
declare @CommaCheck nvarchar(1) 

--Initialize 
set @NextString = '' 
set @CommaCheck = right(@String,1) 

--Check for trailing Comma, if not exists, INSERT 
--if (@CommaCheck <> @Delimiter) 
set @String = @String + @Delimiter 

--Get position of first Comma 
set @Pos = charindex(@Delimiter,@String) 
set @NextPos = 1 

--Loop while there is still a comma in the String of levels 
while (@pos <> 0) 
begin 
    set @NextString = substring(@String,1,@Pos - 1) 

    insert into @ValueTable ([Value]) Values (@NextString) 

    set @String = substring(@String,@pos +1,len(@String)) 

    set @NextPos = @Pos 
    set @pos = charindex(@Delimiter,@String) 
end 

return 
end 

,所以你可以用一个价值得到了一个为

"Select value from dbo.fnsplit (@values,',')" 
+0

我想通过XML,非CSV! – Alexandre 2011-04-07 07:24:27

0

我想你的意思ServiceId,而不是ServicesId。 另外,OPENXML的第三个参数不应该是@ServicesIdCount,它应该是一个描述你想要的输出类型的值。 不要以为你设置的XML根节点,所以删除

SELECT * FROM OPENXML(@XmlDocHanle, '/ROOT/Services/ServicesId',@ServicesIdCount) 
WITH (ServiceId INT) 

应该

SELECT * FROM OPENXML(@XmlDocHanle, '/Services/ServiceId', 1) 
WITH (ServiceId INT) 
+0

这将在/ Services/ServiceId中查找ServiceId @attribute – RichardTheKiwi 2011-04-07 07:40:47

相关问题