这个SQL循环的第一行是做什么的

时间:2011-05-24 18:54:31

标签: sql

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]。[Customer]表

4 个答案:

答案 0 :(得分: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子句。)

但是,如果您在每次更新后触发的那些表上有触发器,则可能不合适 - 可能有故意他们一次处理一个。但是,如果没有触发器,我看不出有时不立即进行整个更新的原因。如果它是安全的,那么只要你将整个事物包装在一个交易中,你做哪个方式并不重要 - 它们同样安全。

答案 1 :(得分:2)

即声明表变量名称不是实际表。使用循环而不是基于集合的过程,过程本身是非常差的。

答案 2 :(得分:1)

声明表变量后,只需插入所有客户ID:

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

它是一种黑客形式的光标,但它可以通过它们只进行一次。如果您只是将@all_customers替换为真实表,则while循环将永远不会结束,并且您将删除您的客户记录。

删除语句错误,因为列名与第一行中的声明不匹配。

答案 3 :(得分:1)

TABLE是一个关键字。这意味着它正在声明一个表变量。在WHILE循环之前,您需要使用您要处理的客户的客户编号来填充@all_customers(名称不佳的IMO)表变量。

总的来说,这是将基于集合的语言转换为运行过程代码而不是编写基于集合的代码的另一种糟糕方式。特别是因为已经为您提供了基于集合的解决方案。