2012-07-25 83 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