如果我们创建 DUAL 表,本地数据库会受到干扰吗?
请建议我?
create table DUAL
(
x varchar2(1)
);
不,您不能创建双表。DUAL 表归 SYS 所有,SYS 拥有数据字典,因此您无法创建它。
见维基
DUAL 表是一种特殊的单行表,默认情况下出现在所有 Oracle 数据库安装中。它适用于选择伪列,例如 SYSDATE 或 USER。该表有一个名为 DUMMY 的 VARCHAR2(1) 列,其值为“X”。
即使您尝试创建 DUAL 表,也会给您带来问题,因为每次 Oracle 引擎都必须确保您没有调用 SYS 双表。您还需要指定数据库和模式。这可能会导致 Oracle 引擎出现过多的歧义问题。Oracle 优化器知道 DUAL 所做的一切以及它应该做什么,然后它会根据这些来做事。
SQL 参考:
DUAL 是由 Oracle 数据库与数据字典一起自动创建的表。DUAL 在用户 SYS 的模式中,但所有用户都可以通过名称 DUAL 访问。它有一列 DUMMY,定义为 VARCHAR2(1),并包含一个值为 X 的行。从 DUAL 表中进行选择对于使用 SELECT 语句计算常量表达式很有用。因为 DUAL 只有一行,所以常数只返回一次。或者,您可以从任何表中选择一个常量、伪列或表达式,但该值将被返回与表中的行数一样多的次数。有关从 DUAL 中选择常量值的许多示例,请参阅“关于 SQL 函数”。
从 Oracle 数据库 10g 第 1 版开始,在计算不包含 DUMMY 列的表达式时,不对 DUAL 表执行逻辑 I/O。此优化在执行计划中列为 FAST DUAL。如果您从 DUAL 中选择 DUMMY 列,则不会进行此优化并且会发生逻辑 I/O。
如果我们创建 DUAL 表,本地数据库会受到干扰吗?
是的,当然,奇怪的事情可以而且将会发生。DUAL 归 SYS 所有。SYS 拥有数据字典,因此 DUAL 是数据字典的一部分。您永远不要通过 SQL 修改数据字典。
第一个问题是“如何保证自己的 DUAL 表中只有一行”?
这可以追溯到Steven Feuerstein的原始文章Self-Managing PL/SQL,他在其中解释了“使用您自己的 DUAL Table ”。但是,那是在 DUAL table 容易出现这种情况的时候。
但是,在最近的版本中,DUAL 表结构变得更加健壮,您不能拥有超过单行。这是一个证明:
SQL> conn sys@pdborcl as sysdba
Enter password:
Connected.
SQL> insert into dual select * from dual;
1 row created.
SQL> select * from dual;
D
-
X
我知道,很少有人会争辩说我们可以使用触发器或 ROWNUM =1 处理我们自己的 DUAL 表中的一行,但是,您很快就会意识到缺点。从 10g 开始就不需要了,因为 DUAL 表现在是一个内存结构,你不能像上面演示的那样向它添加一行。
想象一下,您创建了自己的 DUAL 表,并且在 PL/SQL 代码中使用对 DUAL 表的调用来获取 USER、SYSDATE、SYSTIMESTAMP 等。
这是取自 Oracle 数据库随附的 stdbody.sql 文件的代码:
1 FUNCTION USER
2 RETURN VARCHAR2
3 IS
4 c VARCHAR2 (255);
5 BEGIN
6 SELECT USER
7 INTO c
8 FROM SYS.DUAL;
9
10 RETURN c;
11 END;
如果您自己的 DUAL 表中有不止一行,则每次调用 PL/SQL 代码中的 USER 函数都会失败,并出现TOO_MANY_ROWS错误。
底线:所有关于使用自己的 DUAL 表的讨论在 10g 天之前都是有意义的。DUAL 表现在是一种健壮的内存结构,不允许向其中添加行。因此,使用您自己的 DUAL 表而不是 SYS.DUAL 是没有意义的。