Oracle PLSQL动态查询的长期运行问题

5jdjgkvh  于 2023-06-22  发布在  Oracle
关注(0)|答案(1)|浏览(126)

`下面的代码有长期运行问题。该代码将准备动态更新查询并使用日志执行更新语句。请帮助优化此查询。先谢谢你。

代码:

DECLARE
TYPE MFU_REC_TYPE
IS
  RECORD
  (
    Product_Category VARCHAR2(4000),
    SOURCE_COLUMN    VARCHAR2(4000),
    SOURCE_VALUE     VARCHAR2(4000),
    TARGET_COLUMNS   VARCHAR2(4000),
    TARGET_VALUE     VARCHAR2(4000),
    TP_SYS_NM        VARCHAR2(4000) );
TYPE MFU_table_type
IS
  TABLE OF MFU_REC_TYPE INDEX BY PLS_INTEGER;
  MFU_VALUES MFU_table_type;
TYPE log_REC_TYPE
IS
  RECORD
  (
    log_type        VARCHAR2(4000),
    Update_query    VARCHAR2(4000),
    Process_Message VARCHAR2(4000) );
TYPE log_table_type
IS
  TABLE OF log_REC_TYPE;
  Log_VALUES log_table_type:=log_table_type();
  LS_SQL          VARCHAR2(1000);
  LS_MFU_TABLE    VARCHAR2(1000);
  LS_AGG_TABLE    VARCHAR2(1000);
  ls_update_query VARCHAR2(4000);
  lb_exception    BOOLEAN;
BEGIN
  lb_exception :=false;
  LS_MFU_TABLE := @MFU_Table_name ;
  LS_AGG_TABLE :=@AGG_Table_name;
  
  LS_SQL       := 'SELECT Product_Category,
SOURCE_COLUMN,    
SOURCE_VALUE,    
TARGET_COLUMNS,  
TARGET_VALUE, 
TP_SYS_NM   
FROM '||LS_MFU_TABLE;

  EXECUTE IMMEDIATE ls_sql BULK COLLECT INTO MFU_values;
  
  FOR i IN 1 .. MFU_values.COUNT
  LOOP
    BEGIN
      Log_VALUES.extend;
      
      ls_update_query           := 'update  '||LS_AGG_TABLE||'  set  ' ||MFU_values(i).TARGET_COLUMNS|| ' = '||''''||MFU_values(i).TARGET_VALUE||''''|| ' where trim(' ||MFU_values(i).SOURCE_COLUMN||') = trim( '||''''|| MFU_values(i).SOURCE_VALUE||''''|| ') and  trim(PRODUCT_CATEGORY) = trim('||''''|| MFU_values(i).Product_Category||''''|| ') ' ;
      
      Log_VALUES(i).Update_query:=ls_update_query;
      
      EXECUTE immediate ls_update_query;
      
      Log_VALUES(i).Process_Message:=SQL%ROWCOUNT||' rows got updated.';
      Log_VALUES(i).log_type       :='OK';
      
    EXCEPTION
    WHEN OTHERS THEN
      Log_VALUES(i).Process_Message:=SQLERRM;
      Log_VALUES(i).log_type       :='ERROR';
      lb_exception                 :=true;
    END;
    
  END LOOP;
  
  IF lb_exception THEN
    ROLLBACK;
  END IF;
  
  FOR i IN Log_VALUES.FIRST..Log_VALUES.LAST
  LOOP
    INSERT
    INTO @table_name
      (
        log_type,
        Update_query,
        Process_Message
      )
      VALUES
      (
        Log_VALUES(i).log_type,
        Log_VALUES(i).Update_query,
        Log_VALUES(i).Process_Message
      );
  END LOOP;
  
  COMMIT;
 
END;


上面的代码有长期运行的问题。该代码将准备动态更新查询并使用日志执行更新语句。请帮助优化此查询。先谢谢你。

r1wp621o

r1wp621o1#

最好使用这个:

ls_update_query := 
    'update '||LS_AGG_TABLE||' set ' || MFU_values(i).TARGET_COLUMNS|| ' = :TARGET_COLUMNS '||
     ' where trim(' ||MFU_values(i).SOURCE_COLUMN||') = :SOURCE_COLUMN '||
     ' and trim(PRODUCT_CATEGORY) = :PRODUCT_CATEGORY' ;

EXECUTE IMMEDIATE ls_update_query USING MFU_values(i).TARGET_VALUE, TRIM(MFU_values(i).SOURCE_VALUE), TRIM(MFU_values(i).Product_Category);

对于插入,请查看FORALL语句。

相关问题