【问题标题】:I need to run a stored procedure on multiple records我需要对多条记录运行存储过程
【发布时间】:2010-05-28 14:06:31
【问题描述】:

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

我想知道我可以做些什么来避免迭代。

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 

【问题讨论】:

    标签: sql stored-procedures cursor


    【解决方案1】:

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

    一种可能的替代方法是使用 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)
    

    (不清楚您对该程序的所有输入来自哪里。)

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

    【讨论】:

      【解决方案2】:

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

      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。应该不惜一切代价避免使用光标。

      【讨论】:

      • 是的,这就是我开始的地方。我想知道是否有另一种方法可以作为大规模存储过程调用而不是迭代。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多