运行此过程会出错。...尝试使用输入作为表名运行此过程并获取其空间使用情况统计信息...请帮助修复此问题
需要创建一个以表名作为输入并显示其空间详细信息(例如大小和行以及索引大小等)的过程
请帮助解决以下错误。
create or replace procedure sp_proc(input_owner IN VARCHAR2,input_table_name IN VARCHAR2)
as
segment_size_blocks NUMBER;
segment_size_bytes NUMBER;
used_blocks NUMBER;
used_bytes NUMBER;
expired_blocks NUMBER;
expired_bytes NUMBER;
unexpired_blocks NUMBER;
unexpired_bytes NUMBER;
total_blocks NUMBER;
total_bytes NUMBER;
unused_blocks NUMBER;
unused_bytes NUMBER;
last_ext_file_id NUMBER;
last_ext_blk_id NUMBER;
last_used_blk NUMBER;
result_table NVARCHAR2(128);
result_segment_type NVARCHAR2(128);
result_used_kb NUMBER;
result_unused_kb NUMBER;
result_total_kb NUMBER;
CURSOR cur;
begin
SELECT
s.segment_name AS segment_name,
s.owner AS segment_owner,
s.partition_name AS partition_name,
s.segment_type AS segment_type,
CASE WHEN s.segment_type IN ('TABLE', 'TABLE PARTITION', 'TABLE SUBPARTITION')
THEN s.segment_name
WHEN s.segment_type IN ('INDEX', 'INDEX PARTITION', 'INDEX SUBPARTITION')
THEN (SELECT i.table_name
FROM dba_indexes i
WHERE s.segment_name = i.index_name AND s.owner = i.owner)
WHEN s.segment_type IN ('LOBSEGMENT', 'LOB PARTITION')
THEN (SELECT l.table_name
FROM dba_lobs l
WHERE s.segment_name = l.segment_name AND s.owner = l.owner)
WHEN s.segment_type IN ('LOBINDEX')
THEN (SELECT l.table_name
FROM dba_lobs l
WHERE s.segment_name = l.index_name AND s.owner = l.owner)
ELSE 'Unknown'
END AS table_name,
s.bytes AS segment_bytes
FROM dba_segments s
WHERE owner = input_owner
and segment_name= input_table_name
ORDER BY table_name, segment_type;
dbms_output.put_line('name data(KB) unused(KB)');
FOR ro IN cur
LOOP
result_table := ro.table_name;
result_segment_type := ro.segment_type;
IF ro.segment_type IN ('TABLE', 'INDEX')
THEN
dbms_space.unused_space(
segment_owner => ro.segment_owner,
segment_name => ro.segment_name,
segment_type => ro.segment_type,
total_blocks => total_blocks,
total_bytes => total_bytes,
unused_blocks => unused_blocks,
unused_bytes => unused_bytes,
last_used_extent_file_id => last_ext_file_id,
last_used_extent_block_id => last_ext_blk_id,
last_used_block => last_used_blk);
result_used_kb := (total_bytes - unused_bytes) / 1024;
result_unused_kb := unused_bytes / 1024 ;
result_total_kb := total_bytes / 1024 ;
ELSIF ro.segment_type IN ('LOBSEGMENT')
THEN
dbms_space.space_usage(
segment_owner => ro.segment_owner,
segment_name => ro.segment_name,
segment_type => 'LOB',
partition_name => ro.partition_name,
segment_size_blocks => segment_size_blocks,
segment_size_bytes => segment_size_bytes,
used_blocks => used_blocks,
used_bytes => used_bytes,
expired_blocks => expired_blocks,
expired_bytes => expired_bytes,
unexpired_blocks => unexpired_blocks,
unexpired_bytes => unexpired_bytes
);
result_used_kb := used_bytes / 1024 ;
result_unused_kb := (segment_size_bytes - used_bytes) / 1024 ;
result_total_kb := segment_size_bytes / 1024;
ELSE
-- TODO ??
result_used_kb := ro.segment_bytes / 1024 ;
result_unused_kb := 0;
result_total_kb := result_used_kb + result_unused_kb;
END IF;
dbms_output.put_line(
RPAD(result_table, 30) ||
TO_CHAR(result_used_kb / 1024 , '999999999990D00')||
TO_CHAR(result_unused_kb / 1024 , '999999999990D00'));
END LOOP;
END;
LINE/COL ERROR
-------- -----------------------------------------------------------------
25/3 PL/SQL: Item ignored
25/3 PLS-00360: cursor declaration without body needs return type
27/5 PLS-00428: an INTO clause is expected in this SELECT statement
56/3 PL/SQL: Statement ignored
56/13 PLS-00320: the declaration of the type of this expression is
incomplete or malformed
在上面运行此过程将上述错误作为警告...
答案 0 :(得分:1)
您不能这样声明普通光标
CURSOR cur;
不指定查询或返回类型(通常为记录变量)
为使其简洁明了,请使用隐式游标循环。
CREATE OR REPLACE PROCEDURE sp_proc (
input_owner IN VARCHAR2,
input_table_name IN VARCHAR2
) AS
segment_size_blocks NUMBER;
segment_size_bytes NUMBER;
used_blocks NUMBER;
used_bytes NUMBER;
expired_blocks NUMBER;
expired_bytes NUMBER;
unexpired_blocks NUMBER;
unexpired_bytes NUMBER;
total_blocks NUMBER;
total_bytes NUMBER;
unused_blocks NUMBER;
unused_bytes NUMBER;
last_ext_file_id NUMBER;
last_ext_blk_id NUMBER;
last_used_blk NUMBER;
result_table NVARCHAR2(128);
result_segment_type NVARCHAR2(128);
result_used_kb NUMBER;
result_unused_kb NUMBER;
result_total_kb NUMBER;
BEGIN
dbms_output.put_line('name data(KB) unused(KB)');
FOR ro IN ( --implicit cursor loop
SELECT s.segment_name AS segment_name,
s.owner AS segment_owner,
s.partition_name AS partition_name,
s.segment_type AS segment_type,
CASE
WHEN s.segment_type IN (
'TABLE',
'TABLE PARTITION',
'TABLE SUBPARTITION'
) THEN s.segment_name
WHEN s.segment_type IN (
'INDEX',
'INDEX PARTITION',
'INDEX SUBPARTITION'
) THEN (
SELECT i.table_name
FROM dba_indexes i
WHERE s.segment_name = i.index_name AND s.owner = i.owner
)
WHEN s.segment_type IN (
'LOBSEGMENT',
'LOB PARTITION'
) THEN (
SELECT l.table_name
FROM dba_lobs l
WHERE s.segment_name = l.segment_name AND s.owner = l.owner
)
WHEN s.segment_type IN (
'LOBINDEX'
) THEN (
SELECT l.table_name
FROM dba_lobs l
WHERE s.segment_name = l.index_name AND s.owner = l.owner
)
ELSE 'Unknown'
END
AS table_name,
s.bytes AS segment_bytes
FROM dba_segments s
WHERE owner = input_owner AND segment_name = input_table_name
ORDER BY table_name,
segment_type
) LOOP
result_table := ro.table_name;
result_segment_type := ro.segment_type;
IF
ro.segment_type IN (
'TABLE',
'INDEX'
)
THEN
dbms_space.unused_space(segment_owner => ro.segment_owner,segment_name => ro.segment_name
,segment_type => ro.segment_type,total_blocks => total_blocks,total_bytes => total_bytes
,unused_blocks => unused_blocks,unused_bytes => unused_bytes,last_used_extent_file_id =>
last_ext_file_id,last_used_extent_block_id => last_ext_blk_id,last_used_block => last_used_blk
);
result_used_kb := ( total_bytes - unused_bytes ) / 1024;
result_unused_kb := unused_bytes / 1024;
result_total_kb := total_bytes / 1024;
ELSIF ro.segment_type IN (
'LOBSEGMENT'
) THEN
dbms_space.space_usage(segment_owner => ro.segment_owner,segment_name => ro.segment_name
,segment_type => 'LOB',partition_name => ro.partition_name,segment_size_blocks => segment_size_blocks
,segment_size_bytes => segment_size_bytes,used_blocks => used_blocks,used_bytes => used_bytes
,expired_blocks => expired_blocks,expired_bytes => expired_bytes,unexpired_blocks => unexpired_blocks
,unexpired_bytes => unexpired_bytes);
result_used_kb := used_bytes / 1024;
result_unused_kb := ( segment_size_bytes - used_bytes ) / 1024;
result_total_kb := segment_size_bytes / 1024;
ELSE
-- TODO ??
result_used_kb := ro.segment_bytes / 1024;
result_unused_kb := 0;
result_total_kb := result_used_kb + result_unused_kb;
END IF;
dbms_output.put_line(rpad(result_table,30) || TO_CHAR(result_used_kb / 1024,'999999999990D00'
) || TO_CHAR(result_unused_kb / 1024,'999999999990D00') );
END LOOP;
END;
/
编译很好
Procedure SP_PROC compiled