2017-10-10 8 views
0

Oracleの動的クエリの概念を使用して、クエリでテーブル名を変更しようとしています。Oracle PL/SQL変数値を動的に変更する際の問題

最初の実行は良好でした。しかし、いったんテーブル名が新しい値で変更されると、それは古い値として表示されています。

CREATE OR REPLACE PROCEDURE Test 
AS 
BEGIN 
    DECLARE 
    DELETE_OLD_YEARS NUMBER(2); 
    RECORD_COUNT NUMBER(10); 
    INTERVAL_UNIT VARCHAR2(4); 
    DYNA_QUERY_DEL VARCHAR2(280); 
    DYNA_TABLE_NAME VARCHAR(30); 

    BEGIN 

    INTERVAL_UNIT := 'YEAR'; 
    RECORD_COUNT := 0; 
    DYNA_TABLE_NAME := 'UserData'; 
    DELETE_OLD_YEARS := 7; 

    DYNA_QUERY_DEL := 'SELECT COUNT(*) 
         FROM ' || DYNA_TABLE_NAME || ' UD 
         WHERE UD.LOGIN_DT < (SYSDATE - NUMTOYMINTERVAL(:1, :2)) 
         OR UD.LOGIN_DT IS NULL ORDER BY UD.LOGIN_DT DESC'; 

    -- Delete older than 7 years data 
    DBMS_OUTPUT.PUT_LINE('Dynamic Query with UserData: ' || DYNA_QUERY_DEL); 
    EXECUTE IMMEDIATE DYNA_QUERY_DEL INTO RECORD_COUNT USING DELETE_OLD_YEARS, INTERVAL_UNIT; 
    DBMS_OUTPUT.PUT_LINE('Record Count : ' || RECORD_COUNT); 


    -- Delete older than 7 years data from backup table. 
    DYNA_TABLE_NAME := 'UserData_Backup'; 
    DELETE_OLD_YEARS := 7; 
    DBMS_OUTPUT.PUT_LINE('Dynamic Query with UserData_Backup : ' || DYNA_QUERY_DEL); 
    EXECUTE IMMEDIATE DYNA_QUERY_DEL INTO RECORD_COUNT USING DELETE_OLD_YEARS, INTERVAL_UNIT; 
    DBMS_OUTPUT.PUT_LINE('Record Count 2 : ' || RECORD_COUNT); 

    END; 

END; 
/

exec Test; 

....以下のコードをチェックして、出力されます....

Dynamic Query with UserData : SELECT COUNT(*) 
         FROM UserData UD 
         WHERE UD.LOGIN_DT < (SYSDATE - NUMTOYMINTERVAL(:1, :2)) 
         OR UD.LOGIN_DT IS NULL ORDER BY UD.LOGIN_DT DESC 
Record Count : 6220 
Dynamic Query with UserData_Backup : SELECT COUNT(*) 
         FROM UserData UD 
         WHERE UD.LOGIN_DT < (SYSDATE - NUMTOYMINTERVAL(:1, :2)) 
         OR UD.LOGIN_DT IS NULL ORDER BY UD.LOGIN_DT DESC 
Record Count 2 : 6220 

しかし、ここでは2番目のクエリは、UserData_Backupテーブルで準備する必要があります。

親切

+0

は、私の解決策は、あなたが...それをチェックするのに役立ちます願っています。! –

+0

テーブル名は変更されていません。すでにDYNA_QUERY_DELにハードコードされています。再度使用されない変数の値のみを変更しました。動的SQLを使用する特別な理由はありますか? –

答えて

1

ダイナミッククエリはプログラムで1時間に行動するようにそれを行うには、変数DYNA_QUERY_DEL試みを割り当て直す....私は問題を識別するのに役立ちますFor Loopを使用します。ループを使用したくない場合は、同じクエリを2番目の動的実行に使用できます。ここではループ関数を使用しています。

コード

CREATE OR REPLACE PROCEDURE Test 
     AS 
     BEGIN 
      DECLARE 
      DELETE_OLD_YEARS NUMBER(2); 
      RECORD_COUNT NUMBER(10); 
      INTERVAL_UNIT VARCHAR2(4); 
      DYNA_QUERY_DEL VARCHAR2(280); 
      DYNA_TABLE_NAME VARCHAR(30); 
      BEGIN 
      INTERVAL_UNIT := 'YEAR'; 
      RECORD_COUNT := 0; 
      --DYNA_TABLE_NAME := 'UserData'; 
      -- DYNA_TABLE_NAME := 'UserData_Backup'; 
      DELETE_OLD_YEARS := 7; 
      for c1 in (select 'UserData' as DYNA_TABLE_NAME from dual 
         union all 
         select 'UserData_Backup' as DYNA_TABLE_NAME from dual) 
      loop 
      DYNA_QUERY_DEL := 'SELECT COUNT(*) 
           FROM ' || DYNA_TABLE_NAME || ' UD 
           WHERE UD.LOGIN_DT < (SYSDATE - NUMTOYMINTERVAL(:1, :2)) 
           OR UD.LOGIN_DT IS NULL ORDER BY UD.LOGIN_DT DESC'; 

      -- Delete older than 7 years data 
      DBMS_OUTPUT.PUT_LINE('Dynamic Query with UserData: ' || DYNA_QUERY_DEL); 
      EXECUTE IMMEDIATE DYNA_QUERY_DEL INTO RECORD_COUNT USING DELETE_OLD_YEARS, INTERVAL_UNIT; 
      RECORD_COUNT := RECORD_COUNT +1; 
      end loop; 
      DBMS_OUTPUT.PUT_LINE('Record Count 2 : ' || RECORD_COUNT); 
      END; 
     END; 
     /
     exec Test; 
+0

はい、同じクエリを再割り当てしています。しかし、DYNA_TABLE_NAME変数のキャッシュまたはセッションをリフレッシュするような代替アプローチはありますか? – srihariraom

+0

yah ...代替ループメソッド私は自分のコードを更新しました。 –

+0

これはあなたにとって有益ですか? –

1

はあなたがない限り、この

CREATE OR REPLACE PROCEDURE Test 
AS 
BEGIN 
    DECLARE 
    DELETE_OLD_YEARS NUMBER(2); 
    RECORD_COUNT NUMBER(10); 
    INTERVAL_UNIT VARCHAR2(4); 
    DYNA_QUERY_DEL VARCHAR2(280); 
    DYNA_TABLE_NAME VARCHAR(30); 

    BEGIN 

    INTERVAL_UNIT := 'YEAR'; 
    RECORD_COUNT := 0; 
    DYNA_TABLE_NAME := 'UserData'; 
    DELETE_OLD_YEARS := 7; 

    DYNA_QUERY_DEL := 'SELECT COUNT(*) 
         FROM ' || DYNA_TABLE_NAME || ' UD 
         WHERE UD.LOGIN_DT < (SYSDATE - NUMTOYMINTERVAL(:1, :2)) 
         OR UD.LOGIN_DT IS NULL ORDER BY UD.LOGIN_DT DESC'; 

    -- Delete older than 7 years data 
    DBMS_OUTPUT.PUT_LINE('Dynamic Query with UserData: ' || DYNA_QUERY_DEL); 
    EXECUTE IMMEDIATE DYNA_QUERY_DEL INTO RECORD_COUNT USING DELETE_OLD_YEARS, INTERVAL_UNIT; 
    DBMS_OUTPUT.PUT_LINE('Record Count : ' || RECORD_COUNT); 


    -- Delete older than 7 years data from backup table. 
     DYNA_TABLE_NAME := 'UserData_Backup'; 

    DYNA_QUERY_DEL := 'SELECT COUNT(*) 
         FROM ' || DYNA_TABLE_NAME || ' UD 
         WHERE UD.LOGIN_DT < (SYSDATE - NUMTOYMINTERVAL(:1, :2)) 
         OR UD.LOGIN_DT IS NULL ORDER BY UD.LOGIN_DT DESC'; 

    DELETE_OLD_YEARS := 7; 
    DBMS_OUTPUT.PUT_LINE('Dynamic Query with UserData_Backup : ' || DYNA_QUERY_DEL); 
    EXECUTE IMMEDIATE DYNA_QUERY_DEL INTO RECORD_COUNT USING DELETE_OLD_YEARS, INTERVAL_UNIT; 
    DBMS_OUTPUT.PUT_LINE('Record Count 2 : ' || RECORD_COUNT); 

    END; 

END; 
/

exec Test; 
+0

はい、同じ考えがあります。しかし、再割り当ては私のために幾分奇妙に見えます。私はJava開発者であり、PL/SQLプログラムの初心者です。 – srihariraom

+0

'DYNA_TABLE_NAME'の値が変更されたため、' DYNA_QUERY_DEL'を再度割り当てる必要があります。とにかく、2回目の実行の結果は何ですか? 'UserData_Backup'というテーブル名が含まれていますか? – Moudiz

+0

はい、2番目のテーブル名を取得しました。 :-) – srihariraom

関連する問題