我需要在一堆记录上运行存储过程。我现在的代码遍历存储在临时表中的记录。存储过程返回记录表。
我想知道如果有的话,我可以做些什么来避免迭代。
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
答案 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。应该不惜一切代价避免使用游标。