4 oracle schema constraints ownership
在 Oracle 中,如果您尝试在语句中显式定义约束的架构,CREATE TABLE将会导致ORA-00904: : invalid identifier错误:
CREATE TABLE SCHEMA1.MY_TABLE
(
TABLE_ID NUMBER(5)
, FLAG VARCHAR2(1) DEFAULT 'F'
, CONSTRAINT SCHEMA1.MY_TABLE_PK PRIMARY KEY (TABLE_ID) -- Parser doesn't like 'SCHEMA1'
, CONSTRAINT SCHEMA1.MY_TABLE_FLAG_CK CHECK (FLAG IN ('T', 'F')) --Same issue
);
Run Code Online (Sandbox Code Playgroud)
这没什么大不了的,因为约束OWNER默认与声明中定义的架构相同CREATE TABLE(或者至少在您登录的架构中 - 我的帐户无权验证)。ALL_CONSTRAINTS这可以通过拉出或中的约束DBA_CONSTRAINTS并查看OWNER值(将读取SCHEMA1上面的两个约束)来确认。
但是,如果您随后在不同模式下使用第二个重复语句来跟进此语句:
CREATE TABLE SCHEMA2.MY_TABLE
(
TABLE_ID NUMBER(5)
, FLAG VARCHAR2(1) DEFAULT 'F'
, CONSTRAINT MY_TABLE_PK PRIMARY KEY (TABLE_ID) --This constraint already exists
, CONSTRAINT MY_TABLE_FLAG_CK CHECK (FLAG IN ('T', 'F')) --This one too
);
Run Code Online (Sandbox Code Playgroud)
这会导致ORA-00955: name is already used by an existing object错误。
我对约束的理解是,它们只是数据库上的另一个对象,我假设它们受到我熟悉的相同所有权规则的约束。但根据上述行为,很明显它们的行为与数据库中的大多数对象不同。
问题
对于上下文,我在工作中遇到了一个场景,我想在不同的模式下存储重复的名称(不要问......这是继承的重复,我只是想保持一致,直到我有资金进行重构)。现在,我意识到我可以非常简单地将模式添加到名称中并快速绕过这个问题,但这会以错误的方式摩擦我的强迫症,所以我想更好地理解为什么我不能做我想做的事情。
- - - - - - - - - - - - - - - 更新 - - - - - - - - - - --------
好吧……所以我是个傻瓜。请注意,在干净的环境下,上述情况无法重复。在尝试重现该问题后,我现在意识到发生了什么。
我目前正在清理一些 DDL 语句,为生产版本做准备。我不是这个环境中唯一的开发人员,我的离岸团队一直在这些相同的桌子上工作。我一直在编辑一些预先存在的 DDL 脚本,为生产版本做准备,并向一些CREATE TABLE语句添加了一些所需的约束。
看起来我DROP在运行第二条语句之前未能运行我的脚本SCHEMA2。我的困惑是因为我认为我收到错误是ORA-00955因为我添加了新的约束,而实际上这是因为SCHEMA2.MY_TABLE这个环境中已经存在了。由于我更改了约束名称,然后成功重新运行了所有脚本(因为在DROP重新测试之前我必须在所有模式中运行语句),所以导致了这种误诊。结果,我以为我观察到了不可预见的行为,而实际上我没有观察到。
感谢所有评论的人给我带来了光明!
您的问题中缺少的是运行脚本的用户。但这里有一个小实验。作为用户系统连接到数据库。我有可用于实验的模式 NGM42 和 NGM41。
CREATE TABLE NGM41.MY_TABLE
(
TABLE_ID NUMBER(5)
, FLAG VARCHAR2(1) DEFAULT 'F'
, CONSTRAINT MY_TABLE_PK PRIMARY KEY (TABLE_ID) -- Parser doesn't like 'SCHEMA1'
, CONSTRAINT MY_TABLE_FLAG_CK CHECK (FLAG IN ('T', 'F')) --Same issue
);
CREATE TABLE NGM42.MY_TABLE
(
TABLE_ID NUMBER(5)
, FLAG VARCHAR2(1) DEFAULT 'F'
, CONSTRAINT MY_TABLE_PK PRIMARY KEY (TABLE_ID)
, CONSTRAINT MY_TABLE_FLAG_CK CHECK (FLAG IN ('T', 'F'))
);
Run Code Online (Sandbox Code Playgroud)
两条语句均成功运行。那么约束发生了什么?
select owner,constraint_name from all_constraints
where constraint_name in ('MY_TABLE_PK','MY_TABLE_FLAG_CK')
NGM42 MY_TABLE_PK
NGM41 MY_TABLE_PK
NGM41 MY_TABLE_FLAG_CK
NGM42 MY_TABLE_FLAG_CK
Run Code Online (Sandbox Code Playgroud)
约束是在与表相同的架构中创建的。正如您所看到的,它们在数据库中不需要是全局唯一的。