2017-02-27 246 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

的方式我也想补充一点你的建议是一个聪明的一个。 –