2011-05-24 37 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)表变量。总体而言,这是将基于集合的语言转换为正在运行的过程代码而不是编写基于集合的代码的另一种糟糕的方式。特别是因为基于集合的解决方案已经提供给您。