场景:
我需要从存储过程返回一个结果集,但是我有一个数组参数可以传递未知的多个值,对于传递的每个值,我需要有一个单独的逻辑来获取数据。
SP:
PROCEDURE [dbo].[GetRecommendations]
(
@RecommendationTypesCSV varchar(4000) -- This could have Type1,Type2,Type3...
}
BEGIN
....
END
一旦我转换了这个逗号分隔类型,我需要遍历每个类型并执行一些逻辑,但是当我继续执行所需的逻辑时,我收集数据,最后我必须做一个Union All并返回所有结果作为一个带有新类型的大结果集,并为其分配相关的类型信息。
If (type1)
BEGIN
-- Do Something
END
If (type2)
BEGIN
-- Do Something
END
If (type3)
BEGIN
-- Do Something
END
合并所有三个并返回结果:
Column1 Column2 Column3
----------- ----------- -------
102570 10027 type1
102569 20011 type1
102568 20011 type1
102564 20011 type2
102563 20011 type2
102562 20074 type3
102561 20011 type3
102560 20011 type3
102559 10059 type3
102558 20011 type3
问题:
我需要决定是否应该单独调用DB(SQL)或每种类型的多个调用,然后将类型合并到代码(C#.Net)中,请记住这是面向服务和性能的WCF客户端是一个巨大的决策因素,而且类型不仅限于3种类型,而且可能是更多类型。
如果有效地进行单个数据库调用是光标唯一可能的循环类型并合并它们的方法 - 示例将不胜感激。
答案 0 :(得分:1)
我们有一些使用这种技术的遗留系统。看起来有点像这样:
CREATE PROCEDURE [dbo].[GetRecommendations]
( @RecommendationTypesCSV NVARCHAR(4000) )
AS
BEGIN
DECLARE @StartPos INT
DECLARE @EndPos INT
-- split recommendation types list into table
DECLARE @RecommendationTypes (
[Type] NVARCHAR(40)
)
WHILE LEN(@RecommendationTypesCSV) > 0
BEGIN
SET @StartPos = 1
SET @EndPos = CHARINDEX(',', @RecommendationTypesCSV) - 1
IF @EndPos <= 0 SET @EndPos = LEN(@RecommendationTypesCSV)
INSERT INTO @RecommendationTypes VALUES (SUBSTRING(@RecommendationTypesCSV, @StartPos, @EndPos))
SET @RecommendationTypesCSV = SUBSTRING(@RecommendationTypesCSV, @EndPos + 2, LEN(@RecommendationTypesCSV))
END
If EXISTS (SELECT * FROM @RecommendationTypes WHERE [Type] = 'type1')
BEGIN
-- Do Something
END
...
END
GO
但通常我更喜欢尽可能使用table valued parameters。
CREATE TYPE [dbo].[RecommendationTypes] AS TABLE
( Type VARCHAR(40) );
GO
CREATE PROCEDURE [dbo].[GetRecommendations]
( @RecommendationTypesCSV [dbo].[RecommendationTypes] READONLY )
AS
BEGIN
If EXISTS (SELECT * FROM @RecommendationTypes WHERE [Type] = 'type1')
BEGIN
-- Do Something
END
...
END
GO
唯一的问题是调用存储过程更加困难。
DECLARE @RecommendationTypesCSV [dbo].[RecommendationTypes];
INSERT @RecommendationTypesCSV VALUES ( 'type1' ), ( 'type2' );
EXEC [dbo].[GetRecommendations] @RecommendationTypesCSV