Oracle PL / SQL问题动态更改变量值

时间:2017-10-10 13:46:06

标签: oracle plsql dynamic-sql

我正在尝试使用Oracle中的动态查询概念更改查询中的表名。

初步执行情况良好。但是,一旦表名用新值修改,即使它显示为旧值。

检查以下代码......

    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

但是这里第二个查询应该准备UserData_Backup表。

请帮助我确定问题......

2 个答案:

答案 0 :(得分:1)

重新分配变量DYNA_QUERY_DEL尝试像这样做

    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;

答案 1 :(得分:1)

动态查询将在程序中执行一次,除非您使用For循环。如果您不想使用循环,您可以使用相同的查询来进行第二次动态执行,这里我使用循环函数。

<强>码

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;