如何避免oracle pl / sql中的全局临时表

时间:2016-02-01 01:55:09

标签: arrays oracle plsql

我使用以下FUNCTION根据数组中的给定字符串(po_System_arr)检查重复值。以下是输入参数的说明

  1. 数组将发送两个值(一个是pi_SysArr(i).PrdID,另一个是pi_SysArr(i).sysVal)
  2. " pi_ValueString"中的字符串
  3. pi_system_iid中的系统IID(只有客户ID)
  4. 为此我使用全局临时表(GTT_CR_PROCESS。

    是否有其他方法可以检查重复值而无需存储在GTT ---表脚本

    CREATE GLOBAL TEMPORARY TABLE GTT_CR_PROCESS
    (SYSTEM_IID NUMBER , SYSTEM_STRING VARCHAR2(500))  
    ON COMMIT DELETE ROWS
    

    功能

    FUNCTION Fnc_ChkSystem_Value (pi_SysArr            in po_System_arr,
                              pi_ValueString        VARCHAR2,
                              pi_system_iid         ms_card.SYSTEM_IID%type                          
                              ) 
    RETURN NUMBER 
    IS
        v_cnt         NUMBER := 0;
        v_cnt1        NUMBER := 0;
        v_ArrCNT      NUMBER := 0;
    
        ChkDup        Varchar2(1) :='N';
        nCount          NUMBER:=0;
        nStringCount    NUMBER:=0;
        vSystem_iid ms_card.SYSTEM_IID%TYPE;
        v_AttribIID     NUMBER;
    BEGIN   
    
    IF pi_SysArr IS NOT NULL and pi_SysArr.COUNT>0 THEN
        v_ArrCNT := pi_SysArr.COUNT;
    
        -- Loop through the array of attributes
        FOR i in pi_SysArr.FIRST..pi_SysArr.LAST 
        LOOP
                v_AttribIID := get_ProductTypeID(pi_ProductType => pi_SysArr(i).PrdType,
                                                 pi_ProductId => pi_SysArr(i).PrdID);
    
                SELECT  COUNT(1) INTO nCount
                 from  hk_system_values  HSV
                WHERE hsv.value_iid = v_AttribIID 
                  AND  UPPER(hsv.system_value) =  UPPER(pi_SysArr(i).sysVal)
                  AND hsv.STATUS = 0;
    
                  If nCount > 0 Then    
                        FOR RS IN (SELECT SYSTEM_IID   from  hk_system_values  hsv 
                                    WHERE hsv.value_iid = v_AttribIID 
                                    AND  UPPER(hsv.system_value) =  UPPER(pi_SysArr(i).sysVal)
                                    AND hsv.STATUS = 0)
                        LOOP    
    
                                MERGE INTO GTT_CR_PROCESS CR
                                USING dual
                                ON (CR.SYSTEM_IID = RS.SYSTEM_IID)
                                WHEN MATCHED THEN
                                    UPDATE
                                       SET CR.SYSTEM_STRING = CR.SYSTEM_STRING||UPPER(pi_SysArr(i).sysVal)
                                 WHEN NOT MATCHED THEN
                                    INSERT
                                        (SYSTEM_IID, SYSTEM_STRING)
                                    VALUES
                                        (RS.SYSTEM_IID,
                                        UPPER(pi_SysArr(i).sysVal)
                                         );
                                 ChkDup := 'Y';
                        END LOOP;
                  ELSE              -
                     EXIT;
                     ChkDup := 'N';
                  END IF;
        END LOOP;   
    
    
        if ChkDup = 'Y' Then 
                SELECT COUNT(1),max(SYSTEM_IID) 
                 INTO nStringCount, vSystem_iid 
                 FROM GTT_CR_PROCESS 
                 WHERE SYSTEM_STRING = pi_ValueString;
    
                COMMIT;
    
                IF nStringCount > 0 then         
                    If nStringCount = 1 and vSystem_iid = pi_system_iid Then         
    
                        RETURN 0;
                    else 
                        RETURN 1;
                    end if;
                ELSE 
                    RETURN 0;
                END IF;
        ELSE            -- No Duplicate found
                RETURN 0;
        END IF;
    ELSE 
        RETURN 0;            
    END IF;
    
    END;
    

    从上面的代码中,可以正确地得到所需的结果。但我想避开GTT,还有其他方法吗?。

1 个答案:

答案 0 :(得分:1)

只要你的表中没有数百万行,否则你会为你的会话炸掉PGA,我会在内存集合中声明如下:

 TYPE t_chkdup IS TABLE OF VARCHAR2(32);
 l_chkdup t_chkdup

在您的条件之后将系统值放入集合中:

l_chkdup(i) := UPPER(hsv.system_value); -- or whatever is the unique value here

然后执行以下操作:

for j in l_chkdup.first..l_chkdup.last loop
 if l_chkdup.exists(j) then
 ...... do something
 end if;
end loop;

你会发现这种运行速度非常快,但代价是使用更多的CPU和内存。