1

设想 :

我需要从存储过程返回单个结果集,但是我有一个可以传递未知多个值的数组参数,并且对于传递的每个值,我需要有一个单独的获取数据的逻辑。

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 客户端面对服务和性能是一个巨大的决策因素,而且类型不仅限于三种类型,还可以是更多类型。

如果进行单个 DB 调用的效率是 cursor 循环遍历类型并合并它们的唯一可能方法 - 示例将不胜感激。

4

1 回答 1

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

但通常我更喜欢尽可能使用表值参数

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
于 2013-08-13T21:59:47.080 回答