开发者

Sql Server - pass array to procedure

开发者 https://www.devze.com 2023-02-22 21:40 出处:网络
I need to pass set of int to sql procedure. alter PROC PrCustomerServicesUpd( @CustomerId UNIQUEIDENTIFIER,

I need to pass set of int to sql procedure.

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

This script returns one empty field named 'ServiceId' instead of 2 rows.


Assuming this is SQL Server 2000 (otherwise there is no sane reason to use OPENXML), you need to get the text() within the node, otherwise it tries to find the attribute "ServiceId" within the node "ServiceId". Also your parameter XML is completely out of sync with what the proc expects.

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

Using the XML data type

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


You can pass set of int in varchar(1000) with comma separator

so int value passing as "1223,12,254,5545,8787,8787,787,78,45475,45,45"

And in store procedure you can get one by one id with fnSplit function (Tabular).

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

so you can get the one by one value as

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


I think you mean ServiceId and not ServicesId. In addition the third parameter of OPENXML should not be @ServicesIdCount, it should be a value describing what sort of output you want. Don't think you specify a ROOT node in your XML, so remove that

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

should be

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

精彩评论

暂无评论...
验证码 换一张
取 消