Create Table T ( ID int Identity ( . 1 , . 1 ), name VARCHAR ( 50 ), - trade name J int , - the number of storage C int , - the number of library jdate datetime - timespan ) INSERT INTO T (name, J, C, jdate) SELECT ' A ' , 100 , 0 , ' 2007-12-01 ' INSERT INTO t(name,j,c,jdate) select 'A',200,0,'2008-01-07' insert into t(name,j,c,jdate) select 'B',320,0,'2007-12-21' insert into t(name,j,c,jdate) select 'A',100,0,'2008-01-15' insert into t(name,j,c,jdate) select 'B',90,0,'2008-02-03' insert into t(name,j,c,jdate) select 'A',460,0,'2008-02-01' insert into t(name,j,c,jdate) select 'A',510,0,'2008-03-01' go create proc wsp @name varchar(50),--商品名称 @cost int --Sales AS - to obtain the stock of goods is enough DECLARE @spare a float - the remaining inventory SELECT @spare = SUM (J) - SUM (C) from T WHERE name = the @name IF ( @spare > = @cost ) the begin - of inventory items are processed according to the warehouse using the FIFO principle date Update T SET C = Case When ( SELECT @cost - ISNULL ( SUM (J), 0)+isnull(sum(c),0) from t where name=@name and jdate<=a.jdate and j!=c)>=0 then a.j else case when (select @cost-isnull(sum(j),0)+isnull(sum(c),0) from t where name=@name and jdate<a.jdate and j!=c)<0 then 0 else (select @cost-isnull(sum(j),0)+isnull(sum(c),0)+a.c from t where name=@name and jdate<a.jdate and j!=c) end end from t a where name= The @name and J ! = C End the else RAISERROR ( ' insufficient stock ' , 16 , . 1 ) return Go - Test: Exec WSP the @name = ' A ' , @cost = 110 SELECT * from T - drop Table T - - drop wsp proc / * (4 rows affected) the above mentioned id name JC jdate ----------- --------------------------- ----------------------- ----------- ----------- ----- ------------------ 2007-12-01 00 100 100 A. 1: 00: 00.000 2 2008-01-07 00 A 200 is 200 is: 00: 00.000 . 3 B 320. 0 2007-12-21 00: 00: 00.000 . 4 A 100 30 2008-01- 00 15: 00: 00.000 5 B 90 0 2008-02-03 00:00:00.000 . 6 A 460 0 2008-02-01 00: 00: 00.000 . 7 A 510 0 2008-03-01 00: 00: 00.000 (affected rows. 7) * / the CREATE TABLE #tmp (ID int the IDENTITY ( . 1 , . 1 ), a monovalent decimal ( 18 is , 2 ) the NOT NULL , into the library, the number of decimal ( 18 is , 0 ) the NOT NULL , has a number of decimal ( 18 is , 0 ) the NOT NULL ) INSERT INTO #tmp (Price , into the number of libraries, we have a number of) values ( 1.1 , 50 , 0 ) INSERT iNTO#tmp (number of monovalent, into the library, has a number of) values ( 1.3 , 30 , 0 ) INSERT INTO #tmp (number of monovalent, into the library, has a number of) values ( 1.4 , 60 , 0 ) INSERT INTO #tmp (Price , into the number of libraries, has a number of) values ( for 1.5 , 20 is , 0 ) SELECT * from #tmp DECLARE @t decimal ( 18 is , 0 ) - once the number of libraries , @temp decimal ( 18 is, 0 ) - number of a temporary library monovalent SELECT @t = 20 is Update #tmp SET @temp = Case When @t > feed quantity Library - has a number then enter the number of the library - has a number of - when the library when a number of balances greater than the number of the unit price, the number of the unit price of this library is the number of balance, this means that the number of stock priced all consumed. the else @t - has a number ofWhen the number is less than or equal to the carrying out of the library a number of unit price, then the number of the library is the actual number of outbound End , @t = @t - @temp , - minus time out for a temporary unit price number library have a number = @temp +- the number of new library of a number of previous libraries + where is the number <> feed quantity Library - a monovalent not participate in the library over a library calculated, i.e. the number zero on balance excluded SELECT * from #tmp SET @t = 40 Update #tmp SET @temp = Case When @t > feed quantity library - has a number then enter the number of the library - is the number ofHas a number of the else @t End , @t = @t - @temp , have a number = @temp + has a number WHERE<> Into the library number SELECT * from #tmp Go drop Table #tmp