我可以避免在这里使用游标吗?

时间:2011-03-01 15:48:10

标签: sql sql-server tsql sql-server-2008

所以这是起点

CREATE TABLE #Data (  
  ID      INT IDENTITY(1,1),  
  MyData  VARCHAR(200)  
)   

INSERT INTO #Data (Data) VALUES ('Test123, Test678')  
INSERT INTO #Data (Data) VALUES ( 'abcd, efgh, mnop')  

我想解析来自MyData列的逗号分隔数据并将其关联回相关ID。所以最终结果将是

ID  ParsedData
--------------
1  Test123  
1  Test678  
2  abcd  
2  efgh  
2  mnop  

我可以通过游标来做,但想避免它。有没有更好的方法来编写查询?

4 个答案:

答案 0 :(得分:2)

这样做的最佳方式是much controversy的主题,还取决于字符串的长度,分隔符的频率,并发使用,并行计划的适用性,结果是否将用于{ {1}}操作...

Erland Sommarskog does some performance tests here

我已经链接到下面使用数字表的Adam Machanic的TSQL分割函数。上面的链接中有更多的负载。

1. Create a numbers table

2. Create a split function

JOIN

答案 1 :(得分:0)

您是否愿意更改proc的输入?如果是这样,您可以使用自定义用户定义的表类型;

CREATE TYPE [dbo].[SomeInfo] AS TABLE(
[Id] [int] NOT NULL, 
[SomeValue] [int] NOT NULL )

定义您的存储过程;

CREATE PROCEDURE [dbo].[AddSomeStuff]
    @theStuff [SomeInfo] READONLY
AS
BEGIN
    INSERT INTO SOMETABLE ([...columns...])
    SELECT [...columns...] from @theStuff
END

如果你需要从.net调用它,你需要创建一个与模式匹配的数据表(下面称为表),并调用存储过程;

var cmd = new SqlCommand("AddSomeStuff", sqlConn) {CommandType = CommandType.StoredProcedure};

var param = new SqlParameter("@theStuff", SqlDbType.Structured) {Value = table};
cmd.Parameters.Add(param);

cmd.ExecuteNonQuery();

答案 2 :(得分:0)

在SQL Server 2005及更高版本中,您可以避免使用游标 - 但将此逗号分隔的字符串拆分为有用的字符串将始终是一个迭代过程。

有几种方法和存储函数可以分割字符串并返回值表。使用one of those function,您可以编写如下内容:

SELECT 
d.ID, Value
FROM 
#Data AS d
CROSS APPLY
[dbo].[SplitDelimited](d.MyData, ',') 

你会得到类似的输出:

ID   Value
 1   Test123
 1   Test678
 2   abcd
 2   efgh
 2   mnop

答案 3 :(得分:0)