oracle的dual是啥表,oracle中的dual表

DUAL表的用途

Dual 是 Oracle中的一个实际存在的表,任何用户均可读取,常用在没有目标表的Select语句块中

--查看当前连接用户

SQL> select user from dual;

USER

--------

SYSTEM

--查看当前日期、时间

sql> select sysdate from dual;

SYSDATE

---------

2012-5-22

sql> select to_char(sysdate,''yyyy-mm-dd hh24:mi:ss'') from dual;

TO_CHAR(SYSDATE,''YYYY-MM-DDHH2

------------------------------

2007-01-24 15:02:47

--当作计算器用

SQL> select 1+2 from dual;

1+2

----------

3

--查看序列值

SQL> create sequence aaa increment by 1 start with 1;

SQL> select aaa.nextval from dual;

NEXTVAL

----------

1

SQL> select aaa.currval from dual;

CURRVAL

----------

1

=======================================================================

关于DUAL表的测试与分析

DUAL就是个一行一列的表,如果你往里执行insert、delete、truncate 操作,

就会导致很多程序出问题。结果也因sql*plus、pl/sql dev等工具而异。

=======================================================================

查看DUAL是什么OBJECT

DUAL是属于SYS schema的一个表, 然后以PUBLIC SYNONYM的方式供其他数据库USER使用

SQL> select owner, object_name , object_type from dba_objects where object_name like '%DUAL%';

OWNER OBJECT_NAME OBJECT_TYPE

---- ------------ ------------------

SYS     DUAL       TABLE

PUBLIC  DUAL       SYNONYM

--查看表结构,只有一个字段DUMMY,为VARCHAR2(1)型

SQL> desc dual

Name Type Nullable Default Comments

----- ----------- -------- ------- --------

DUMMY VARCHAR2(1) Y

--DUAL表的结构:

CREATE TABLE "SYS"."DUAL"

(

"DUMMY" VARCHAR2(1)

)

PCTFREE 10

PCTUSED 40

INITRANS 1

MAXTRANS 255

NOCOMPRESS LOGGING

STORAGE(

INITIAL 16384

NEXT 1048576

MINEXTENTS 1

MAXEXTENTS 2147483645

PCTINCREASE 0

FREELISTS 1

FREELIST GROUPS 1

BUFFER_POOL DEFAULT)

TABLESPACE "SYSTEM"

DUAL表是建立在SYSTEM表空间的,第一是因为DUAL表是SYS这个用

户建的,本来默认的表空间就是SYSTEM;第二,把这个可能经常被查询的表

和用户表分开来存放,对于系统性能的是有好处的。

有了创建了表、创建了同义词还是不够的。DUAL在SYS这个Schema下面,

因此用别的用户登录是无法查询这个表的,因此还需要授权:

grant select on SYS.DUAL to PUBLIC with grant option;

将Select 权限授予公众。

事实上,DUAL表中的数据和oracle数据库环境有着十分重要的关系(ORACLE不会为此瘫痪,但是不少存储过程以

及一些查询将无法被正确执行)。

=======================================================================

DUAL 表行数问题

SQL> select count(*) from dual;

COUNT(*)

----------

1

SQL> select * from dual;

DUMMY

-----

X

--插入数据,再查询记录,只返回一行记

SQL> insert into dual values ('Y');

1 row created.

SQL> commit;

Commit complete.

SQL> insert into dual values ('X');

1 row created.

SQL> insert into dual values ('Z');

1 row created.

SQL> commit;

Commit complete.

SQL> select count(*) from dual;

COUNT(*)

----------

4

SQL> select * from dual;

DUMMY

-----

X        --这里查就剩下一行数据了

----------------------------------------------------------------------------

SQL> insert into dual values(''Y'');

1 行 已插入

SQL> commit;

提交完成

SQL> select * from dual;

DUMMY

-----

X

Y

SQL> select sysdate from dual;

SYSDATE

-----------

2012-5-22

2012-5-22

这个时候返回的是两条记录,这样同样会引起问题。在通过使用

SQL>select sysdate into v_sysdate from dual;

来获取时间或者其他信息的存储过程来说 ,ORACLE 会抛出TOO_MANY_ROWS(ORA-01422)异常。

----------------------------------------------------------------------------

--把表截掉

SQL> truncate table dual;

Table truncated.

SQL> select count(*) from dual;

COUNT(*)

----------

0

SQL> select * from dual;

no rows selected

SQL> select sysdate from dual;

no rows selected

--试着把DUAL表中的数据删除,看看会出现什么结果:

SQL> delete from dual;

1 行 已删除

SQL> select * from dual;

DUMMY

-----

SQL> select sysdate from dual;

SYSDATE

-----------

我们便取不到系统日期了。因为,sysdate是个函数,作用于每一个数据行。现在没有数据了,自然就不可能取出系统日期。

这个对于很多用:

SQL>select sysdate into v_sysdate from dual;

这种方式取系统时间以及其他信息的存储过程来说是致命的,因为,

ORACLE会马上抛出一个NO_DATA_FOUND(ORA-01403)的异常,即使异常

被捕获,存储过程也将无法正确完成要求的动作。

----------------------------------------------------------------------------

对于delete操作来说,oracle对dual表的操作做了一些内部处理,尽量保证dual表中只返回一条记录,

当然这些内部操作是不可见的

不管表内有多少记录(没有记录除外),oracle对于每次delete操作都只删除一条数据。

SQL> select count(*) from dual;

COUNT(*)

----------

2

SQL> delete from dual;

1 行 已删除

SQL> commit;

提交完成

SQL> select count(*) from dual;

COUNT(*)

----------

1

=======================================================================

Drop Dual table

DUAL表可以执行插入、更新、删除操作,还可以执行drop操作。但是不要去执行drop表的操作,否则会使系统

不能用,数据库起不了,会报Databasestartup crashes with ORA-1092错误。

DUAL表被"不幸"删除后的恢复:

(1)用sys用户登陆。

SQL> create pfile=‘d:\pfile.bak‘ from spfile

SQL> shutdown immediate

(2)创建DUAL表。

CREATE TABLE "SYS"."DUAL"

(

"DUMMY" VARCHAR2(1)

)

PCTFREE 10

PCTUSED 40

INITRANS 1

MAXTRANS 255

NOCOMPRESS LOGGING

STORAGE(

INITIAL 16384

NEXT 1048576

MINEXTENTS 1

MAXEXTENTS 2147483645

PCTINCREASE 0

FREELISTS 1

FREELIST GROUPS 1

BUFFER_POOL DEFAULT)

TABLESPACE "SYSTEM" ;

(3)授予公众SELECT权限(SQL如下,但不要给UPDATE,INSERT,DELETE权限)

sql> grant select on dual to Public;

sql> select * from dual;

(4)向DUAL表插入一条记录(仅此一条): insert into dual values('X');

sql> insert into dual values(?X‘);

(5)提交修改。

sql> commit;

最后:

SQL> shutdown immediate

SQL> startup

--OK, 下面就可以正常使用了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值