2016-09-22 58 views
0

我想通過所有表和ID和表名複製到表中多行。 由於我必須使用一個變量作爲表名,我用IMMEDIATE EXECUTE試了一下。但對於動態SQL,INSERT INTO語句只允許單行。的Oracle PL/SQL - 我如何可以插入使用動態SQL

下面的SQL語句就是這樣,如果 IMMEDIATE EXECUTE將允許INSERT INTO與muplitple行。

DECLARE 
    sqlStat VARCHAR2(500); 

BEGIN 
    FOR TName IN (
    SELECT TABLE_NAME FROM all_tab_cols WHERE column_name='ID' 
) 

    LOOP 
    sqlStat := 'INSERT INTO storeTab (ID,TABLE_NAME) SELECT ID, '' :1 '' FROM :2'; 
    EXECUTE IMMEDIATE sqlStat USING TName.TABLE_NAME,TName.TABLE_NAME; 
    END LOOP; 
END; 

如何循環訪問表並收集記錄?

回答

5

insert ... select可以插入多個行,如果不管它是通過「普通」 SQL執行時,通過PL/SQL或通過動態SQL。

但你不能使用佔位符動態SQL的標識符(名稱)。您需要連接查詢。而你並不需要,如果你是通過USING子句將值傳遞給使用單引號:

DECLARE 
    sqlStat VARCHAR2(500); 
BEGIN 
    FOR TName IN (SELECT TABLE_NAME FROM all_tab_cols WHERE column_name='ID' and table_name = 'FOO') 
    LOOP 
    sqlStat := 'INSERT INTO storetab (ID,TABLE_NAME) SELECT ID, :1 FROM '||tname.table_name; 
    EXECUTE IMMEDIATE sqlStat USING TName.TABLE_NAME; 
    END LOOP; 
END; 
/

插入儘可能多的行插入storetab因爲有源表中的行。


有點風馬牛不相及,但:

all_tab_columns可以多次可能返回相同的表名,如果當前用戶有權訪問在不同的模式這些表。您應該處理的是正確的選擇也從all_tab_columns and adjust theowner選擇part of the dynamic SQL accordingly. Or use user_tab_cols`,而不是如果你只在當前用戶擁有表感興趣。

+0

獲取串聯查詢所做的工作,我能夠檢索多個行。感謝您的快速解決方案! – DonJoe

0

我更喜歡使用USER_TAB_COLUMNS,因爲沒有需要追加模式名和表名。如果我們使用ALL_TAB_COLS,那麼最好使用OWNER。

您還可以通過使用USER_TAB_COLUMNS如下框架您的查詢。

DECLARE 
    sqlStat VARCHAR2(500); 
BEGIN 
    FOR TName IN (SELECT TABLE_NAME FROM USER_TAB_COLUMNS WHERE column_name='ID') 
    LOOP 
    sqlstat := 'INSERT INTO storeTab (ID,TABLE_NAME) SELECT ID, ''' ||TName.TABLE_NAME|| ''' FROM '||Tname.TABLE_NAME ; 
    EXECUTE IMMEDIATE sqlStat ; 
    END LOOP; 
END; 

還是從ALL_TAB_COLS

DECLARE 
    sqlStat VARCHAR2(500); 
BEGIN 
    FOR TName IN (SELECT OWNER,TABLE_NAME FROM ALL_TAB_COLS WHERE column_name='ID') 
    LOOP 
    sqlStat := 'INSERT INTO storeTab (ID,TABLE_NAME) SELECT ID, ''' ||TName.TABLE_NAME|| ''' FROM '||Tname.OWNER||'.'||Tname.TABLE_NAME; 
    EXECUTE IMMEDIATE sqlStat ; 
    END LOOP ; 
END ;