2011-05-24 36 views
1
declare @all_customers as table( CustNum int); 

/* --you can insert dummy data for testing purposes like so: 
insert into @all_customers select 5, 1 union select 2, 1 --*/ 

while (0 < (select count(*) from @all_customers)) 
begin 
declare @current_customer int = (select top 1 CustNum from @all_customers); 
declare @balance money = (select acct_balance from [crrsql].[dbo].[Customer] where CustNum = @current_customer); 
update [crrsql].[dbo].[Customer] set Acct_balance = 0; 
INSERT INTO [crrsql].[dbo].[AR_Transactions] (cashier_ID, CustNum, Balance) VALUES (100199, user, abs(@balance));  
delete @all_customers where customernumber = @current_customer; 
end 

我是否需要字表更改爲實際的表名的第一線......或者是一個關鍵字,如果是的話我如何指定Customers表 基本上我需要通過[DBO]環[客戶]表這是什麼SQL循環做

回答

4
declare @all_customers as table( CustNum int); 

這被稱爲創建一個@all_customers表變量。然後,您的代碼通過從該臨時表的最上一行獲取ID,使用該ID處理客戶,然後從列表中刪除進程ID並重復,直到表爲空(即已處理所有ID )。你不能在這裏更改單詞table,沒有。 (這基本上與我在客戶桌上使用光標相同,但允許您修改底下的表格 - 儘管如此,我認爲它並不那麼高效。)

如果要處理所有客戶在這個循環中,你可能想要將它們的ID加載到這個表中,例如

declare @all_customers as table( CustNum int); 

// Load customer IDs to process 
insert into @all_customers select CustNum from Customers; // where <condition>? 

while (0 < (select count(*) from @all_customers)) 

這一切說,我不明白爲什麼你需要在這裏循環。你可能也可以這樣做:

INSERT INTO [crrsql].[dbo].[AR_Transactions] (cashier_ID, CustNum, Balance) 
SELECT 100199, CustNum, abs(acct_balance) 
    FROM [crrsql].[dbo].[Customer]; 

UPDATE [crrsql].[dbo].[Customer] set Acct_balance = 0; 

一次處理所有記錄。 (如果你想選擇一部分客戶,你也可以使用這裏的where子句來做到這一點。)

但是,如果你在每一行更新之後觸發那些表的觸發器 - 這可能是故意的他們一次處理一個的原因。但是,如果沒有觸發器,我不會看到一個不會立即執行整個更新的理由。如果它的目的是爲了安全,那麼只要你將所有事情都包裝在一個交易中,你做它的方式並不重要 - 它們同樣安全。

+0

從技術上講,它是一個表變量,而不是臨時表,http://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/03/30/sql-server-table-variable-vs-local-temporary- table.aspx – 2011-05-24 19:01:27

+0

但增量在哪裏...喜歡這個循環如何知道什麼時候停止 – Trace 2011-05-24 19:04:53

+0

@Shan D'哦 - 謝謝,修正。 – Rup 2011-05-24 19:05:35

2

這是聲明一個表變量名稱不是一個實際的表。使用循環代替基於集合的過程的過程本身是非常差的過程。

1

表變量的聲明之後,只需插入所有客戶的ID:

insert into @all_customers select customerIDcolumn from [crrsql].[dbo].[Customers] 

這是一個光標的哈克形式,但它的工作原理通過他們去一次,只有一次。如果你只是將@all_customers替換爲真正的表,while循環將永遠不會結束,並且你將刪除你的客戶記錄。

delete語句錯誤,因爲列名稱與第一行中的聲明不匹配。

1

TABLE是一個關鍵字。這意味着它正在聲明一個表變量。在WHILE循環之前,您需要使用您想要處理的客戶的客戶編號來填充@all_customers(一個貧窮的名稱IMO)表變量。總體而言,這是將基於集合的語言轉換爲正在運行的過程代碼而不是編寫基於集合的代碼的另一種糟糕的方式。特別是因爲基於集合的解決方案已經提供給您。