我们要迁移到的ERP系统要求GL的5,000行以下的csv文件。每个文件中的借方和贷方事务必须平衡为零。有多个共享相同交易ID的借方和贷方交易行。
接下来使用偏移量和提取次数,我一次可以提取5000行,但是贷方和借方不平衡。
数据示例:
TranID Credit Debit Balance Account#
1 250 0 250 ABC
1 0 250 0 DEF
2 0 100 -100 GHI
2 50 0 -50 JKL
2 50 0 0 MNO
declare @batchsize INT = 5000,
@loopcount INT = 0;
while (@loopcount*@batchsize < (select count(*) from [Apps2].[dbo].[GLTrans]))
begin
SELECT * FROM [Apps2].[dbo].[GLTrans]
ORDER BY tranID
offset (@batchsize * @loopcount) rows
fetch next (@batchsize) rows only
set @loopcount= @loopcount + 1
end
答案 0 :(得分:3)
一个简单的解决方案是预处理所有交易并分配批次编号(对于每个CSV文件)。临时表存储了每个TranID的行数。
假定每个TranID的借方和贷方都将保持平衡。
之后,您可以基于临时表生成CSV。
-- create the temp table
create table #trans
(
TranID int identity,
Cnt int,
Batch int
)
-- populate the temp table
insert into #trans (TranID, Cnt)
select TranID, Cnt = count(*)
from [Apps2].[dbo].[GLTrans]
group by TranID
declare @batchsize int = 5000,
@batch int = 1
while exists (select * from #trans where Batch is null)
begin
update t
set Batch = @batch
from
(
select *, cumm = sum(Cnt) over (order by TranID)
from #trans
where Batch is null
) t
where cumm <= @batchsize
select @batch = @batch + 1
end
-- Verify
select *, sum(Cnt) over (partition by Batch order by TranID)
from #trans
order by TranID
答案 1 :(得分:3)
使用表变量遍历数据。有点喜欢在Oracle中使用游标...
如果我正确理解了样本数据,并且假设每个transID的nets都设置为0,那么您可以更改循环逻辑,使其更像do ......,而like this example here则在其中获取下一个交易集并决定是否将批次保持在5k以下。 假设每个交易ID设置的净额为$ 0,这应该涵盖填充一批5000行或更少的净额为$ 0的行
Declare @batchCursor TABLE (
TransID INT,
Credit INT, -- chose int for expediency
Debit INT,
Balance INT,
AccountNo Varchar(4)
),
@batchsize INT = 5000,
@rowCount INT = 0,
@transID INT = 1,
@transSize INT = 0;
while (@rowcount <= 5000)
BEGIN
INSERT INTO @batchCursor
SELECT * FROM [Apps2].[dbo].[GLTrans] -- you might need to enumerate all your column names
WHERE TransID = @transID;
SELECT @transSize = COUNT(*) FROM @batchCursor where TransID = @transID);
IF(@transSize > 0)
BEGIN
IF (@transSize + @rowCount < @batchSize)
BEGIN
Set @rowCount += transSize;
Set @transID += 1;
END;
END;
ELSE Set @transID += 1;
IF((Select count(*) FROM [Apps2].[dbo].[GLTrans] WHERE TransID = @transID) + @rowCount > @batch)
BREAK;
END;