循环遍历值并在每个完成后更新

时间:2013-07-30 15:31:21

标签: sql-server sql-server-2005 cursor

我有以下代码,我需要运行350个位置,需要一个小时才能完成5个位置,所以我一次运行5个,其中location_code位于('0001','0002','0003',' 0005','0006')我想创建一个临时表,其中包含2列一个location_id,另一个已完成并循环遍历location_id列上的每个值,然后在完成后使用日期和时间戳更新已完成的列,并在每个值之后提交。这样我就可以让它运行,如果我需要杀死它,我可以看到最后完成的location_id,并知道从哪里重新启动过程或更好,但它检查完成列中的vaule,如果存在,请转到下一个.....

--Collecting all records containing remnant cost. You will need to specify the location     number(s). In the example below we're using location 0035
select sku_id, ib.location_id, price_status_id, inventory_status_id, sum(transaction_units) as units, sum(transaction_cost) as cost, 
sum(transaction_valuation_retail) as val_retail, sum(transaction_selling_retail) as sell_retail
into #remnant_cost 
from ib_inventory ib
inner join location l on l.location_id = ib.location_id
where location_code in ('0001', '0002', '0003', '0005', '0006')
group by sku_id, ib.location_id, price_status_id, inventory_status_id
having sum(transaction_units) = 0
and sum(transaction_cost) <> 0


--Verify the total remnant cost.
select location_id, sum(units) as units, sum(cost) as cost, sum(val_retail) as val_retail, sum(sell_retail) as sell_retail
from #remnant_cost
group by location_id

select *
from #remnant_cost

----------------------------------------------------Run above this line first and gather results--------------------------------


--inserting into a temp table the cost negation using transaction_type_code 500 (Actual shrink) before inserting into ib_inventory
--corrected query adding transaction date as column heading (Marshall)
select
sku_id, location_id, price_status_id, convert(smalldatetime,convert(varchar(50),getdate(),101)) as transaction_date, 500 as transaction_type_code, inventory_status_id, NULL as other_location_id, 
NULL as transaction_reason_id, 999999 as document_number, 0 as transaction_units, cost * -1 as transaction_cost, 0 as transaction_valuation_retail, 
0 as transaction_selling_retail,NULL as price_change_type, NULL as units_affected
into #rem_fix
from #remnant_cost


--Validating to make sure cost will have the exact opposite to negate.
select location_id, sum(transaction_units) as units, sum(transaction_cost) as cost, sum(transaction_valuation_retail) as val_retail, 
sum(transaction_selling_retail) as sell_retail
from #rem_fix
group by location_id


BEGIN TRAN

EXEC inventory_update_$sp 'SELECT      sku_id,location_id,price_status_id,transaction_date,transaction_type_code,inventory_status_id,other_location_id,
transaction_reason_id,document_number,transaction_units,transaction_cost,transaction_valuation_retail,transaction_selling_retail,price_change_type,
units_affected FROM #rem_fix'

COMMIT

1 个答案:

答案 0 :(得分:0)

对您的架构做出一些假设:

-- A working table to track progress that will stick around.
create table dbo.Location_Codes
  ( Location_Code VarChar(4), Started DateTime NULL, Completed DateTime NULL );

然后以这种方式分解工作:

if not exists ( select 42 from dbo.Location_Codes where Completed is NULL )
  begin
  -- All of the locations have been processed (or this is the first time through).
  delete from dbo.Location_Codes;
  -- Get all of the location codes.
  insert into dbo.Location_Codes
    select Location_Code, NULL, NULL
      from Location;
  end

-- Temporary table to make things easier.
declare @Pass_Location_Codes as Table ( Location_Code VarChar(4) );

-- Loop until all locations have been processed.
while exists ( select 42 from dbo.Location_Codes where Completed is NULL )
  begin
  -- Get the next five locations for which processing has not completed.
  delete from @Pass_Location_Codes;
  insert into @Pass_Location_Codes
    select top 5 Location_Code
      from dbo.Location_Codes
      where Completed is NULL
      order by Location_Code;
  -- Record the start date/time.
  update dbo.Location_Codes
    set Started = GetDate()
    where Location_Code in ( select Location_Code from @Pass_Location_Codes );

  -- Run the big query.
  select ...
    where Location_Code in ( select Location_Code from @Pass_Location_Codes )
    ...

  -- Record the completion date/time.
  update dbo.Location_Codes
    set Completed = GetDate()
    where Location_Code in ( select Location_Code from @Pass_Location_Codes );
  end