2013-04-09 127 views
1

我有一张名为master的表,主键是account_num。每个帐号都有一个account_type(单个字符)。我需要做到以下几点:SQL循环遍历表中的记录

  1. 找到所有账户用A型或B.
  2. 商店,占在一个新的表数year_end_close随着当交易发生
  3. 的时间戳叫
  4. 设置主所有账户到C A型的,所有账户,以d

是什么在SQL处理的最佳方式是B型的? while循环?案例陈述?光标?任何帮助表示赞赏。这张桌子有大约17,000行。

+0

你可以用2个查询做到这一点。插入和更新。 – 2013-04-09 17:34:44

+1

那么,3个查询,如果你还没有创建表。 – 2013-04-09 17:35:25

+0

我对SQL脚本编程的熟悉程度非常有限 - 我知道如何在其他语言中执行此操作,但我的不确定性在于如何确保查看表中的每条记录并为每条记录执行操作 - if这就说得通了。 – Jana 2013-04-09 17:39:01

回答

3

你不应该需要使用光标/循环,做这样的事情。编写SQL时,总是先尝试查找基于集合的解决方案。我会推荐一个CASE声明,这是您提到的选项之一。

试试这个:

BEGIN TRAN; 

SELECT account_num, CURRENT_TIMESTAMP 
INTO year_end_close 
FROM dbo.master 
WHERE account_type IN ('a','b'); 

UPDATE dbo.master 
SET account_type = CASE account_type 
        WHEN 'a' THEN 'c' 
        WHEN 'b' THEN 'd' 
        ELSE account_type 
        END 
WHERE account_type IN ('a','b'); 

COMMIT TRAN; 
+1

这基本上就是我要去的方式,尽管我会选择nits并使用ANSI'current_timestamp'而不是专有'getdate()',并将同一个where子句应用于select和update。 – 2013-04-09 18:16:43

+0

@TimLehner你是对的,好点。我通常自己使用'current_timestamp';我只是认为'getdate()'对于不熟悉SQL的人来说更容易遵循,我不知道'current_timestamp'是ANSI标准。我会编辑我的答案。 – 2013-04-09 18:20:30

+1

基于集合逻辑的好建议。 SELECT ... INTO ...也是专有语法。如果您想要成为严格的ANSI,请使用单独的CREATE TABLE和INSERT ... SELECT ...另外,您可能需要过滤for_end_close中存在的行。根据活动和隔离级别,您可以更新插入到year_end_close后插入或更新的行。 – JAQFrost 2013-04-09 18:31:33

2

你在寻找类似的东西吗? (替换“打印”语句为您的实际的SQL语句)

DECLARE @MasterTable TABLE 
(
    account_num int, 
    account_type varchar(1) 
) 
INSERT INTO @MasterTable VALUES (1, 'A') 
INSERT INTO @MasterTable VALUES (2, 'A') 
INSERT INTO @MasterTable VALUES (3, 'B') 
INSERT INTO @MasterTable VALUES (4, 'B') 
INSERT INTO @MasterTable VALUES (5, 'C') 
INSERT INTO @MasterTable VALUES (6, 'C') 

DECLARE @account_num int 
DECLARE @account_type varchar(1) 
DECLARE @switch_type varchar(1) 

DECLARE db_cursor CURSOR FOR 
SELECT account_num, account_type 
FROM @MasterTable 
WHERE account_type IN ('A', 'B') 

OPEN db_cursor 
FETCH NEXT FROM db_cursor INTO @account_num, @account_type 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    IF @account_type = 'A' 
     SET @switch_type = 'C' 
    ELSE 
     SET @switch_type = 'D' 

    PRINT 'INSERT year_end_close (account_num, timestampfield) VALUES (' + CAST(@account_num AS VARCHAR) + ', GETDATE())' 
    PRINT 'UPDATE @MasterTable SET account_type = ' + @switch_type + ' WHERE account_num = ' + CAST(@account_num AS VARCHAR) 
FETCH NEXT FROM db_cursor INTO @account_num, @account_type 
END 

CLOSE db_cursor 
DEALLOCATE db_cursor