2011-04-07 139 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

相關問題