ORA-01735: 在具有动态 SQL 的段上释放未使用 space 时无效的 ALTER TABLE 选项
ORA-01735: Invalid ALTER TABLE option when deallocated unused space on a segment with dynamic SQL
我开发了一个简单的打包程序,允许 space 未被段(HWM 以上)使用的免费。它接收作为参数的模式名称、table 的名称和 KEEP 子句e.
的值
当我 运行 使用 EXECUTE IMMEDIATE 语句的 DDL 语句时,它告诉我 ALTER 选项无效 。如果我 运行 来自普通终端的相同语句,这将正常工作。
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
程序定义如下:
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;
例如,当使用此参数执行过程时,结果语句将是这样的:
EXEC MANAGEMENT_OF_TABLES_AND_INDEX.RELEASE_UNUSED_SPACE('SERGIO11', 'EMPLOYEES');
ALTER TABLE SERGIO11.EMPLOYEES DEALLOCATE UNUSED;
我已明确向所有者用户授予 ALTER ANY TABLE 权限,该用户也是执行它的用户。
有谁知道问题出在哪里。提前致谢!!!
尝试删除此语句
v_deallocate_sql := v_deallocate_sql || ';';
所以你的句子应该是:
ALTER TABLE SERGIO11.EMPLOYEES DEALLOCATE UNUSED
我开发了一个简单的打包程序,允许 space 未被段(HWM 以上)使用的免费。它接收作为参数的模式名称、table 的名称和 KEEP 子句e.
的值当我 运行 使用 EXECUTE IMMEDIATE 语句的 DDL 语句时,它告诉我 ALTER 选项无效 。如果我 运行 来自普通终端的相同语句,这将正常工作。
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
程序定义如下:
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;
例如,当使用此参数执行过程时,结果语句将是这样的:
EXEC MANAGEMENT_OF_TABLES_AND_INDEX.RELEASE_UNUSED_SPACE('SERGIO11', 'EMPLOYEES');
ALTER TABLE SERGIO11.EMPLOYEES DEALLOCATE UNUSED;
我已明确向所有者用户授予 ALTER ANY TABLE 权限,该用户也是执行它的用户。
有谁知道问题出在哪里。提前致谢!!!
尝试删除此语句
v_deallocate_sql := v_deallocate_sql || ';';
所以你的句子应该是:
ALTER TABLE SERGIO11.EMPLOYEES DEALLOCATE UNUSED