ORACLE 存储过程内是否可以做这样一件事(保证每次调用该存储过程时都是一个新的会话SESSION)是这样的:我在存储过程内使用了已经建好的临时表,因为,计算量很大,而且计算次数多,我把每次的计算结果都直接存入这个临时表了,最后我只返回临时表中数据就可以了;可是我遇到这样一个问题:1、每次的执行后这个临时表中数据,不一定是每次计算后的结果,有时是上一次的结果,有时是空的!2、我在存储过程内第一行加了清表的ORACLE指令,也一样是有时是上次的结果,有时是空的!3、我感觉好像是每次执行时会话不一定结束了,所以仍保留着上次的结果;因为在加 DELETE FROM TABLENAME 之前有时数据是重叠好几份;加了以后虽然不重叠了,但有时是上次的结果;有时是空结果;(对空结果表示不理解)(注:我这个临时表是会话级的临时表)

解决方案 »

  1.   

    1、每次的执行后这个临时表中数据,不一定是每次计算后的结果,有时是上一次的结果,有时是空的!
    这个问题你写表后写commit了吗?写了的话位置对不对,看是在循环里面还是在外面。
      

  2.   

    存储过程执行前truncate table 
      

  3.   

    建临时表有两个选项,确认是否选择正确:
    CREATE GLOBAL TEMPORARY TABLE tableName
       ON COMMIT DELETE ROWS ;
    当执行COMMIT时会把记录清空。CREATE GLOBAL TEMPORARY TABLE tableName
       ON COMMIT PRESERVE ROWS ;
    当SESSION结束时会把记录清空。
      

  4.   


    试了,如果 COMMIT ,那我这个临时表就空了,没有一条记录可以返回!
      

  5.   

    具体的计算过程之类的代码全部删减了,以免太大,大家不方便看!
    create or replace procedure RPT_CALC(par_year              IN NUMBER, -- 业务年度
                                         par_roleCode          IN VARCHAR2, -- 角色编码
                                         par_reptTemplateId    IN NUMBER, -- 报表模板ID
                                         par_out_return_   OUT NUMBER, -- 输出成功标志, 1-成功, 0-异常 
                                         par_out_sql_statement OUT VARCHAR2 -- 输出 SQL 语句
                                         ) IS  TYPE FieldCursor IS REF CURSOR;
      res_success varchar2(10);  /** 字段列表 **/
      fieldsList VARCHAR2(32767);  /** 执行: 统计本级数据并存入 TEMP_TB_REPT01 **/
      FUNCTION totalChildLevelData(par_reptId IN VARCHAR2) RETURN VARCHAR2 AS
      BEGIN
        /** 计算本级数据里也是个循环计算 **/
        -- 此处代码略
        RETURN '1'; -- 1表示统计成功
      END totalChildLevelData;  /** 执行: 统计非本级数据并存入 TEMP_TB_REPT01 **/
      FUNCTION totalParentLevelData(par_levelno IN NUMBER,
                                    par_reptId  IN VARCHAR2) RETURN VARCHAR2 AS
      BEGIN
        -- 此处代码略
        RETURN '1'; -- 1表示统计成功
      END totalParentLevelData;begin  DELETE FROM TEMP_TB_REPT01;  res_success := totalChildLevelData(par_reptTemplateId);  /**
        res_success := totalParentLevelData(par_reptTemplateId);  
        -- ...这三行连续的数据表示这里原来是一个未知次数的循环计算
        res_success := totalParentLevelData(par_reptTemplateId);
      **/  --增加本级标识
      UPDATE TEMP_TB_REPT01 SET NAME = NAME || '(本级)' WHERE ISTHELEVEL = 1;  par_out_return_   := 1;
      par_out_sql_statement := 'SELECT * FROM TEMP_TB_REPT01 ORDER BY CODE, LEVELNO, ISTHELEVEL';EXCEPTION
      WHEN OTHERS THEN
        par_out_return_   := 0;
        par_out_sql_statement := '';
    end RPT_CALC;现在问题是,第一行虽然加了 DELETE FROM TEMP_TB_REPT01 ,仍然有两种情况:
    1、本不该有数据结果时有结果,本该有结果的却没有结果;(这一点本人感觉像是上次的结果没有清掉,
       可能是 ORACLE 的 SESSION 还是上一次的吧;
    2、如果不要 DELETE FROM TEMP_TB_REPT01 这一行代码,那么数据会叠加起来;所以感觉很明显是 ORACLE SESSION 的问题了,只是不知道有什么办法解决啊特此求助谢谢非常感谢
      

  6.   

    问题已经解决了,给分!是这样解决的,在存储过程最前面加个:DELETE FROM TEMP_TB_REPT01;
    COMMIT;    -- 最关键的是加这个 COMMIT,意思是把清掉的数据 COMMIT 一下,此时表才被真正的清掉;
               -- 这样就能保证下面的所有写表数据,都会在本次会话中返回,也就不会有像楼上那样查到
               -- 的是上次查询的结果了;(已经测试过没有问题了!)