我需要在多个记录上运行存储过程

时间:2010-05-28 14:06:31

标签: sql stored-procedures cursor

我需要在一堆记录上运行存储过程。我现在的代码遍历存储在临时表中的记录。存储过程返回记录表。

我想知道如果有的话,我可以做些什么来避免迭代。

set @counter = 1     
set @empnum = null     
set @lname = null     
set @fname = null     
-- get all punches for employees     
while exists(select emp_num, lname, fname from #tt_employees where id = @counter)     
begin     
    set @empnum = 0     
    select @empnum = emp_num, @lname = lname , @fname= fname from #tt_employees where id = @counter     

   INSERT @tt_hrs     
   exec PCT_GetEmpTimeSp 
      empnum    
     ,@d_start_dt     
     ,@d_end_dt     
     ,@pMode = 0    
     ,@pLunchMode = 3    
     ,@pShowdetail = 0    
     ,@pGetAll = 1          

  set @counter = @counter + 1     
end 

2 个答案:

答案 0 :(得分:2)

避免这种迭代的一种方法是分析存储过程中的代码并进行修改,以便不是一次处理一组输入,而是一次处理所有输入集。通常情况下,这是不可能的,这就是为什么迭代循环不是那么罕见的原因。

可能的替代方法是使用APPLY功能(交叉应用,外部应用)。为此,您将该过程重写为表类型函数之一,并将该函数用于查询,如下所示:

INSERT @tt_hrs      
 select [columnList]
 from #tt_employees
  cross apply dbo.PCT_GetEmpTimeFunc(emp_num, @d_start_dt, @d_end_dt, 0, 3, 0, 1)

(目前尚不清楚程序的所有输入来自何处。)

请注意,您仍在迭代对函数的调用,但现在它已“打包”到一个查询中。

答案 1 :(得分:0)

我认为你走在正确的轨道上。 你可以拥有一个带有标识列的临时表

CREATE TABLE #A (ID INT IDENTITY(1,1) NOT NULL, Name VARCHAR(50))

将记录插入此临时表后,查找表中的记录总数。

DECLARE @TableLength INTEGER
SELECT @TableLength  = MAX(ID) FROM #A

DECLARE @Index INT
SET @Index = 1

WHILE (@Index <=@TableLength)
BEGIN

-- DO your work here 

SET @Index = @Index + 1


END

与您已经提出的相似。 迭代记录的替代方法是使用CURSOR。应该不惜一切代价避免使用游标。

相关问题