【发布时间】:2013-12-09 17:57:44
【问题描述】:
我有一个接受 A、B、C...等字符串的存储过程。我想拆分字符串并将每个字母作为一条记录插入到表中。结果应该是:
col1 col2
1 A
2 B
3 C
我可以使用游标,但是如果我从我的网页调用这个存储过程,游标会有点慢。有没有更好的解决办法?
【问题讨论】:
我有一个接受 A、B、C...等字符串的存储过程。我想拆分字符串并将每个字母作为一条记录插入到表中。结果应该是:
col1 col2
1 A
2 B
3 C
我可以使用游标,但是如果我从我的网页调用这个存储过程,游标会有点慢。有没有更好的解决办法?
【问题讨论】:
不要传递逗号分隔的字符串,而是传递一个表值参数。首先,在你的数据库中创建一个表类型:
CREATE TYPE dbo.Strings AS TABLE(String NVARCHAR(32));
然后你的存储过程:
CREATE PROCEDURE dbo.InsertStrings
@Strings dbo.Strings READONLY
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.Table(Col2) -- assuming col1 is an IDENTITY column?
SELECT String FROM @Strings;
END
GO
然后在您的 C# 代码或其他代码中,您只需将 DataTable 作为 Structured 参数传递。 Example here 和 background here。
如果您真的不想这样做,因为它太难或其他什么,那么您可以使用效率低得多的字符串拆分功能,例如
CREATE FUNCTION [dbo].[SplitString]
(
@List NVARCHAR(MAX),
@Delim VARCHAR(255)
)
RETURNS TABLE
AS
RETURN ( SELECT [Value] FROM
(
SELECT
[Value] = LTRIM(RTRIM(SUBSTRING(@List, [Number],
CHARINDEX(@Delim, @List + @Delim, [Number]) - [Number])))
FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
FROM sys.all_objects) AS x
WHERE Number <= LEN(@List)
AND SUBSTRING(@Delim + @List, [Number], LEN(@Delim)) = @Delim
) AS y
);
那么你的程序是:
CREATE PROCEDURE dbo.InsertStrings
@Strings NVARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.Table(Col2) -- assuming col1 is an IDENTITY column?
SELECT [Value] FROM dbo.SplitString(@Strings, ',');
END
GO
【讨论】: