Salakhetdinov Shamil
mcp2004 at mail.ru
Sun May 27 01:43:37 CDT 2012
Hi Paul -- It's definitely a bad design case as noted here by Arthur and others but it looks like it can be handled without cursors at all: -- -- Step ONE - Create sample tables -- IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[POAllocation]') AND type in (N'U')) DROP TABLE [dbo].[POAllocation] GO IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[PODetail]') AND type in (N'U')) DROP TABLE [dbo].[PODetail] GO CREATE TABLE POAllocation (PONumber int, Allocated money) CREATE TABLE PODetail (PONumber int, Amount money, IsAllocated bit, RowID int IDENTITY(1,1) NOT NULL) go -- allocation is greater than details totals INSERT POAllocation VALUES (123456, 141.00) INSERT PODetail VALUES (123456, 50.00, 0) INSERT PODetail VALUES (123456, 20.00, 0) INSERT PODetail VALUES (123456, 76.00, 0) GO -- allocation is less than details totals INSERT POAllocation VALUES (789012, 253.00) INSERT PODetail VALUES (789012, 99.00, 0) INSERT PODetail VALUES (789012, 101.00, 0) GO -- allocation is equal to details totals INSERT POAllocation VALUES (345678, 101.00) INSERT PODetail VALUES (345678, 9.00, 0) INSERT PODetail VALUES (345678, 31.00, 0) INSERT PODetail VALUES (345678, 20.00, 0) INSERT PODetail VALUES (345678, 30.00, 0) INSERT PODetail VALUES (345678, 11.00, 0) GO -- allocation without details INSERT POAllocation VALUES (567890, 99.00) GO -- zero allocation, zero details INSERT POAllocation VALUES (901234, 0.00) GO select * from POAllocation select * from PODetail -- -- STEP TWO - Test -- DECLARE @AllocationTbl TABLE ( RowId int, PONumber int, Amount money, RunningTotal money, Allocated money, IsAllocated bit ) DECLARE @RunningTotal money DECLARE @PONumber int SET @RunningTotal = 0 set @PONumber = null INSERT INTO @AllocationTbl SELECT RowId, a.PONumber, Amount, null, a.Allocated, null FROM PODetail d, POAllocation a where d.PONumber = a.PONumber ORDER BY a.PONumber, RowId UPDATE @AllocationTbl SET @RunningTotal = RunningTotal = case when (@PONumber = PONumber) then @RunningTotal + Amount else Amount end, @PONumber = PONumber, IsAllocated = case when (@RunningTotal <= Allocated) then 1 else 0 end FROM @AllocationTbl -- SELECT * FROM @AllocationTbl update PODetail set IsAllocated = a.IsAllocated from PODetail d, @AllocationTbl a where d.PONumber = a.PONumber and d.RowId = a.RowId -- select * from POAllocation select * from PODetail -- -- Result -- -- 123456 50.00 1 1 -- 123456 20.00 1 2 -- 123456 76.00 0 3 -- 789012 99.00 1 4 -- 789012 101.00 1 5 -- 345678 9.00 1 6 -- 345678 31.00 1 7 -- 345678 20.00 1 8 -- 345678 30.00 1 9 -- 345678 11.00 1 10 Enjoy! :)(But verify that it will work for your case - tested here with MS SQL 2008 R2 Express Edition) Credit: Calculating Running Totals in SQL Server 2005, The optimal solution? http://geekswithblogs.net/Rhames/archive/2008/10/28/calculating-running-totals-in-sql-server-2005---the-optimal.aspx Thank you. -- Shamil Fri, 25 May 2012 13:35:21 +0100 от Paul Hartland <paul.hartland at googlemail.com>: > To all, > > I will try and explain the problem as best as I possibly can, for this > purpose lets say I have two tables, PODetail which holds detail records for > a purchase order, and a table containing a value which we have currently > allocated to a single purchase order number POAllocation > > PODetail > PoNumber Amount Allocated RowID > 123456 50.00 0 1 > 123456 20.00 0 2 > 123456 76.00 0 3 > > POAllocation > PONumber Allocated > 123456 141.00 > > What I need to do is update the Allocated field in PODetail with a value, > the way I want to do this is get the PO number and allocated amount from > POAllocation and then loop through the PODetail records updating the > Allocated field, so I would come to record (rowid) 1 if the allocated > amount is less than 50.00 then update the allocated field with that value, > if the allocated amount is great than 50.00 then update the allocated field > to 50.00, take 50.00 away from 141.00 to get 91.00 then report the process > for record (rowid) 2. > > I am thinking/in middle of writing a cursor inside a cursor, anyone else > any better ideas on how to do this. > > Thanks in advance for any help. > > > -- > Paul Hartland > paul.hartland at googlemail.com > --