代码改变世界

Sql Server 中模拟数组

2007-07-30 23:54  晓风残月  阅读(...)  评论(...编辑  收藏

SQL Server 不支持数组参数,然而作为二维关系的“表”事实上不就是一个“数组”吗?
这里通过自定义函数分隔目标字符串,并作为表变量结果集返回。
自定义函数可以直接用在常见的 DML 语句中,如 SELECT。

对于某些多对多应用中,前端应用程序可以直接将的那边键连接成字符串,连同的那边的数据一次性传入存储过程,执行数据写入,不必在应用程序,遍历循环多次执行 Command。

使用示例

CREATE PROCEDURE dbo.usp_CreateProduct(
   
@ProductName varchar(100),
   
@UnitPrice money,
   
@CategoryIds varchar(4000),
   
@ProductID int output
AS

SET NOCOUNT ON

-- 写入产品数据
INSERT Product(ProductName, UnitPrice)
VALUE(
@ProductName@UnitPrice)
-- 获取产品ID
SELECT @ProductID = @@Identity

-- 写入产品-种类关系表
--
 基于 INSERT INTO  SELECT 语法
INSERT INTO ProductCategoryShip(ProductID, CategoryID)
SELECT @ProductID, Value FROM dbo.uf_Util_SplitStr(@CategoryID','-- 分隔产品种类ID

SET NOCOUNT OFF


自定义函数


/*
 * 字符串分割,结果作为表变量返回
 * 示例: 
 *    SELECT Value FROM dbo.uf_Util_SplitStr('1,2,3,4,5,6', DEFAULT)
 *  SELECT Value FROM dbo.uf_Util_SplitStr('A;B;C;D;E;F', ';')
*/

ALTER FUNCTION dbo.uf_Util_SplitStr(
    
@Src varchar(8000),
    
@Separator varchar(10= null
)
RETURNS @Result TABLE(VALUE varchar(100))
AS
BEGIN
    
IF @Separator IS NULL
        
SET @Separator = ','
        
    
DECLARE @i int
    
SET @Src = RTRIM(LTRIM(@Src))
    
SET @i = CHARINDEX(@Separator,@Src)
    
WHILE @i>=1
    
BEGIN
        
-- 插入新值
        INSERT @Result 
        
VALUES(LEFT(@Src@i-1))
        
        
SET @Src = SUBSTRING(@Src@i + 1LEN(@Src- @i)
        
SET @i = CHARINDEX(@Separator@Src)
    
END
   
    
IF @Src <> '' 
        
INSERT @Result 
        
VALUES(@Src)
   
   
RETURN
END