2011-11-18 56 views
2

我在選擇語句時遇到問題,不確定我做錯了什麼。這是源表的結構:SQL選擇和案例相結合

源架構DATA1

源表FOLDERS

源列FOLDERID,USERID

目標架構DATA1

目標表FOLDER_USER

目標列FOLDER_ID,USER_ID

這裏是查詢(我需要更改文件夾ID,因爲它是被拉出第一個查詢,因此案件):

DECLARE 
BEGIN 
    FOR FOLDER_ROW IN (SELECT FOLDERID = CASE 
           WHEN FOLDERID = '10' THEN '1' 
           WHEN FOLDERID = '565' THEN '2' 
           WHEN FOLDERID = '11' THEN '3' 
           WHEN FOLDERID = '81' THEN '4' 
           ELSE '0' 
          END, USERID FROM DATA1.FOLDERS WHERE UPPER(OWNER) = 'ADMIN') 
     LOOP      
      INSERT INTO DATA1.FOLDER_USER (FOLDER_ID, CORP_ID) VALUES (FOLDER_ROW.FOLDERID, FOLDER_ROW.CORPID); 
    END LOOP; 
    COMMIT; 
END; 

我收到以下錯誤,當我執行和我堅持爲什麼我得到它。我知道它與選擇內的情況有關:

ORA-06550: line 3, column 39: 
PL/SQL: ORA-00923: FROM keyword not found where expected 
ORA-06550: line 3, column 22: 
PL/SQL: SQL Statement ignored 
+1

爲什麼這麼複雜?這可以通過直接使用INSERT ... SELECT來完成。這會很快**。 –

回答

3

SELECT FOLDERID = CASE is wrong。它應該是SELECT CASE ..... END作爲FOLDERID

+0

謝謝,這麼簡單,但它讓我堅持了這麼久。我認爲我嘗試了除此之外的其他選擇案例的其他組合! – Kaskade

3

看起來你只是想

BEGIN 
    FOR FOLDER_ROW IN (SELECT CASE 
           WHEN FOLDERID = '10' THEN '1' 
           WHEN FOLDERID = '565' THEN '2' 
           WHEN FOLDERID = '11' THEN '3' 
           WHEN FOLDERID = '81' THEN '4' 
           ELSE '0' 
          END folder_id, 
          USERID 
         FROM DATA1.FOLDERS 
        WHERE UPPER(OWNER) = 'ADMIN') 
     LOOP      
      INSERT INTO DATA1.FOLDER_USER (FOLDER_ID, CORP_ID) VALUES (FOLDER_ROW.FOLDER_ID, FOLDER_ROW.CORPID); 
    END LOOP; 
    COMMIT; 
END; 

我添加的FOLDER_ID的別名CASE聲明並消除來自CASE

FOLDERID =
1

你也可以把它改寫爲decode (它是便攜性較差,更難雖然讀)

DECLARE 
BEGIN  
    FOR folder_row IN (SELECT DECODE(folderid,'10', '1','565','2','11', '3','81', '4','0') AS folderid , 
           userid 
         FROM data1.folders 
         WHERE UPPER(owner) = 'ADMIN')  
    LOOP         
     INSERT INTO data1.folder_user (folder_id, corp_id) VALUES (folder_row.folderid, folder_row.corpid);  
    END LOOP;  
    COMMIT; 
END; 

看到:http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/functions042.htm

+0

如果OP使用的是Oracle 8i或更高版本,那麼最好使用ANSI兼容的CASE over DECODE,因爲它有幾個優點(http://oracledoug.com/decode.html) – Ollie

+0

我想這就是爲什麼我寫'less portable更難讀「! –

1

我不知道你是否已經張貼問題之前簡化您的代碼或沒有,但我想看看擺脫遊標的FOR循環完全,只是使用和INSERT語句子-query。

我認爲CURSOR FOR循環已經被Oracle很好地優化了,所以它可能不會運行得更快,但可能更容易理解。

BEGIN 
    INSERT INTO DATA1.FOLDER_USER (FOLDER_ID, CORP_ID) 
    SELECT 
    CASE 
     WHEN FOLDERID = '10' THEN '1' 
     WHEN FOLDERID = '565' THEN '2' 
     WHEN FOLDERID = '11' THEN '3' 
     WHEN FOLDERID = '81' THEN '4' 
     ELSE '0' 
    END folder_id, 
    USERID 
    FROM DATA1.FOLDERS 
    WHERE UPPER(OWNER) = 'ADMIN'; 

    COMMIT; 
END; 
+0

你在代碼中的'ADMIN'之後留下了一個僞造的「)」。 – Ollie

+0

@Ollie謝謝。固定。 –