您的位置:首页 > 数据库

SQLServer-存储过程中使用字符串和分隔符实现传递数组参数(转)

2008-03-31 15:53 1326 查看
< DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd> 一 简介

在高级语言中,很容易编写带有数组参数的函数。但在数据库的存储过程中却没有那么容易,因为存储过程的参数只能以一些基本类型作为参数。我们希望数组作为参数的情况是很常见的,例如有一个表Table(Id int, Data nvarchar(50)),需要向该表一次存入一批数据。如果存储过程以基本数据类型作为参数,定义为InsertData(@data nvarchar(50)), 那么需要循环多次调用该存储过程。

要使存储过程支持数组参数,需做一点变通。可以将需输入的数据转换成字符串,并以某一个分隔符隔开组成一个大的字符串,可以用基本类型text 或 ntext表示。将这个字符串传给存储过程,存储过程内部将其解析,即去掉分隔符,把这批数据放入零时表或某个标变量中,最后批量插入数据表中。

二 解析含有分隔符的字符串生成表变量的流程



三 解析含有分隔符的字符串生成表变量的用户函数脚本

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[SplitTextToStringArray]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))

DROP FUNCTION [dbo].[SplitTextToStringArray]

GO

-- =============================================

-- Author: fishinthewind

-- Create date: 7/10/2007

-- Description: Split string variant with type of ntext

-- =============================================

CREATE FUNCTION [dbo].[SplitTextToStringArray]

(

@text ntext,

@delimiter char(1)

)

RETURNS @arrayTable TABLE(Idx bigint, [Value] nvarchar(200))

AS

BEGIN

DECLARE @splitlen int

SET @splitlen = 4000

DECLARE @Idx int SET @Idx = 0

-- 定义取子串的起始位置

DECLARE @textsplit bigint

SET @textsplit = 1

WHILE( @textsplit <= DATALENGTH(@text) )

BEGIN

-- 由于许多字符串处理函数无法用于ntext数据类型

-- 所以需要循环按批处理ntext字符串,一批取出

-- 个字符放入nvarchar(4000)类型的变量中.

DECLARE @string nvarchar(4000)

SELECT @string = SUBSTRING(@text,@textsplit,@splitlen)

-- 能够取出满个字符

IF LEN(@string) = @splitlen

BEGIN

-- 确保取出的个字符是完整的由分隔符隔开的字符串组合

DECLARE @lastcomma int

SELECT @lastcomma = CHARINDEX(@delimiter,REVERSE(@string),1)

-- 最后一个分隔符后面的字符串不完整,应抛弃

IF @lastcomma > 0

BEGIN

SELECT @string = SUBSTRING(@string,1,@splitlen - @lastcomma)

-- 设置下一次从@text取字符的起始位置

SELECT @textsplit = @textsplit + @splitlen - @lastcomma + 1

END

-- 最后一个分隔符后面的字符串完整.

ELSE

BEGIN

SELECT @textsplit = @textsplit + @splitlen + 1

END

END

-- 取出不满个字符

ELSE

BEGIN

SELECT @textsplit = @textsplit + @splitlen + 1

END

-- 解析@string,取出以分隔符为界限的子字符串

DECLARE @i1 int SET @i1 = 1

DECLARE @i2 int SET @i2 = 1

WHILE @i1 <= LEN(@string)

BEGIN

SET @i2 = CHARINDEX(@delimiter,@string,@i1+1)

IF @i2 = 0

SET @i2 = LEN(@string) + 1

INSERT @arrayTable (Idx, Value)

SELECT @Idx, SUBSTRING(@string,@i1,@i2-@i1)

SET @i1 = @i2 + 1

SET @Idx = @Idx + 1

END

END

RETURN

END

GO

四 使用该字符串分隔函数的过程脚本

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GetCategoryRevisionIds]') AND type in (N'P', N'PC'))

DROP PROCEDURE [dbo].[GetCategoryRevisionIds]

GO

-- =============================================

-- Author: fishinthewind

-- Create date: 7/10/2007

-- Description: 使用字符分割函数

-- =============================================

CREATE PROCEDURE [dbo].[GetCategoryRevisionIds]

(

@stringArray ntext

)

AS

BEGIN

-- SET NOCOUNT ON added to prevent extra result sets from

-- interfering with SELECT statements.

SET NOCOUNT ON;

DECLARE @stringArrayT TABLE(Idx bigint, [Value] nvarchar(200))

INSERT INTO @stringArrayT(Idx, [Value])

(

SELECT Idx, [Value]

FROM SplitTextToStringArray(@stringArray, ',')

)

SELECT * FROM @stringArrayT

END

GO
#数据库技术
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: