0

セグメント(HWMの上)で使用されていない空き領域を許可する単純なパッケージ化プロシージャを開発しました。スキーマ名、テーブル名、およびKEEP clausの値をパラメータとして受け取ります。ORA-01735:動的SQLでセグメント上の未使用領域を割当て解除すると、無効なALTER TABLEオプション

私はを使用してDDL文がIMMEDIATE EXECUTEステートメント実行すると、それはALTERオプションが無効であることを私に伝えます。私が正常な端末から同じステートメントを実行する場合、これは正しく動作します。

例えば
PROCEDURE RELEASE_UNUSED_SPACE(
      p_owner IN DBA_TABLES.OWNER%TYPE, 
      p_table IN DBA_TABLES.TABLE_NAME%TYPE, 
      p_keep IN NUMBER DEFAULT NULL, 
      p_unit IN VARCHAR2 DEFAULT 'M' 
     ) AS 
      UNAVAILABLE_UNIT EXCEPTION; 
      TYPE R_SEGMENT_BLOCKS_INFO IS RECORD (
       occupied_blocks DBA_SEGMENTS.BLOCKS%TYPE, 
       assigned_blocks DBA_SEGMENTS.BLOCKS%TYPE, 
       initial_extent DBA_SEGMENTS.INITIAL_EXTENT%TYPE 
      ); 

      v_segmentBlocksInfo R_SEGMENT_BLOCKS_INFO; 
      v_deallocate_sql VARCHAR2(100); 

     BEGIN 

      IF(p_owner IS NULL OR p_table IS NULL) THEN 
       RAISE INVALID_ARGUMENTS; 
      END IF; 

      IF (p_keep IS NOT NULL AND UPPER(p_unit) NOT IN ('M', 'K')) THEN 
       RAISE UNAVAILABLE_UNIT; 
      END IF; 

      SELECT T.BLOCKS, S.BLOCKS, CEIL(S.INITIAL_EXTENT/8000) 
      INTO v_segmentBlocksInfo 
      FROM DBA_TABLES T, DBA_SEGMENTS S 
      WHERE S.SEGMENT_NAME = T.TABLE_NAME AND S.OWNER = T.OWNER 
       AND S.OWNER = T.OWNER 
       AND T.TABLE_NAME = UPPER(p_table) AND T.OWNER = UPPER(p_owner); 

      PRINT_LINE('BLOQUES ASIGNADOS -> ' || v_segmentBlocksInfo.assigned_blocks); 
      PRINT_LINE('BLOQUES OCUPADOS -> ' || v_segmentBlocksInfo.occupied_blocks); 
      PRINT_LINE('TAMAÑO INICIAL -> ' || v_segmentBlocksInfo.initial_extent); 

      IF v_segmentBlocksInfo.occupied_blocks < v_segmentBlocksInfo.assigned_blocks THEN 
       v_deallocate_sql := 'ALTER TABLE ' || p_owner || '.' || p_table || ' DEALLOCATE UNUSED'; 
       IF p_keep IS NOT NULL THEN 
        v_deallocate_sql := v_deallocate_sql || ' KEEP ' || p_keep || 'M'; 
       END IF; 
       v_deallocate_sql := v_deallocate_sql || ';'; 
       PRINT_LINE('LIBERANDO ESPACIO ' || v_deallocate_sql); 
       EXECUTE IMMEDIATE v_deallocate_sql; 
      END IF; 

     EXCEPTION 
      WHEN NO_DATA_FOUND THEN 
       PRINT_LINE('TABLE ' || p_table || ' ON SCHEMA ' || p_owner || ' NOT EXISTS'); 
      WHEN UNAVAILABLE_UNIT THEN 
       PRINT_LINE('UNIT OF MEASURE NOT VALID. Only M or K is allowed'); 
      WHEN OTHERS THEN 
       PRINT_LINE('ERROR : ' || SQLCODE || 'MENSAJE: ' || SQLERRM); 
     END RELEASE_UNUSED_SPACE; 

これで手順を実行した文は、このパラメータになります:ここで

BLOQUES ASIGNADOS -> 8 
BLOQUES OCUPADOS -> 5 
TAMAÑO INICIAL -> 9 
LIBERANDO ESPACIO ALTER TABLE SERGIO11.EMPLOYEES DEALLOCATE UNUSED; 
ERROR : -1735MENSAJE: ORA-01735: opción ALTER TABLE no válida 

は、プロシージャの定義である

EXEC MANAGEMENT_OF_TABLES_AND_INDEX.RELEASE_UNUSED_SPACE('SERGIO11', 'EMPLOYEES'); 

ALTER TABLE SERGIO11.EMPLOYEES DEALLOCATE UNUSED; 

私が明示的に付与していますそれを実行するのと同じ所有者ユーザーにも、ALTER ANY TABLE権限を与えます。

問題が何であるかは誰にも分かります。前もって感謝します!!!。

答えて

2

は、だからあなたの文章があるべきこの文

v_deallocate_sql := v_deallocate_sql || ';'; 

を削除してみてください。

ALTER TABLE SERGIO11.EMPLOYEES DEALLOCATE UNUSED 
関連する問題