2016-07-23 67 views
0

@proc_name表变量中,我有存储过程名称,并且我使用动态SQL传递参数。我正在使用while循环遍历@proc_name中的所有行。我可以在这里使用CTE来提高性能吗?通过CTE迭代和执行

SELECT * 
FROM @proc_name 

WHILE (@count <= @max) 
BEGIN 
    SET @proc_exec = 'usp_Balance_' 
     +Replace((SELECT Description FROM @proc_name WHERE rn= @count),' ','')+' '+' '+'''' 
     +Replace((SELECT TellerID FROM @proc_name WHERE rn= @count),' ','')+''''+' ,'+'''' 
      [email protected]+''''+' , '+''''+cONvert(VARCHAR(100),@BusinessDate)+'''' 

    -- Update TDrawerSummary 
    PRINT (@proc_exec) 

    SET @count = @count + 1 
END 

谢谢。

+0

可能不能够提高这么多,但有点难以完全理解。你是否肯定需要'动态sql'来运行存储过程遍历每个recordin'@ proc_name'?存储过程中实际发生了什么? – sgeddes

+1

CTE(在SQL Server中)不会提高性能。他们确实使查询更容易理解,不过。 –

+0

@GordonLinoff - 我已经让他们提高了性能 - 从一个大表中选择一小组字段,这些字段是唯一的,并且包含在cte的索引中,然后返回到表中以获得其余列。 – Hogan

回答

2

要下手,如下图所示的光标代替WHILE循环:

DECLARE c CURSOR FOR 
    SELECT 'usp_Balance_' 
      +Replace(Description,' ','')+' '+' '+'''' 
      +Replace(TellerID,' ','')+''''+' ,'+'''' 
       [email protected]+''''+' , '+''''+cONvert(VARCHAR(100),@BusinessDate)+'''' 
    FROM @proc_name 
    ORDER BY rn 
OPEN c 
FETCH c INTO @proc_exec 
WHILE @@FETCH_STATUS=0 
    BEGIN 
     -- Update TDrawerSummary 
     PRINT @proc_exec 
     FETCH c INTO @proc_exec 
    END 
CLOSE c 
DEALLOCATE c 

在某些情况下,你可以使用一个CTE来转换程序代码到一个查询。这可以提高性能。如果您可以共享构建@proc_name的代码,我可以检查是否有可能。

在游标内部,您应该考虑采取一些措施来帮助您追踪错误。在当前的代码中,很难知道哪个迭代发生了错误。一个简单的例子如下所示:

BEGIN TRY 
     -- Update TDrawerSummary 
     PRINT @proc_exec 
    END TRY 
    BEGIN CATCH 
     PRINT 'Failed executing '+COALESCE(@proc_exec,'(null)')+': '+ERROR_MESSAGE() 
    END CATCH 
+0

我的建议非常好的代码示例。好答案! – Hogan