嗨,我们都知道DUAL
是SYS
的表,其他用户也有它的同义词。
但是当我开动以下命令时
create table dual(x varchar2(1));
有效。已创建名称为DUAL
的对象。
当已经有名称DUAL
的同义词时,我们如何创建另一个相同名称的对象? oracle为什么允许我们这样做。
答案 0 :(得分:7)
您可以创建一个名为DUAL
的表,因为表和 public 同义词具有不同的命名空间。有关详细信息,请参见《 Oracle SQL语言参考》的Database Object Names and Qualifiers章。
编辑:以说明该机制:
如果您以用户scott的身份创建自己的DUAL
表
CREATE TABLE dual (x VARCHAR2(1));
...然后它显示在数据字典中:
SELECT object_id, object_type, owner, object_name, namespace
FROM dba_objects
WHERE object_name='DUAL';
OBJECT_ID OBJECT_TYPE OWNER OBJECT_NAME NAMESPACE
142 TABLE SYS DUAL 1
143 SYNONYM PUBLIC DUAL 1
78138 TABLE SCOTT DUAL 1
因此,每个所有者和名称空间的名称都是唯一的。您不能在架构中添加另一个名为DUAL的表。您无法创建名为DUAL的私有同义词,但可以为其他对象中的架构创建自己的同义词。
请确保再次放下桌子。甚至简单的语句也不再起作用:
SELECT sysdate FROM DUAL;
--
DROP TABLE dual;
SELECT sysdate FROM DUAL;
01.07.2018
答案 1 :(得分:1)
我认为DUAL
在这里令人分心。当然,这是一个系统表,如果您对此感到困惑,会有副作用,所以请不要。但是,问题实际上是关于为什么 any 对象和具有相同名称的公共同义词之间没有名称空间冲突。例如,我可以在自己的架构中创建一个名为ALL_TABLES
或DBMS_OUTPUT
的表(如果我确实愿意的话)。或者,我可以创建一个名为MYDEMOTABLE
的表,然后为MYDEMOTABLE
创建一个公共同义词WILLIAM.MYDEMOTABLE
。
但是,您期望存在什么限制?已经存在一个表(由SYS
拥有)和一个名为PUBLIC
的公共同义词(由DUAL
拥有)。只要不属于SYS
或PUBLIC
的对象,就可以创建具有相同名称的第三个对象。
答案 2 :(得分:1)
我想我找到了一种方法来演示正在发生的事情(不使用DUAL
或任何其他SYS
对象;-):
如果两个用户创建一个具有相同名称的表,则这些表将按预期以自己的模式出现:
CREATE USER user_a IDENTIFIED BY user_a;
CREATE USER user_b IDENTIFIED BY user_b;
CREATE TABLE user_a.foo (x NUMBER);
CREATE TABLE user_b.foo (x NUMBER);
SELECT object_id, object_type, owner, object_name, namespace
FROM dba_objects
WHERE object_name='FOO';
OBJECT_ID OBJECT_TYPE OWNER OBJECT_NAME NAMESPACE
78225 TABLE USER_A FOO 1
78226 TABLE USER_B FOO 1
但是当其中一个创建公共同义词时(如SYS
对DUAL
表所做的操作),它最终以名为PUBLIC
的魔术模式出现:
CREATE PUBLIC SYNONYM foo FOR user_a.foo;
SELECT object_id, object_type, owner, object_name, namespace
FROM dba_objects
WHERE object_name='FOO';
OBJECT_ID OBJECT_TYPE OWNER OBJECT_NAME NAMESPACE
78225 TABLE USER_A FOO 1
78226 TABLE USER_B FOO 1
78156 SYNONYM PUBLIC FOO 1
因此,换句话说,公共同义词只是存在于模式PUBLIC
中的同义词。而且每个模式只能有一个表,视图,序列,包,同义词,并且名称相同。
答案 3 :(得分:0)
单个数据库中有多种模式。当您询问默认的DUAL
表时,该表实际上属于系统架构的'sys' Schema
。但是您的默认数据库架构为dbo
,这意味着在执行查询以创建DUAL表时,实际上是在名为dbo
的默认架构中创建的。
如果要检查其实际的双重存在,有很多检查方法。
"select * from sys.DUAL"
和"select * from dbo.DUAL"
之类的查询。在那里,您将看到两个不同的输出。"select * from sys.schemas"
中的所有架构。
"select * from sys.tables where name ='DUAL'";
结果将是具有两个不同架构ID的两个不同表。
希望这将帮助您了解架构基础。