Мне нужно запустить хранимую процедуру для нескольких записей - PullRequest
2 голосов
/ 28 мая 2010

Мне нужно запустить хранимую процедуру для нескольких записей. Код, который я сейчас имею, перебирает записи, хранящиеся во временной таблице. Хранимая процедура возвращает таблицу записей.

Мне было интересно, что я могу сделать, чтобы избежать итерации, если что-нибудь.

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 ]

2 голосов
/ 28 мая 2010

Один из способов избежать такого рода итераций - это проанализировать код в хранимой процедуре и пересмотреть его так, чтобы вместо обработки для одного набора входов за раз он обрабатывал все наборы входов за раз.Довольно часто это невозможно, поэтому итерационные циклы не так уж редки.

Возможной альтернативой является использование функциональности 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)

(Было не ясно, где все ваши входные данные дляПроцедура исходила из.)

Обратите внимание, что вы все еще перебираете вызовы функции, но теперь она "упакована" в один запрос.

0 голосов
/ 28 мая 2010

Я думаю, вы на правильном пути. у вас может быть временная таблица со столбцом идентификаторов

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. КУРСОРОВ следует избегать любой ценой.

...