2017-10-10 12 views
0

J'essaie de modifier le nom de la table dans la requête en utilisant le concept de requête dynamique dans Oracle.Problème Oracle PL/SQL dans la modification dynamique de la valeur de la variable

L'exécution initiale était bonne. Mais alors, une fois le nom de la table modifié avec une nouvelle valeur, même si elle est en valeur ancienne.

Vérifier le code ci-dessous ....

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; 

Et la sortie est ....

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 

Mais ici la deuxième requête doit préparer avec table UserData_Backup.

bien vouloir me aider à identifier le problème ....

+0

espère que ma solution vous aidera à .. vérifier. !! –

+0

Vous n'avez pas modifié le nom de la table, il est déjà codé en dur dans DYNA_QUERY_DEL. Vous avez seulement changé la valeur de la variable qui n'est plus utilisée. Y a-t-il une raison spécifique pour utiliser SQL dynamique? –

Répondre

1

requête dynamique agir une fois dans un programme à moins que vous êtes en utilisant For Loop. Si vous ne voulez pas utiliser la boucle, vous pouvez utiliser la même requête pour la seconde exécution dynamique et ici j'utilise des fonctions de bouclage.

Code

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

Oui, la réaffectation de la même requête fonctionne. Mais avons-nous une autre approche comme rafraîchir le cache ou la session de la variable DYNA_TABLE_NAME? – srihariraom

+0

yah ... méthode de bouclage alternatif j'ai mis à jour dans mon code le vérifier. –

+0

Cela vous at-il été utile? –

1

re assigner la variable DYNA_QUERY_DEL essayer de le faire comme ça

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

Oui, j'ai aussi eu la même idée. Mais réaffecter semble étrange pour moi. Je suis développeur Java et nouveau programme PL/SQL. – srihariraom

+0

la valeur de 'DYNA_TABLE_NAME' a changé, c'est pourquoi vous devez attribuer à nouveau' DYNA_QUERY_DEL'. de toute façon pouvez-vous me dire quelle est la sortie de la deuxième exécution? il contient le nom de la table 'UserData_Backup' droit? – Moudiz

+0

Oui, vous avez le deuxième nom de table. :-) – srihariraom