2013-04-09 164 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