Comment créer deux objets avec le même nom dans le même schéma - How to create two objects with the same name in the same schema
Introduction
Quand vous débutez en tant que DBA Oracle, on vous dit qu'il n'est pas possible de créer, pour un même user, deux objets avec le même nom. Nous allons voir que c'est faux, la vraie règle est "Deux objets ne peuvent pas avoir le même nom dans un même schéma s'ils appartiennent au même namespace".
Petit rappel : le User est l'utilisateur qui se connecte à la base, le Schéma est l'espace du User connecté et l'ensemble des objets qu'il a créé alors que le namespace est une catégorie pour ranger les objets par leur type.
Points d'attention
NA.
Base de tests
N'importe quelle base Oracle.
Exemples
============================================================================================
Création de deux objets avec le même nom dans le même schéma
============================================================================================
Pour le user HR, nous avons une table de nom COUNTRIES et il est impossible de créer une table ou une vue de même nom pour ce user.
SQL> show user
USER is "HR"
SQL> select * from cat order by table_name
TABLE_NAME TABLE_TYPE
------------------------------ -----------
COUNTRIES TABLE
DEPARTMENTS TABLE
DEPARTMENTS_SEQ SEQUENCE
EMPLOYEES TABLE
EMPLOYEES_SEQ SEQUENCE
EMP_DETAILS_VIEW VIEW
JOBS TABLE
JOB_HISTORY TABLE
LOCATIONS TABLE
LOCATIONS_SEQ SEQUENCE
REGIONS TABLE
TEST_OBJ01 TABLE
TEST_OBJ02 TABLE
13 rows selected.
SQL> create table COUNTRIES (ID NUMBER);
create table COUNTRIES (ID NUMBER)
*
ERROR at line 1:
ORA-00955: name is already used by an existing object
SQL> create view COUNTRIES as select * from all_objects;
create view COUNTRIES as select * from all_objects
*
ERROR at line 1:
ORA-00955: name is already used by an existing object
Néanmoins il est possible de créer un objet avec le même nom mais dans un schéma différent.
SQL> select owner, object_name, object_type from dba_objects where object_name = 'COUNTRIES';
OWNER OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------------------ ------------------------------
SYSTEM COUNTRIES TABLE
HR COUNTRIES TABLE
HRREST COUNTRIES TABLE
HRTEST COUNTRIES TABLE
Et c'est là qu'intervient la notion de namespace!
Je remplace le CREATE TABLE par un CREATE INDEX et... voilà, pas de message d'erreur!
Nous avons pour le même user deux objets de même nom, de type différent ET qui appartiennent à deux namespaces différents, c'est pourquoi Oracle permet cette création alors que les tables et vues appartiennent au même namespace.
SQL> create index COUNTRIES on JOB_HISTORY(END_DATE);
Index created.
SQL> select owner, object_name, object_type from dba_objects where object_name = 'COUNTRIES' and owner = 'HR'
OWNER OBJECT_NAME OBJECT_TYPE
------------------------------ ------------------------------ ------------------------------
HR COUNTRIES TABLE
HR COUNTRIES INDEX
Attention aux SELECT dans DBA_OBJECTS, surtout en PL/SQL
Le corollaire de ce que nous venons de voir, c'est que quand on fait un SELECT dans DBA_OBJECTS pour avoir des infos sur un objet, il faut préciser son nom, bien sur, son propriétaire ET son type sinon le SELECT peut planter, surtout s'il s'agit d'un programme PL/SQL. En PL/SQL il faut faire un SELECT colonnes INTO variables; si on a un SELECT qui retourne au moins deux enregistrements au lieu de un, il faut que les variables soient de type tableau sinon le SELECT échoue!
============================================================================================
Liste des namespaces d'une base 12c
============================================================================================
Liste des namespaces avec les types d'objets
Pour avoir la liste des namespaces et des types d'objets associés, il suffit d'interroger DBA_OBJECTS.
Nous constatons que dans le namespace 1 se retrouvent les tables et les vues mais que les index appartiennent au namespace 4.
SQL> clear col
SQL> clear breaks
SQL> set linesize 150 pagesize 5000
SQL> col owner format A20
SQL> col table_name format A30
SQL> col column_name format A25
SQL> col data_type format A20
SQL> break on namespace
SQL> select NAMESPACE, OBJECT_TYPE from DBA_OBJECTS group by NAMESPACE, OBJECT_TYPE order by NAMESPACE, OBJECT_TYPE;
NAMESPACE OBJECT_TYPE
---------- -----------------------
1 DESTINATION
FUNCTION
INDEXTYPE
JAVA CLASS
JOB
JOB CLASS
LIBRARY
OPERATOR
PACKAGE
PROCEDURE
PROGRAM
SCHEDULE
SCHEDULER GROUP
SEQUENCE
SYNONYM
TABLE
TABLE PARTITION
TABLE SUBPARTITION
TYPE
VIEW
WINDOW
2 PACKAGE BODY
TYPE BODY
3 TRIGGER
4 INDEX
INDEX PARTITION
5 CLUSTER
8 LOB
LOB PARTITION
9 DIRECTORY
10 QUEUE
13 JAVA SOURCE
14 JAVA RESOURCE
19 REWRITE EQUIVALENCE
21 CONTEXT
23 RULE SET
24 CONSUMER GROUP
RESOURCE PLAN
25 XML SCHEMA
32 JAVA DATA
36 RULE
38 EVALUATION CONTEXT
51 UNDEFINED
52 UNDEFINED
64 EDITION
93 UNIFIED AUDIT POLICY
DATABASE LINK
47 rows selected.
La liste comprends 22 namespaces différents, identifiés uniquement par un numéro et pas par un libellé.
Liste des namespaces : 1, 2, 3, 4,5, 8, 9, 10, 13, 14, 19, 21, 23, 24, 25, 32, 36, 38, 51, 52, 64, 93
A noter, mais le premier ordre SQL ne le montre pas à cause du break, que les dblinks ne sont associés à aucun namespace.
SQL> select distinct coalesce(namespace,0) from dba_objects where object_type = 'DATABASE LINK';
COALESCE(NAMESPACE,0)
---------------------
0
Liste des tables avec une colonne %NAMESPACE%
Est-ce que le libellé pour les namespaces existe dans une table du dictionnaire de données? Voyons combien de tables ont une colonne avec NAMESPACE dans le nom. Aïe, il y en a 165... certaines colonnes sont de type NUMBER, d'autres de type VARCHAR2, NVARCHAR2.
SQL> break on owner skip 1 on table_name
SQL> select owner, table_name, COLUMN_NAME, DATA_TYPE from dba_tab_cols where COLUMN_NAME like
OWNER TABLE_NAME COLUMN_NAME DATA_TYPE
-------------------- ------------------------------ -------------------------
APEX_050100 APEX_APPLICATION_AUTH RAS_NAMESPACES VARCHAR2
WWV_FLOW_AUTHENTICATIONS RAS_NAMESPACES VARCHAR2
DVSYS DBA_DV_FACTOR NAMESPACE VARCHAR2
NAMESPACE_ATTRIBUTE VARCHAR2
DV$FACTOR NAMESPACE_ATTRIBUTE VARCHAR2
NAMESPACE VARCHAR2
FACTOR$ NAMESPACE_ATTRIBUTE VARCHAR2
NAMESPACE VARCHAR2
MDSYS RDF_PARAM$ NAMESPACE VARCHAR2
RDF_PARAM$_TBL NAMESPACE VARCHAR2
RDF_PARAMETER NAMESPACE VARCHAR2
SRSNAMESPACE_TABLE SRSNAMESPACE VARCHAR2
WFS_FEATURETYPE$ NAMESPACEPREFIX VARCHAR2
NAMESPACEURL VARCHAR2
WFS_FEATURETYPENESTEDSDOS$ OBJNAMESPACE VARCHAR2
WFS_FEATURETYPEXMLCOLINFO$ FTNAMESPACEURL VARCHAR2
SYS ALL_CONTEXT NAMESPACE VARCHAR2
ALL_OBJECTS NAMESPACE NUMBER
ALL_OBJECTS_AE NAMESPACE NUMBER
ALL_POLICY_ATTRIBUTES NAMESPACE VARCHAR2
ALL_POLICY_CONTEXTS NAMESPACE VARCHAR2
ALL_PROBE_OBJECTS NAMESPACE NUMBER
ALL_XML_SCHEMA_ATTRIBUTES TARGET_NAMESPACE VARCHAR2
ALL_XML_SCHEMA_COMPLEX_TYPES BASE_TARGET_NAMESPACE VARCHAR2
TARGET_NAMESPACE VARCHAR2
ALL_XML_SCHEMA_ELEMENTS TARGET_NAMESPACE VARCHAR2
ALL_XML_SCHEMA_NAMESPACES TARGET_NAMESPACE VARCHAR2
ALL_XML_SCHEMA_SIMPLE_TYPES TARGET_NAMESPACE VARCHAR2
ALL_XML_SCHEMA_SUBSTGRP_HEAD TARGET_NAMESPACE VARCHAR2
ALL_XML_SCHEMA_SUBSTGRP_MBRS TARGET_NAMESPACE VARCHAR2
HEAD_TARGET_NAMESPACE VARCHAR2
AUDIT_UNIFIED_CONTEXTS NAMESPACE VARCHAR2
AUD_CONTEXT$ NAMESPACE VARCHAR2
AWR_PDB_LIBRARYCACHE NAMESPACE VARCHAR2
AWR_ROOT_LIBRARYCACHE NAMESPACE VARCHAR2
CDB_CONTEXT NAMESPACE VARCHAR2
CDB_GLOBAL_CONTEXT NAMESPACE VARCHAR2
CDB_HIST_LIBRARYCACHE NAMESPACE VARCHAR2
CDB_INVALID_OBJECTS NAMESPACE NUMBER
CDB_OBJECTS NAMESPACE NUMBER
CDB_OBJECTS_AE NAMESPACE NUMBER
CDB_POLICY_ATTRIBUTES NAMESPACE VARCHAR2
CDB_POLICY_CONTEXTS NAMESPACE VARCHAR2
CDB_REGISTRY NAMESPACE VARCHAR2
CDB_REGISTRY_DEPENDENCIES REQ_NAMESPACE VARCHAR2
NAMESPACE VARCHAR2
CDB_REGISTRY_HIERARCHY NAMESPACE VARCHAR2
CDB_REGISTRY_HISTORY NAMESPACE VARCHAR2
CDB_REGISTRY_LOG NAMESPACE VARCHAR2
CDB_REGISTRY_PROGRESS NAMESPACE VARCHAR2
CDB_REGISTRY_SCHEMAS NAMESPACE VARCHAR2
CDB_SUBSCR_REGISTRATIONS NAMESPACE VARCHAR2
CDB_XML_SCHEMA_ATTRIBUTES TARGET_NAMESPACE VARCHAR2
CDB_XML_SCHEMA_COMPLEX_TYPES TARGET_NAMESPACE VARCHAR2
BASE_TARGET_NAMESPACE VARCHAR2
CDB_XML_SCHEMA_ELEMENTS TARGET_NAMESPACE VARCHAR2
CDB_XML_SCHEMA_NAMESPACES TARGET_NAMESPACE VARCHAR2
CDB_XML_SCHEMA_SIMPLE_TYPES TARGET_NAMESPACE VARCHAR2
CDB_XML_SCHEMA_SUBSTGRP_HEAD TARGET_NAMESPACE VARCHAR2
CDB_XML_SCHEMA_SUBSTGRP_MBRS TARGET_NAMESPACE VARCHAR2
HEAD_TARGET_NAMESPACE VARCHAR2
CDB_XS_NS_TEMPLATE_ATTRIBUTES NAMESPACE VARCHAR2
CDB_XS_SESSION_NS_ATTRIBUTES NAMESPACE VARCHAR2
DBA_CONTEXT NAMESPACE VARCHAR2
DBA_GLOBAL_CONTEXT NAMESPACE VARCHAR2
DBA_HIST_LIBRARYCACHE NAMESPACE VARCHAR2
DBA_INVALID_OBJECTS NAMESPACE NUMBER
DBA_OBJECTS NAMESPACE NUMBER
DBA_OBJECTS_AE NAMESPACE NUMBER
DBA_POLICY_ATTRIBUTES NAMESPACE VARCHAR2
DBA_POLICY_CONTEXTS NAMESPACE VARCHAR2
DBA_REGISTRY NAMESPACE VARCHAR2
DBA_REGISTRY_DEPENDENCIES NAMESPACE VARCHAR2
REQ_NAMESPACE VARCHAR2
DBA_REGISTRY_HIERARCHY NAMESPACE VARCHAR2
DBA_REGISTRY_HISTORY NAMESPACE VARCHAR2
DBA_REGISTRY_LOG NAMESPACE VARCHAR2
DBA_REGISTRY_PROGRESS NAMESPACE VARCHAR2
DBA_REGISTRY_SCHEMAS NAMESPACE VARCHAR2
DBA_SUBSCR_REGISTRATIONS NAMESPACE VARCHAR2
DBA_XML_SCHEMA_ATTRIBUTES TARGET_NAMESPACE VARCHAR2
DBA_XML_SCHEMA_COMPLEX_TYPES BASE_TARGET_NAMESPACE VARCHAR2
TARGET_NAMESPACE VARCHAR2
DBA_XML_SCHEMA_ELEMENTS TARGET_NAMESPACE VARCHAR2
DBA_XML_SCHEMA_NAMESPACES TARGET_NAMESPACE VARCHAR2
DBA_XML_SCHEMA_SIMPLE_TYPES TARGET_NAMESPACE VARCHAR2
DBA_XML_SCHEMA_SUBSTGRP_HEAD TARGET_NAMESPACE VARCHAR2
DBA_XML_SCHEMA_SUBSTGRP_MBRS HEAD_TARGET_NAMESPACE VARCHAR2
TARGET_NAMESPACE VARCHAR2
DBA_XS_NS_TEMPLATE_ATTRIBUTES NAMESPACE VARCHAR2
DBA_XS_SESSION_NS_ATTRIBUTES NAMESPACE VARCHAR2
EXU81OBJ NAMESPACE NUMBER
EXU9ACTIONOBJ NAMESPACE NUMBER
EXU9PCT NAMESPACE VARCHAR2
GLOBAL_CONTEXT NAMESPACE VARCHAR2
GV_$AQ_NONDUR_REGISTRATIONS NAMESPACE NUMBER
GV_$CONTEXT NAMESPACE VARCHAR2
GV_$DB_OBJECT_CACHE NAMESPACE VARCHAR2
GV_$GLOBALCONTEXT NAMESPACE VARCHAR2
GV_$JAVA_LIBRARY_CACHE_MEMORY LC_NAMESPACE VARCHAR2
GV_$LIBRARYCACHE NAMESPACE VARCHAR2
GV_$LIBRARY_CACHE_MEMORY LC_NAMESPACE VARCHAR2
GV_$RESULT_CACHE_OBJECTS NAMESPACE VARCHAR2
GV_$XS_SESSION_NS_ATTRIBUTES NAMESPACE_NAME VARCHAR2
INT$DBA_CONTEXT NAMESPACE VARCHAR2
JAVAJAROBJECTS$ NAMESPACE NUMBER
KU$_AUDCONTEXT_NAMESPACE_VIEW NAMESPACE VARCHAR2
KU$_EDITION_OBJ_VIEW NAMESPACE NUMBER
KU$_EDITION_SCHEMAOBJ_VIEW NAMESPACE NUMBER
KU$_INC_TYPE_VIEW NAMESPACE NUMBER
KU$_JAVA_OBJNUM_VIEW NAMESPACE NUMBER
KU$_PROCOBJ_OBJNUM_VIEW NAMESPACE NUMBER
KU$_SCHEMAOBJNUM_VIEW NAMESPACE NUMBER
KU$_SCHEMAOBJ_VIEW NAMESPACE NUMBER
KU$_VIEW_OBJNUM_VIEW NAMESPACE NUMBER
LOGMNRG_OBJ$ NAMESPACE NUMBER
OBJ$ NAMESPACE NUMBER
REG$ NAMESPACE NUMBER
REGISTRY$ NAMESPACE VARCHAR2
REGISTRY$DEPENDENCIES REQ_NAMESPACE VARCHAR2
NAMESPACE VARCHAR2
REGISTRY$HISTORY NAMESPACE VARCHAR2
REGISTRY$LOG NAMESPACE VARCHAR2
REGISTRY$PROGRESS NAMESPACE VARCHAR2
REGISTRY$SCHEMAS NAMESPACE VARCHAR2
SESSION_CONTEXT NAMESPACE VARCHAR2
SYS_FBA_CONTEXT NAMESPACE VARCHAR2
SYS_FBA_CONTEXT_LIST NAMESPACE VARCHAR2
TTS_OBJ_VIEW NAMESPACE NUMBER
USER_OBJECTS NAMESPACE NUMBER
USER_OBJECTS_AE NAMESPACE NUMBER
USER_POLICY_ATTRIBUTES NAMESPACE VARCHAR2
USER_POLICY_CONTEXTS NAMESPACE VARCHAR2
USER_REGISTRY NAMESPACE VARCHAR2
USER_SUBSCR_REGISTRATIONS NAMESPACE VARCHAR2
USER_XML_SCHEMA_ATTRIBUTES TARGET_NAMESPACE VARCHAR2
USER_XML_SCHEMA_COMPLEX_TYPES BASE_TARGET_NAMESPACE VARCHAR2
TARGET_NAMESPACE VARCHAR2
USER_XML_SCHEMA_ELEMENTS TARGET_NAMESPACE VARCHAR2
USER_XML_SCHEMA_NAMESPACES TARGET_NAMESPACE VARCHAR2
USER_XML_SCHEMA_SIMPLE_TYPES TARGET_NAMESPACE VARCHAR2
USER_XML_SCHEMA_SUBSTGRP_HEAD TARGET_NAMESPACE VARCHAR2
USER_XML_SCHEMA_SUBSTGRP_MBRS TARGET_NAMESPACE VARCHAR2
HEAD_TARGET_NAMESPACE VARCHAR2
UTL_RECOMP_ALL_OBJECTS NAMESPACE NUMBER
UTL_RECOMP_INVALID_ALL NAMESPACE NUMBER
UTL_RECOMP_INVALID_JAVA_SYN NAMESPACE NUMBER
UTL_RECOMP_INVALID_MV NAMESPACE NUMBER
UTL_RECOMP_INVALID_PARALLEL NAMESPACE NUMBER
UTL_RECOMP_INVALID_SEQ NAMESPACE NUMBER
UTL_RECOMP_SORTED NAMESPACE NUMBER
V_$AQ_NONDUR_REGISTRATIONS NAMESPACE NUMBER
V_$CONTEXT NAMESPACE VARCHAR2
V_$DB_OBJECT_CACHE NAMESPACE VARCHAR2
V_$GLOBALCONTEXT NAMESPACE VARCHAR2
V_$JAVA_LIBRARY_CACHE_MEMORY LC_NAMESPACE VARCHAR2
V_$LIBRARYCACHE NAMESPACE VARCHAR2
V_$LIBRARY_CACHE_MEMORY LC_NAMESPACE VARCHAR2
V_$RESULT_CACHE_OBJECTS NAMESPACE VARCHAR2
V_$XS_SESSION_NS_ATTRIBUTES NAMESPACE_NAME VARCHAR2
WRH$_LIBRARYCACHE NAMESPACE VARCHAR2
_ACTUAL_EDITION_OBJ NAMESPACE NUMBER
_CURRENT_EDITION_OBJ NAMESPACE NUMBER
SYSTEM LOGMNR_OBJ$ NAMESPACE NUMBER
XDB XDB$XTABNMSP NAMESPACE NVARCHAR2
165 rows selected.
Liste des colones avec %NAMESPACE% dans leur nom
Combien de noms de colonnes différents avec le mot NAMESPACE dedans? 14!
SQL> select distinct COLUMN_NAME from dba_tab_cols where COLUMN_NAME like '%NAMESPACE%' order by 1;
COLUMN_NAME
-------------------------
BASE_TARGET_NAMESPACE
FTNAMESPACEURL
HEAD_TARGET_NAMESPACE
LC_NAMESPACE
NAMESPACE
NAMESPACEPREFIX
NAMESPACEURL
NAMESPACE_ATTRIBUTE
NAMESPACE_NAME
OBJNAMESPACE
RAS_NAMESPACES
REQ_NAMESPACE
SRSNAMESPACE
TARGET_NAMESPACE
14 rows selected.
Type des colones %NAMESPACE%
Regardons maintenant le type associé à ces colonnes. On passe à 16 car la colonne NAMESPACE peut être de type NUMBER, VARCHAR2 ou NVARCHAR2.
SQL> select distinct COLUMN_NAME, data_type from dba_tab_cols where COLUMN_NAME like '%NAMESPACE%' order by 1;
COLUMN_NAME DATA_TYPE
------------------------- --------------------
BASE_TARGET_NAMESPACE VARCHAR2
FTNAMESPACEURL VARCHAR2
HEAD_TARGET_NAMESPACE VARCHAR2
LC_NAMESPACE VARCHAR2
NAMESPACE NUMBER
NVARCHAR2
VARCHAR2
NAMESPACEPREFIX VARCHAR2
NAMESPACEURL VARCHAR2
NAMESPACE_ATTRIBUTE VARCHAR2
NAMESPACE_NAME VARCHAR2
OBJNAMESPACE VARCHAR2
RAS_NAMESPACES VARCHAR2
REQ_NAMESPACE VARCHAR2
SRSNAMESPACE VARCHAR2
TARGET_NAMESPACE VARCHAR2
16 rows selected.
Contenu des colonnes VARCHAR2 %NAMESPACE%
Regardons le contenu de quelques unes de ces tables avec une colonne NAMESPACE de type VARCHAR2 pour voir si on peut les associer aux namespaces de DBA_OBJECTS. Sur ces deux exemples ce n'est pas parlant et, après mes recherches sur le net, il apparait qu'aucune vue n'associe un libellé au numéro de namespace de DBA_OBJECTS.
SQL> select NAMESPACE from v$librarycache order by 1;
NAMESPACE
----------------------------------------------------------------
ACCOUNT_STATUS
AUDIT POLICY
BODY
CLUSTER
CMP
DBINSTANCE
DBLINK
DIRECTORY
EDITION
FED APP
INDEX
OBJECT ID
PDB
PDBOPER
QUEUE
RULESET
SCHEMA
SQL AREA
SQL AREA BUILD
SQL AREA STATS
SUBSCRIPTION
TABLE/PROCEDURE
TRIGGER
23 rows selected.
SQL> select distinct namespace from DBA_REGISTRY order by 1;
NAMESPACE
------------------------------
SERVER
Voilà, sauf erreur de ma part, les namespaces sous Oracle sont juste des nombres, allant de 1 à 93 avec NULL en plus, sans libellé associé.