2012-07-25 51 views
2

条件这是我的表结构:更新一行在SQL Server 2008

CREATE table Credit(id integer, organisationid int, availableCredit int) 

INSERT INTO Credit VALUES (1, 1, 1000) 
INSERT INTO Credit VALUES (2, 1, 100) 
INSERT INTO Credit VALUES (3, 2, 600) 
INSERT INTO Credit VALUES (4, 2, 400) 

我不得不减少可用信用列值,我有量1050和我在一起。我需要从组织ID = 1的信用表中减少1050.在这里组织ID 1总共有1100个可用信用。条件是首先应该先更新插入的信用额度,然后再更新(FIFO模型),同时更新应该只发生在organisationId = 1。

我们如何使用单个或多个更新语句更新?

有什么建议吗?

回答

2

不幸的是,这是一个相当混乱的事情在T-SQL做减少 “ID 2” availableCredit - 你会需要类似循环(光标或WHILE语句)。

在这里使用此代码,我可以让它运行 - 它不漂亮,但它的工作原理。

-- you want to reduce the total credits by this amount 
DECLARE @AmountToReduce INT = 1050 

-- temporary variables  
DECLARE @ID INT, @AvailableCredit INT 

-- get the first row from dbo.Credit that still has availableCredit - ordered by id 
SELECT TOP 1 @ID = id, @AvailableCredit = availableCredit 
FROM dbo.Credit 
WHERE availableCredit > 0 AND organisationId = 1 
ORDER BY id 

-- as long as we still have credit to reduce - loop.. 
WHILE @AmountToReduce > 0 AND @ID IS NOT NULL 
BEGIN 
    -- if we need to remove the complete availableCredit - do this UPDATE 
    IF @AmountToReduce > @AvailableCredit 
    BEGIN 
     UPDATE dbo.Credit 
     SET availableCredit = 0 
     WHERE id = @ID 

     SET @AmountToReduce = @AmountToReduce - @AvailableCredit 
    END 
    ELSE BEGIN 
      -- if the amount to reduce left is less than the availableCredit - do this UPDATE 
     UPDATE dbo.Credit 
     SET availableCredit = availableCredit - @AmountToReduce 
     WHERE id = @ID 

     SET @AmountToReduce = 0 
    END 

    -- set @ID to NULL to be able to detect that there's no more rows left 
    SET @ID = NULL 

    -- select the next "first" row with availableCredit > 0 to process  
    SELECT TOP 1 @ID = id, @AvailableCredit = availableCredit 
    FROM dbo.Credit 
    WHERE availableCredit > 0 AND organisationId = 1 
    ORDER BY id 
END 
+0

谢谢,这个作品 – HashCoder 2012-07-26 04:12:41

1

该脚本由1000减少 “ID 1” availableCredit,并通过50

UPDATE Credit 
SET availableCredit=(availableCredit-1000) 
WHERE id=1 

UPDATE Credit 
SET availableCredit=(availableCredit-50) 
WHERE id=2 
+1

我认为他的意思是一个自动扣除金额的方式,从第一个信用开始。你只知道金额 - 1050. – cppcoder 2012-07-25 10:43:05

+0

我现在编辑了这个问题。感谢cppcoder,这就是我的意思 – HashCoder 2012-07-25 10:47:19

0

尝试此查询:

CREATE table Credit(id integer, organisationid int, availableCredit int) 

INSERT INTO Credit VALUES (1, 1, 1000) 
INSERT INTO Credit VALUES (2, 1, 100) 
INSERT INTO Credit VALUES (3, 2, 600) 
INSERT INTO Credit VALUES (4, 2, 400) 


DECLARE @balance int=1050 

;WITH CTE as (
select id,organisationid,CASE when @balance>availableCredit then 0 else [email protected] end as availableCredit, 
CASE when @balance>availableCredit then @balance-availableCredit else 0 end as balamt from Credit where id=1 and organisationid=1 

union all 

select t.id,t.organisationid,CASE when c.balamt>t.availableCredit then 0 else t.availableCredit-c.balamt end as availableCredit, 
CASE when c.balamt>t.availableCredit then c.balamt-t.availableCredit else 0 end as balamt1 
from Credit t inner join CTE c on t.id-1=c.id and t.organisationid=1 

) 
SELECT id,organisationid,availableCredit FROM CTE 
+0

对不起,我将无法硬编码ids的值。 – HashCoder 2012-07-26 04:13:28

+0

这意味着你想要一次性拥有所有的ID吗? – AnandPhadke 2012-07-26 04:17:16

1

以前我只给出的选择查询,这是最后的更新查询该做的任务。

DECLARE @balance int=1050 

;WITH CTE as (
select id,organisationid,CASE when @balance>availableCredit then 0 else [email protected] end as availableCredit, 
CASE when @balance>availableCredit then @balance-availableCredit else 0 end as balamt from Credit where id=1 and organisationid=1 

union all 

select t.id,t.organisationid,CASE when c.balamt>t.availableCredit then 0 else t.availableCredit-c.balamt end as availableCredit, 
CASE when c.balamt>t.availableCredit then c.balamt-t.availableCredit else 0 end as balamt1 
from Credit t inner join CTE c on t.id-1=c.id --and t.organisationid=1 

) 

Update c SET c.availableCredit = ct.availableCredit 
FROM Credit c inner join CTE ct 
on c.id=ct.id 

SELECT * FROM Credit 
+0

这是更快(SET BASED),因为它不使用while循环。只需检查查询。 – AnandPhadke 2012-07-26 04:24:31