仓库移动建议(合并两个表并填写)- 仅通过 SQL 光标?
Warehouse movements proposal (Combine two tables and fullfill) - Only by SQL Cursor?
我将每个仓库公司的所有产品分成两个数据库 tables(给予者和接受者),并使用某种逻辑为每条记录排序,以按其优先级进行处理。
我最终得到了两个 table。第一个 table 包含付出者,第二个 table 包含接受者
我正在努力创造一个结果,该结果将连续提出从给予者到接受者所需的动作。这只能由 SQL Cursor 处理吗?我可以在不使用 Cursor 的情况下得到结果吗,因为它对我来说很复杂?任何帮助将不胜感激..
捐赠者TABLE
Product
QtyAllowedToGive
Warehouse_ID_Giver
Rank
A
30
100
1
A
30
101
2
A
10
102
3
B
10
200
4
B
6
201
9
D
5
300
10
接受者TABLE
Product
QtyAllowedToTake
Warehouse_ID_Taker
Rank
A
50
200
1
A
5
203
2
A
11
202
3
B
16
202
4
B
3
202
5
C
10
300
6
需要结果
Product
QtyToMove
Warehouse_ID_Giver
Warehouse_ID_Taker
A
30
100
200
A
20
101
200
A
5
101
203
A
5
101
202
A
6
102
202
B
10
200
202
B
9
201
202
也许是这样的?
drop table #Givers
select *
into #Givers
from (values
('A', 30, 100, 1)
,('A', 30, 101, 2)
,('A', 10, 102, 3)
,('B', 10, 200, 4)
,('B', 6, 201, 9)
,('D', 5, 300, 10)
) T(Product,QtyAllowedToGive, Warehouse_ID_Giver, [Rank])
drop table #Takers
select *
into #Takers
from (values
('A', 50, 200, 1)
,('A', 5, 203, 2)
,('A', 11, 202, 3)
,('B', 16, 202, 4)
,('B', 3, 202, 5)
,('C', 10, 300, 6)
) T(Product, QtyAllowedToTake, Warehouse_ID_Taker, [Rank])
declare TakerCursor cursor fast_forward for
select Product, QtyAllowedToTake, WareHouse_ID_Taker from #Takers order by Product, [Rank];
declare GiverCursor cursor fast_forward for
select Product, QtyAllowedToGive, WareHouse_ID_Giver from #Givers order by Product, [Rank];
declare @TakerProduct char(1)='', @QtyAllowedToTake integer=0, @WareHouseID_Taker integer=0;
declare @GiverProduct char(1)='', @QtyAllowedToGive integer=0, @WareHouseID_Giver integer=0;
open TakerCursor
open GiverCursor
fetch next from TakerCursor into @TakerProduct, @QtyAllowedToTake, @WareHouseID_Taker;
if @@FETCH_STATUS<>0 return -- no more Takers
fetch next from GiverCursor into @GiverProduct, @QtyAllowedToGive, @WareHouseID_Giver;
if @@FETCH_STATUS<>0 return -- no more Givers
declare @QtyToMove integer=0
declare @Output table (Product char(1), Warehouse_ID_Giver integer, WareHouse_ID_Taker integer, Qty integer);
while 1=1 begin
if @TakerProduct=@GiverProduct begin
if @QtyAllowedToTake<=@QtyAllowedToGive
set @QtyToMove=@QtyAllowedToTake
else
set @QtyToMove=@QtyAllowedToGive
insert into @Output (Product, Warehouse_ID_Giver, WareHouse_ID_Taker, Qty)
Select Product=@TakerProduct
--, QtyAllowedToTake=@QtyAllowedToTake, QtyAllowedToGive=@QtyAllowedToGive,
, Giver=@WareHouseID_Giver
, Taker=@WareHouseID_Taker
, Qty=@QtyToMove;
set @QtyAllowedToTake=@QtyAllowedToTake-@QtyToMove
set @QtyAllowedToGive=@QtyAllowedToGive-@QtyToMove
if @QtyAllowedToGive=0 begin
fetch next from GiverCursor into @GiverProduct, @QtyAllowedToGive, @WareHouseID_Giver;
if @@FETCH_STATUS<>0 break -- no more Givers
end
if @QtyAllowedToTake=0 begin
fetch next from TakerCursor into @TakerProduct, @QtyAllowedToTake, @WareHouseID_Taker;
if @@FETCH_STATUS<>0 break -- no more Takers
end
end else
if @TakerProduct>@GiverProduct begin
fetch next from GiverCursor into @GiverProduct, @QtyAllowedToGive, @WareHouseID_Giver;
if @@FETCH_STATUS<>0 break -- no more Givers
end else
if @TakerProduct<@GiverProduct begin
fetch next from TakerCursor into @TakerProduct, @QtyAllowedToTake, @WareHouseID_Taker;
if @@FETCH_STATUS<>0 break -- no more Takers
end
end
close GiverCursor
close TakerCursor
deallocate GiverCursor
deallocate TakerCursor
select * from @Output
没有错误检查或整理或优化。
我将每个仓库公司的所有产品分成两个数据库 tables(给予者和接受者),并使用某种逻辑为每条记录排序,以按其优先级进行处理。 我最终得到了两个 table。第一个 table 包含付出者,第二个 table 包含接受者
我正在努力创造一个结果,该结果将连续提出从给予者到接受者所需的动作。这只能由 SQL Cursor 处理吗?我可以在不使用 Cursor 的情况下得到结果吗,因为它对我来说很复杂?任何帮助将不胜感激..
捐赠者TABLE
Product | QtyAllowedToGive | Warehouse_ID_Giver | Rank |
---|---|---|---|
A | 30 | 100 | 1 |
A | 30 | 101 | 2 |
A | 10 | 102 | 3 |
B | 10 | 200 | 4 |
B | 6 | 201 | 9 |
D | 5 | 300 | 10 |
接受者TABLE
Product | QtyAllowedToTake | Warehouse_ID_Taker | Rank |
---|---|---|---|
A | 50 | 200 | 1 |
A | 5 | 203 | 2 |
A | 11 | 202 | 3 |
B | 16 | 202 | 4 |
B | 3 | 202 | 5 |
C | 10 | 300 | 6 |
需要结果
Product | QtyToMove | Warehouse_ID_Giver | Warehouse_ID_Taker |
---|---|---|---|
A | 30 | 100 | 200 |
A | 20 | 101 | 200 |
A | 5 | 101 | 203 |
A | 5 | 101 | 202 |
A | 6 | 102 | 202 |
B | 10 | 200 | 202 |
B | 9 | 201 | 202 |
也许是这样的?
drop table #Givers
select *
into #Givers
from (values
('A', 30, 100, 1)
,('A', 30, 101, 2)
,('A', 10, 102, 3)
,('B', 10, 200, 4)
,('B', 6, 201, 9)
,('D', 5, 300, 10)
) T(Product,QtyAllowedToGive, Warehouse_ID_Giver, [Rank])
drop table #Takers
select *
into #Takers
from (values
('A', 50, 200, 1)
,('A', 5, 203, 2)
,('A', 11, 202, 3)
,('B', 16, 202, 4)
,('B', 3, 202, 5)
,('C', 10, 300, 6)
) T(Product, QtyAllowedToTake, Warehouse_ID_Taker, [Rank])
declare TakerCursor cursor fast_forward for
select Product, QtyAllowedToTake, WareHouse_ID_Taker from #Takers order by Product, [Rank];
declare GiverCursor cursor fast_forward for
select Product, QtyAllowedToGive, WareHouse_ID_Giver from #Givers order by Product, [Rank];
declare @TakerProduct char(1)='', @QtyAllowedToTake integer=0, @WareHouseID_Taker integer=0;
declare @GiverProduct char(1)='', @QtyAllowedToGive integer=0, @WareHouseID_Giver integer=0;
open TakerCursor
open GiverCursor
fetch next from TakerCursor into @TakerProduct, @QtyAllowedToTake, @WareHouseID_Taker;
if @@FETCH_STATUS<>0 return -- no more Takers
fetch next from GiverCursor into @GiverProduct, @QtyAllowedToGive, @WareHouseID_Giver;
if @@FETCH_STATUS<>0 return -- no more Givers
declare @QtyToMove integer=0
declare @Output table (Product char(1), Warehouse_ID_Giver integer, WareHouse_ID_Taker integer, Qty integer);
while 1=1 begin
if @TakerProduct=@GiverProduct begin
if @QtyAllowedToTake<=@QtyAllowedToGive
set @QtyToMove=@QtyAllowedToTake
else
set @QtyToMove=@QtyAllowedToGive
insert into @Output (Product, Warehouse_ID_Giver, WareHouse_ID_Taker, Qty)
Select Product=@TakerProduct
--, QtyAllowedToTake=@QtyAllowedToTake, QtyAllowedToGive=@QtyAllowedToGive,
, Giver=@WareHouseID_Giver
, Taker=@WareHouseID_Taker
, Qty=@QtyToMove;
set @QtyAllowedToTake=@QtyAllowedToTake-@QtyToMove
set @QtyAllowedToGive=@QtyAllowedToGive-@QtyToMove
if @QtyAllowedToGive=0 begin
fetch next from GiverCursor into @GiverProduct, @QtyAllowedToGive, @WareHouseID_Giver;
if @@FETCH_STATUS<>0 break -- no more Givers
end
if @QtyAllowedToTake=0 begin
fetch next from TakerCursor into @TakerProduct, @QtyAllowedToTake, @WareHouseID_Taker;
if @@FETCH_STATUS<>0 break -- no more Takers
end
end else
if @TakerProduct>@GiverProduct begin
fetch next from GiverCursor into @GiverProduct, @QtyAllowedToGive, @WareHouseID_Giver;
if @@FETCH_STATUS<>0 break -- no more Givers
end else
if @TakerProduct<@GiverProduct begin
fetch next from TakerCursor into @TakerProduct, @QtyAllowedToTake, @WareHouseID_Taker;
if @@FETCH_STATUS<>0 break -- no more Takers
end
end
close GiverCursor
close TakerCursor
deallocate GiverCursor
deallocate TakerCursor
select * from @Output
没有错误检查或整理或优化。