您的位置:首页 > 数据库 > Oracle

oracle中dual表相关的知识(续一)

2009-05-06 18:18 573 查看
1、Asktom上的这篇文章给与了深入持续的讨论。
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1562813956388

2、Tom的评论:
There is internalized code that makes this happen. Code checks that ensure that a table scan of SYS.DUAL only returns one row. Svrmgrl behaviour is incorrect but this is now an obsolete product.
The base issue you should always remember and keep is: DUAL table should always have 1 ROW. Dual is a normal table with one dummy column of varchar2(1).
This is basically used from several applications as a pseudo table for getting results from a select statement that use functions like sysdate or other prebuilt or application functions.
If DUAL has no rows at all some applications (that use DUAL) may fail with NO_DATA_FOUND exception. If DUAL has more than 1 row then applications (that use DUAL) may fail with TOO_MANY_ROWS exception.
So DUAL should ALWAYS have 1 and only 1 row.
3、关闭数据库会出现一下情况,说明dual并不是简单的表
SQL> alter database close;

数据库已更改。

SQL> select * from dual;

ADDR INDX INST_ID D
-------- ---------- ---------- -
01B74DC8 0 1 X

4、Dual是字典表,因此您不应该试图去修改它。
Let me just start by saying -- DUAL is owned by SYS. SYS owns the data dictionary,
therefore DUAL is part of the data dictionary. You are not to modify the data dictionary
via SQL ever -- wierd things can and will happen -- you are just demonstrating some of
them. We can make many strange things happen in Oracle by updating the data dictionary.
It is neither recommend, supported nor a very good idea.
dual is just a convienence table. You don't need to use it, you can use anything you
want. The advantage to dual is the optimizer understands dual is a special one row, one
column table -- when you use it in queries, it uses this knowledge when developing the
plan.
You are updating the data dictionary. You should naturally expect very bad
things to happen.

5、dual表的由来
He says that he created a two rows table and called it dual because he wanted to duplicate easily one table.Since this table has lost one row but kept its name.

6、不要对序列使用from dual
a) NOT use dynamic sql when static sql could be used. why execute immediate????

b) NOT use a function to query dual to return a sequence

c) avoid using DUAL all together by putting s.nextval right into my insert:

insert into t ( pk, .... ) values ( s.nextval, .... );

and if I needed the value, use the returning clause:

insert into t ( pk, .... ) values (s.nextval, .... ) returning pk into l_pk;

7、解决dual中的列二义性。
select * from dual, dual;

would be the same as:

select dual.dummy, dual.dummy from dual, dual;

where as:

select * from dual, (select * from dual)

is the same as:

select dual.dummy, <anonymous>.dummy from dual, (select * from dual);

where anonymous is like "null" - no anonymous equates to anyother anonymous. by inlining the view
-- you "renamed" dual much like:

ops$tkyte@ORA9IR2> select * from dual, dual d2;

D D
- -
X X

9、执行计划的分析
-----------------------------
SQL>explain plan for select * from dual;
SQL>select * from table(dbms_xplan.display);
system stats are a measure of your disk speeds and cpu speeds. gathering stats on the
dictionary or optimizer dynamic sampleing (in 10g, stats on the dictionary are done for you)

in 8i, i wouldn't do stats on sys but it is supported if you have tested it and found benefit

in 9i, do it in test and fully test it first

in 10g, it is standard.

10、使用cursor_sharing来提高执行的效率,减少SQL的硬分析
SQL> alter session set cursor_sharing=exact;
Session altered.
SQL> select 'hi' from dual d1;
'H
--
hi
SQL> alter session set cursor_sharing=force;
Session altered.
SQL> select 'hi' from dual d2;
'HI'
--------------------------------
hi
SQL> alter session set cursor_sharing=exact;
Session altered.
SQL> select sql_text from v$sql where sql_text like 'select % from dual d%';

SQL_TEXT
-------------------------------------------------------------------------------
select sql_text from v$sql where sql_text like 'select % from dual d%'
select :"SYS_B_0" from dual d2
select 'hi' from dual d1
I would say that at the system level, cursor sharing should be exact. individual applications that "need" this crutch while they fix the bug they have (not using binds) can enable it as they need. But this is something you need to sit down and discuss with the person that set it, they must have had a good reason for doing so - and you'll need to understand why it is set to similar

11、访问Dual的性能
you are seeing the difference between a FULL scan and an INDEX scan. In order for the index scan to happen, you need to use CBO with stats.Billions of apps rely on DUAL. It is safe to say that EVERY Oracle application in the world relies on DUAL. Many sites do not yet fully use the CBO, they do not gather stats. If we took the above approach, all sites would be flung immediately into CBO mode as soon as they hit DUAL. The effects would be enormous, people would be really mad.We told people for I don't know how many years "internal -- going away, svrmgrl -- going away". they are still in a state of shock when the install 9i and internal is actually gone, svrmgrl actually doesn't exist. Can you imagine if all of a sudden the CBO was the default for many (but not all) queries?
Here is the classic example of backwards compatibility getting in the way of new advances.
Fortunately dual being so small and frequently access, all is cached.

12、所有与Dual有关的对象
select object_name, owner, object_type from dba_objects where object_name = 'DUAL';

13、制作一个时间段的返回
var levels number;
exec :levels := &levels;
set timing on
set autotrace traceonly
WITH x AS (SELECT LEVEL AS lev FROM dual CONNECT BY LEVEL <= :levels)
SELECT lev, TO_DATE('19900101','YYYYMMDD')+lev-1 AS dt FROM x;
/* now for model */
SELECT lev, dt
FROM dual
MODEL
DIMENSION BY (0 AS lev)
MEASURES (TO_DATE('19990101','YYYYMMDD') AS dt)
RULES (
dt[FOR lev FROM 0 TO :levels-1 INCREMENT 1] = dt[0] + CV(lev)
)
;
14、关于Dual的一些忠告

BUT -- changing DUAL like that globally = "potentially dangerous" and "definitely not something support would like to hear"

Best if you can set up a private synonym "dual" in the schema(s) you want to effect -- as few as
possible.

If you use the IOT -- all queries involving DUAL will go CBO (if they are not already)

If you use the x$dual -- well, it's an X$ table and might have other unanticipate side effects I
haven't thought about yet.

If you do it - make sure you can back it out.

15、关于Object $的建议
If you are querying obj$ and the type number = 10, thats a "NON-EXISTENT" trick object we set up
when you reference a synonym in your code. we use it to track dependencies.

Get in the habit of ignore the obj$ table and all SYS.tables -- in 9i, we make it really hard to
query them by default and the views are what you should use day to day.

can you show me how you are using sys_context?

in plsql, it is most performant to use plsql variables.

16.

附1,WinXP+Oralce9.2.0.1.0的Dual表查询测试:
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup nomount;
ORACLE instance started.

Total System Global Area 97589952 bytes
Fixed Size 453312 bytes
Variable Size 62914560 bytes
Database Buffers 33554432 bytes
Redo Buffers 667648 bytes
SQL> select * from dual;

ADDR INDX INST_ID DU
-------- ---------- ---------- --
01B74DC8 0 1 X

SQL> select status from v$instance;

STATUS
------------------------
STARTED

SQL> alter database mount;

数据库已更改。

SQL> select * from dual;

ADDR INDX INST_ID D
-------- ---------- ---------- -
01B74DC8 0 1 X

SQL> select status from v$instance;

STATUS
------------------------
MOUNTED

SQL> alter database open;

数据库已更改。

SQL> select * from dual;

D
-
X

SQL> select status from v$instance;

STATUS
------------
OPEN

SQL> alter database close;

数据库已更改。

SQL> select * from dual;

ADDR INDX INST_ID D
-------- ---------- ---------- -
01B74DC8 0 1 X

SQL> select status from v$instance;

STATUS
------------
MOUNTED

SQL> alter database dismount;

数据库已更改。

SQL> select * from dual;

ADDR INDX INST_ID D
-------- ---------- ---------- -
01B74DC8 0 1 X

SQL> alter session set nls_language=american;

Session altered.

SQL> shutdown;
ORA-01507: database not mounted

ORACLE 例程已经关闭。
SQL>
附2.实用context的测试
SQL> create or replace context my_ctx using p
2 /

上下文已创建。

SQL> create or replace procedure p ( p_name in varchar2, p_val in varchar2 )
2 as
3 begin
4 dbms_session.set_context( 'my_ctx', p_name, p_val );
5 end;
6 /

过程已创建。

SQL> exec p( 'x1', 'a' );

PL/SQL 过程已成功完成。

SQL> exec p( 'x2', 'b' );

PL/SQL 过程已成功完成。

SQL> exec p( 'x3', 'c' );

PL/SQL 过程已成功完成。

SQL> create or replace procedure p1
2 as
3 x1 varchar2(5) default sys_context( 'my_ctx', 'x1' );
4 x2 varchar2(5) default sys_context( 'my_ctx', 'x2' );
5 x3 varchar2(5) default sys_context( 'my_ctx', 'x3' );
6 begin
7 null;
8 end;
9 /

过程已创建。

SQL> create or replace procedure p2
2 as
3 x1 varchar2(5);
4 x2 varchar2(5);
5 x3 varchar2(5);
6 begin
7 select sys_context( 'my_ctx', 'x1' ), sys_context( 'my_ctx', 'x2' ), sys_context(
8 'my_ctx', 'x3' )
9 into x1, x2, x3
10 from dual;
11 end;
12 /

过程已创建。

SQL> exec runStats_pkg.rs_start

PL/SQL 过程已成功完成。

SQL> exec begin for i in 1 .. 10000 loop p1; end loop; end;

PL/SQL 过程已成功完成。

SQL> exec runStats_pkg.rs_middle

PL/SQL 过程已成功完成。

SQL> exec begin for i in 1 .. 10000 loop p2; end loop; end;

PL/SQL 过程已成功完成。

SQL> exec runStats_pkg.rs_stop(10000)
Run1 ran in 1181 hsecs
Run2 ran in 1454 hsecs
run 1 ran in 81.22% of the time

Name Run1 Run2 Diff
STAT...recursive calls 30,001 10,002 -19,999
STAT...buffer is not pinned co 30,000 10,000 -20,000
STAT...execute count 30,005 10,005 -20,000
STAT...table scan blocks gotte 30,000 10,000 -20,000
STAT...table scans (short tabl 30,000 10,000 -20,000
STAT...table scan rows gotten 30,000 10,000 -20,000
STAT...no work - consistent re 30,000 10,000 -20,000
LATCH.shared pool 30,128 10,108 -20,020
LATCH.library cache pin 60,079 20,063 -40,016
LATCH.library cache 60,147 20,124 -40,023
STAT...session logical reads 90,561 30,569 -59,992
STAT...consistent gets 90,014 30,016 -59,998
STAT...calls to get snapshot s 90,001 30,001 -60,000
LATCH.cache buffers chains 182,792 62,659 -120,133

Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
334,691 114,209 -220,482 293.05%

PL/SQL 过程已成功完成。

SQL> spool off;
附3.dual的IOT测试
SQL> create table dual_iot ( dummy primary key ) organization index
2 as
3 select * from dual;

表已创建。

SQL> analyze table dual_iot compute statistics
2 /

表已分析。

SQL> create or replace view dual_view
2 as
3 select dummy from x$dual;

视图已建立。

SQL> grant select on dual_view to public
2 /

授权成功。

SQL> create public synonym dual_view for dual_view
2 /

同义词已创建。

SQL> exec runStats_pkg.rs_start

PL/SQL 过程已成功完成。

SQL> declare
2 l_cnt number;
3 begin
4 for i in 1 .. 50000
5 loop
6 select count(*) into l_cnt from dual;
7 end loop;
8 end;
9 /

PL/SQL 过程已成功完成。

SQL> exec runStats_pkg.rs_middle

PL/SQL 过程已成功完成。

SQL> declare
2 l_cnt number;
3 begin
4 for i in 1 .. 50000
5 loop
6 select count(*) into l_cnt from dual_iot;
7 end loop;
8 end;
9 /

PL/SQL 过程已成功完成。

SQL> exec runStats_pkg.rs_stop(10000)
Run1 ran in 2622 hsecs
Run2 ran in 3163 hsecs
run 1 ran in 82.9% of the time

Name Run1 Run2 Diff
STAT...no work - consistent re 50,000 4 -49,996
STAT...buffer is not pinned co 50,000 1 -49,999
STAT...table scan blocks gotte 50,000 0 -50,000
STAT...table scans (short tabl 50,000 0 -50,000
STAT...table scan rows gotten 50,000 0 -50,000
STAT...index scans kdiixs1 0 50,006 50,006
STAT...shared hash latch upgra 0 50,006 50,006
STAT...session logical reads 150,561 50,612 -99,949
STAT...consistent gets 150,014 50,039 -99,975
STAT...calls to get snapshot s 150,001 50,016 -99,985
LATCH.cache buffers chains 302,651 102,797 -199,854

Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
554,648 355,846 -198,802 155.87%

PL/SQL 过程已成功完成。

SQL> exec runStats_pkg.rs_start

PL/SQL 过程已成功完成。

SQL> declare
2 l_cnt number;
3 begin
4 for i in 1 .. 50000
5 loop
6 select count(*) into l_cnt from dual_iot;
7 end loop;
8 end;
9 /

PL/SQL 过程已成功完成。

SQL> exec runStats_pkg.rs_middle

PL/SQL 过程已成功完成。

SQL> declare
2 l_cnt number;
3 begin
4 for i in 1 .. 50000
5 loop
6 select count(*) into l_cnt from dual_view;
7 end loop;
8 end;
9 /

PL/SQL 过程已成功完成。

SQL> exec runStats_pkg.rs_stop(10000)
Run1 ran in 2685 hsecs
Run2 ran in 2574 hsecs
run 1 ran in 104.31% of the time

Name Run1 Run2 Diff
STAT...session logical reads 50,567 674 -49,893
STAT...consistent gets 50,016 69 -49,947
STAT...index scans kdiixs1 50,000 11 -49,989
STAT...shared hash latch upgra 50,000 11 -49,989
LATCH.cache buffers chains 102,655 2,979 -99,676

Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
354,745 255,887 -98,858 138.63%

PL/SQL 过程已成功完成。

SQL> spool off

附4.Tom的使用分析脚本
create or replace view stats
as select 'STAT...' || a.name name, b.value
from v$statname a, v$mystat b
where a.statistic# = b.statistic#
union all
select 'LATCH.' || name, gets
from v$latch;
create global temporary table run_stats
( runid varchar2(15),
name varchar2(80),
value int )
on commit preserve rows;

create or replace package runstats_pkg
as
procedure rs_start;
procedure rs_middle;
procedure rs_stop( p_difference_threshold in number default 0 );
end;
/
create or replace package body runstats_pkg
as

g_start number;
g_run1 number;
g_run2 number;

procedure rs_start
is
begin
delete from run_stats;

insert into run_stats
select 'before', stats.* from stats;

g_start := dbms_utility.get_time;
end;

procedure rs_middle
is
begin
g_run1 := (dbms_utility.get_time-g_start);

insert into run_stats
select 'after 1', stats.* from stats;
g_start := dbms_utility.get_time;

end;

procedure rs_stop(p_difference_threshold in number default 0)
is
begin
g_run2 := (dbms_utility.get_time-g_start);

dbms_output.put_line
( 'Run1 ran in ' || g_run1 || ' hsecs' );
dbms_output.put_line
( 'Run2 ran in ' || g_run2 || ' hsecs' );
dbms_output.put_line
( 'run 1 ran in ' || round(g_run1/g_run2*100,2) ||
'% of the time' );
dbms_output.put_line( chr(9) );

insert into run_stats
select 'after 2', stats.* from stats;

dbms_output.put_line
( rpad( 'Name', 30 ) || lpad( 'Run1', 10 ) ||
lpad( 'Run2', 10 ) || lpad( 'Diff', 10 ) );

for x in
( select rpad( a.name, 30 ) ||
to_char( b.value-a.value, '9,999,999' ) ||
to_char( c.value-b.value, '9,999,999' ) ||
to_char( ( (c.value-b.value)-(b.value-a.value)), '9,999,999' ) data
from run_stats a, run_stats b, run_stats c
where a.name = b.name
and b.name = c.name
and a.runid = 'before'
and b.runid = 'after 1'
and c.runid = 'after 2'
and (c.value-a.value) > 0
and abs( (c.value-b.value) - (b.value-a.value) )
> p_difference_threshold
order by abs( (c.value-b.value)-(b.value-a.value))
) loop
dbms_output.put_line( x.data );
end loop;

dbms_output.put_line( chr(9) );
dbms_output.put_line
( 'Run1 latches total versus runs -- difference and pct' );
dbms_output.put_line
( lpad( 'Run1', 10 ) || lpad( 'Run2', 10 ) ||
lpad( 'Diff', 10 ) || lpad( 'Pct', 8 ) );

for x in
( select to_char( run1, '9,999,999' ) ||
to_char( run2, '9,999,999' ) ||
to_char( diff, '9,999,999' ) ||
to_char( round( run1/run2*100,2 ), '999.99' ) || '%' data
from ( select sum(b.value-a.value) run1, sum(c.value-b.value) run2,
sum( (c.value-b.value)-(b.value-a.value)) diff
from run_stats a, run_stats b, run_stats c
where a.name = b.name
and b.name = c.name
and a.runid = 'before'
and b.runid = 'after 1'
and c.runid = 'after 2'
and a.name like 'LATCH%'
)
) loop
dbms_output.put_line( x.data );
end loop;
end;

end;
/

create or replace procedure show_space
( p_segname in varchar2,
p_owner in varchar2 default user,
p_type in varchar2 default 'TABLE',
p_partition in varchar2 default NULL )
-- this procedure uses authid current user so it can query DBA_*
-- views using privileges from a ROLE, and so it can be installed
-- once per database, instead of once per user who wanted to use it
authid current_user
as
l_free_blks number;
l_total_blocks number;
l_total_bytes number;
l_unused_blocks number;
l_unused_bytes number;
l_LastUsedExtFileId number;
l_LastUsedExtBlockId number;
l_LAST_USED_BLOCK number;
l_segment_space_mgmt varchar2(255);
l_unformatted_blocks number;
l_unformatted_bytes number;
l_fs1_blocks number; l_fs1_bytes number;
l_fs2_blocks number; l_fs2_bytes number;
l_fs3_blocks number; l_fs3_bytes number;
l_fs4_blocks number; l_fs4_bytes number;
l_full_blocks number; l_full_bytes number;
-- inline procedure to print out numbers nicely formatted
-- with a simple label
procedure p( p_label in varchar2, p_num in number )
is
begin
dbms_output.put_line( rpad(p_label,40,'.') ||
to_char(p_num,'999,999,999,999') );
end;
begin
-- this query is executed dynamically in order to allow this procedure
-- to be created by a user who has access to DBA_SEGMENTS/TABLESPACES
-- via a role as is customary.
-- NOTE: at runtime, the invoker MUST have access to these two
-- views!
-- this query determines if the object is an ASSM object or not
begin
execute immediate
'select ts.segment_space_management
from dba_segments seg, dba_tablespaces ts
where seg.segment_name = <img src="images/smilies/13.gif" smilieid="207" border="0" alt="" />_segname
and (<img src="images/smilies/13.gif" smilieid="207" border="0" alt="" />_partition is null or
seg.partition_name = <img src="images/smilies/13.gif" smilieid="207" border="0" alt="" />_partition)
and seg.owner = <img src="images/smilies/13.gif" smilieid="207" border="0" alt="" />_owner
and seg.tablespace_name = ts.tablespace_name'
into l_segment_space_mgmt
using p_segname, p_partition, p_partition, p_owner;
exception
when too_many_rows then
dbms_output.put_line
( 'This must be a partitioned table, use p_partition => ');
return;
end;
-- if the object is in an ASSM tablespace, we must use this API
-- call to get space information, otherwise we use the FREE_BLOCKS
-- API for the user-managed segments
if l_segment_space_mgmt = 'AUTO'
then
dbms_space.space_usage
( p_owner, p_segname, p_type, l_unformatted_blocks,
l_unformatted_bytes, l_fs1_blocks, l_fs1_bytes,
l_fs2_blocks, l_fs2_bytes, l_fs3_blocks, l_fs3_bytes,
l_fs4_blocks, l_fs4_bytes, l_full_blocks, l_full_bytes, p_partition);
p( 'Unformatted Blocks ', l_unformatted_blocks );
p( 'FS1 Blocks (0-25) ', l_fs1_blocks );
p( 'FS2 Blocks (25-50) ', l_fs2_blocks );
p( 'FS3 Blocks (50-75) ', l_fs3_blocks );
p( 'FS4 Blocks (75-100)', l_fs4_blocks );
p( 'Full Blocks ', l_full_blocks );
else
dbms_space.free_blocks(
segment_owner => p_owner,
segment_name => p_segname,
segment_type => p_type,
freelist_group_id => 0,
free_blks => l_free_blks);
p( 'Free Blocks', l_free_blks );
end if;
-- and then the unused space API call to get the rest of the
-- information
dbms_space.unused_space
( segment_owner => p_owner,
segment_name => p_segname,
segment_type => p_type,
partition_name => p_partition,
total_blocks => l_total_blocks,
total_bytes => l_total_bytes,
unused_blocks => l_unused_blocks,
unused_bytes => l_unused_bytes,
LAST_USED_EXTENT_FILE_ID => l_LastUsedExtFileId,
LAST_USED_EXTENT_BLOCK_ID => l_LastUsedExtBlockId,
LAST_USED_BLOCK => l_LAST_USED_BLOCK );
p( 'Total Blocks', l_total_blocks );
p( 'Total Bytes', l_total_bytes );
p( 'Total MBytes', trunc(l_total_bytes/1024/1024) );
p( 'Unused Blocks', l_unused_blocks );
p( 'Unused Bytes', l_unused_bytes );
p( 'Last Used Ext FileId', l_LastUsedExtFileId );
p( 'Last Used Ext BlockId', l_LastUsedExtBlockId );
p( 'Last Used Block', l_LAST_USED_BLOCK );
end;
/
--------------------------------------------------------------------------------------
PHP code:--------------------------------------------------------------------------------
truncate table te1;
truncate table te2;
exec runstats_pkg.rs_start;
insert into te1 select * from cj603;
commit;
exec runstats_pkg.rs_middle;
begin
for x in ( select * from cj603 )
loop
insert into te2 values X;
end loop;
commit;
end;
/
exec runstats_pkg.rs_stop(80000);
Run1 ran in 152 hsecs
Run2 ran in 564 hsecs
run 1 ran in 26.95% of the time

Name Run1 Run2 Diff
STAT...consistent gets 2,729 83,446 80,717
STAT...table scan blocks gotte 936 82,352 81,416
STAT...no work - consistent re 1,024 82,448 81,424
STAT...buffer is not pinned co 1,090 82,518 81,428
STAT...calls to get snapshot s 1,082 82,514 81,432
STAT...db block gets 10,250 91,766 81,516
STAT...redo entries 5,846 87,801 81,955
LATCH.redo allocation 5,931 88,063 82,132
STAT...execute count 50 82,375 82,325
LATCH.shared pool 284 82,749 82,465
STAT...session logical reads 12,979 175,212 162,233
STAT...db block changes 8,297 171,591 163,294
STAT...recursive calls 464 165,144 164,680
LATCH.library cache pin 409 165,115 164,706
LATCH.library cache 582 165,373 164,791
LATCH.cache buffers chains 39,700 610,752 571,052
STAT...redo size 7,531,664####################

Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
54,604 1,133,573 1,078,969 4.82%

PL/SQL 过程已成功完成。

lt@IBMLT> exec show_space( 'TE2');
Unformatted Blocks ..................... 0
FS1 Blocks (0-25) ..................... 0
FS2 Blocks (25-50) ..................... 0
FS3 Blocks (50-75) ..................... 1
FS4 Blocks (75-100)..................... 32
Full Blocks ..................... 903
Total Blocks............................ 1,024
Total Bytes............................. 8,388,608
Total MBytes............................ 8
Unused Blocks........................... 64
Unused Bytes............................ 524,288
Last Used Ext FileId.................... 12
Last Used Ext BlockId................... 5,640
Last Used Block......................... 64

PL/SQL 过程已成功完成。

lt@IBMLT> exec show_space( 'TE1');
Unformatted Blocks ..................... 0
FS1 Blocks (0-25) ..................... 0
FS2 Blocks (25-50) ..................... 0
FS3 Blocks (50-75) ..................... 1
FS4 Blocks (75-100)..................... 32
Full Blocks ..................... 903
Total Blocks............................ 1,024
Total Bytes............................. 8,388,608
Total MBytes............................ 8
Unused Blocks........................... 64
Unused Bytes............................ 524,288
Last Used Ext FileId.................... 12
Last Used Ext BlockId................... 4,616
Last Used Block......................... 64

PL/SQL 过程已成功完成。
------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: