2017-02-27 42 views
1

これは私のコードです。私の問題を提出する前に、エディタが書式設定に苦労していたので、宣言セクションに変数を入れないことを私に許してください。FORループ内のOracle FORループ

私は結果変数(v_Var)は、テーブルTEMP_TRG_CONSTRNTは、それがために働いている、2行を持っているので、それは

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

として印刷取得され、

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

として印刷値を持っていますがしたいですv_IDも2回。 私はこの問題が外部の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つのテーブル間の所有者に参加している行方不明)があります
  2. 同じテーブルに複数の制約が存在する可能性があります。

さらに、ネストループを実行することで、ネストループジョインを再作成することもできました。一般的に、これは悪い考えです。ハッシュ結合がより効果的だったらどうしたらいいですか?ループのネストされたカーソルを使用すると、効果的にOracleを悩ますことになります。少なくとも、1つのSQL文で2つのカーソルを結合してからループすることができます。

しかし、変数を入力せずにリストを生成しようとしているようです。あなたは、単一の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に対して複数の制約が返された場合に対応しました。

複数のテーブルの変数のリストを一度に生成する場合は、上記のクエリ(DISTINCTを削除することができます)で集計listagg関数をCHR(10)の区切り文字で使用できます。

+0

代替方法を提案してくれてありがとう..私は私のアプローチでは、問題はv_Var(出力)を構築していた方法だと考えた –

+0

私はあなたの提案がよりスマートなものだと付け加えたい。 –