2017-02-27 68 views
1

這裏是我的代碼。請原諒我不要把變量放在聲明部分,因爲編輯在給我提交問題之前給我格式化了一些困難時間。甲骨文FOR循環內FOR循環

我想要的結果變量(v_Var)具有值打印爲

v_ID = :NEW.ID; 
v_NAME = :NEW.NAME; 
v_ENTITY_ID = :NEW.ENTITY_ID; 

但是,它是越來越打印爲

v_ID = :NEW.ID; 
v_ID = :NEW.ID; 
v_NAME = :NEW.NAME; 
v_ENTITY_ID = :NEW.ENTITY_ID; 

由於表TEMP_TRG_CONSTRNT有兩行,則工作v_ID也是兩次。 我知道問題是與外部FOR循環,但我不知道如何處理它。

DECLARE 
    CURSOR c1 IS 
SELECT NAME, OCCUR_COUNT FROM IFMS_SYSTEMCONFIGURATION.TEMP_TRG_CONSTRNT; 


BEGIN 
    v_TableName := 'MyTable'; 
    EXECUTE IMMEDIATE 'TRUNCATE TABLE IFMS_SYSTEMCONFIGURATION.TEMP_TRG_CONSTRNT'; 

    INSERT INTO IFMS_SYSTEMCONFIGURATION.TEMP_TRG_CONSTRNT (NAME, OCCUR_COUNT) 
    SELECT A.FKN, COUNT(A.FKN) AS OCCUR_COUNT FROM 
    (
     SELECT A.CONSTRAINT_NAME AS FKN FROM ALL_CONSTRAINTS A 
     INNER JOIN ALL_CONS_COLUMNS B 
     ON A.CONSTRAINT_NAME = B.CONSTRAINT_NAME 
     WHERE A.CONSTRAINT_TYPE IN ('P', 'U') AND A.TABLE_NAME = 'MyTable' 
    )A 
    GROUP BY A.FKN; 

    --FOR CONSTR_NAME IN (SELECT NAME FROM IFMS_SYSTEMCONFIGURATION.TEMP_TRG_CONSTRNT) 
    FOR CONSTR_NAME IN c1 
    LOOP 
    --SELECT NAME, OCCUR_COUNT INTO v_Constr_Name, v_Index_Count FROM TEMP_TRG_CONSTRNT WHERE NAME = CONSTR_NAME.NAME; 
     FOR COL_NAME IN (SELECT COLUMN_NAME FROM ALL_CONS_COLUMNS WHERE CONSTRAINT_NAME = CONSTR_NAME.NAME) 
     LOOP 
     v_Var := v_Var || 'v_' || COL_NAME.COLUMN_NAME || ' = :NEW.' || COL_NAME.COLUMN_NAME || ';' || CHR(13); 
     END LOOP; 
    DBMS_OUTPUT.PUT_LINE(v_Var); 
    END LOOP; 

    END; 
+2

能告訴你,你已經取得了什麼樣的代碼? – Tenzin

+0

我用實際的代碼替換了前面的描述。 –

+0

您是否嘗試過在for循環中使用'SELECT DISTINCT'來刪除重複項? – Jeremy

回答

2

可能有幾件事情引起你的結果:

  1. 有在具有相同名稱的不同模式的表格(你錯過了兩個表之間的店主加入)
  2. 在同一個表上可能有多個約束。

除此之外,您還設法通過執行嵌套循環來重新創建嵌套循環連接。一般來說,這是一個糟糕的主意 - 如果哈希連接更高性能會怎樣?通過使用嵌套遊標for循環,您將有效地遏制Oracle。至少,您可以在循環遍歷它之前在單個sql語句中加入兩個遊標。

但是,它看起來像你想生成的變量列表,而無需輸入。您可以在一個單獨的SQL語句做到這一點 - 不需要PL/SQL,像這樣:

SELECT DISTINCT con.constraint_name, 
       con.owner, 
       con.table_name, 
       col.column_name, 
       'v_'||col.column_name||' := :NEW.'||col.column_name||';' 
FROM all_constraints con 
     inner JOIN all_cons_columns col ON con.constraint_name = col.constraint_name 
              AND con.owner = col.owner 
              AND con.constraint_type IN ('P', 'U') 
              --AND con.owner = 'SOME_OWNER' -- uncomment out and put in the correct owner name, esp if your table exists in more than one owner. 
              AND con.table_name = 'YOUR_TABLE' 
ORDER BY con.owner, con.table_name; 

請注意,我已經包含額外的列,這樣就可以明白爲什麼你得到的結果你如果這與你期望看到的不符,我包含了DISTINCT關鍵字來處理您爲單個owner.table返回多個約束的情況。

如果您想一次爲多個表生成變量列表,您可能希望在CHR(10)的分隔符上使用上述查詢(意味着可以刪除DISTINCT)的聚合listagg函數。

+0

感謝暗示的另一種方法。我在我的方法想通了,這個問題我正在建造的v_Var(輸出) –

+0

的方式我也想補充一點你的建議是一個聰明的一個。 –