{
  "date": "2014-12-28T18:59:38",
  "slug": "create-schema-synonym-in-oracle-unsupported-feature",
  "link": "https://www.dbi-services.com/blog/create-schema-synonym-in-oracle-unsupported-feature/",
  "title": {
    "rendered": "Creating a schema synonym in Oracle &#8211; an unsupported feature"
  },
  "content": {
    "rendered": "<h2>By Franck Pachot</h2>\n<p>.<br />\nIvica Arsov (<a href=\"https://twitter.com/IvicaArsov\">@IvicaArsov</a>) has made an interesting <a href=\"/oracle-12c-cdb-metadata-a-object-links-internals#comment-363\">comment</a> about AUDIT_ACTIONS object link table. I&#8217;ll blog about it soon, but in the meantime when checking its definition in cataudit.sql it came upon the following:</p>\n<pre><code>/* SCHEMA SYNONYMS will be added in 12g */\n-- insert into audit_actions values (222, 'CREATE SCHEMA SYNONYM');\n-- insert into audit_actions values (224, 'DROP SCHEMA SYNONYM');\n</code></pre>\n<p>which caught my attention.</p>\n<p>So this blog post is not about mulitenant but about Schema Synonyms. There are a lot of internal references to 12g&#8217; written when the &#8216;c&#8217; was not yet decided. But that feature is not yet supported: its implementation has probably been postponed again. But that&#8217;s not a reason not to try it &#8211; in lab only of course.</p>\n<p>Let&#8217;s give a try to the syntax:</p>\n<pre><code>SQL&gt; create schema synonym DEMO2 for DEMO;\ncreate schema synonym DEMO2 for DEMO\n              *\nERROR at line 1:\nORA-00901: invalid CREATE command\n</code></pre>\n<h3>Undocumented parameter</h3>\n<p>Doesn&#8217;t work. But there is an undocumented parameter:</p>\n<pre><code>SQL&gt; select ksppinm, ksppstvl from x$ksppi a, x$ksppsv b where a.indx=b.indx and ksppinm like '%schema%synonym%';\n\nKSPPINM                   KSPPSTVL\n------------------------- ----------\n_enable_schema_synonyms   FALSE\n</code></pre>\n<p>Ok, let&#8217;s go:</p>\n<pre><code>SQL&gt; connect sys/oracle as sysdba\nConnected.\n\nSQL&gt; alter system set \"_enable_schema_synonyms\" = true scope=spfile;\nSystem altered.\n\nSQL&gt; startup force;\n</code></pre>\n<p>So I have a DEMO schema:</p>\n<pre><code>SQL&gt; select user_id,username from dba_users where username like 'DEMO%';\n\n   USER_ID USERNAME\n---------- --------------------\n       111 DEMO\n</code></pre>\n<pre><code>which is type 1 in user$ (type 0 is for roles):</code></pre>\n<pre><code>SQL&gt; select user#,name,type#,ctime from sys.user$ where name like 'DEMO%';\n\n     USER# NAME               TYPE# CTIME\n---------- ------------- ---------- ---------\n       111 DEMO                   1 09-NOV-14</code></pre>\n<p>And I create a synonym DEMO2 for it:</p>\n<pre><code>SQL&gt; create schema synonym DEMO2 for DEMO;\nSchema synonym created.\n</code></pre>\n<p>It&#8217;s not a user:</p>\n<pre><code>SQL&gt; select user_id,username from dba_users where username like 'DEMO%';\n\n   USER_ID USERNAME\n---------- --------------------\n       111 DEMO\n</code></pre>\n<p>but it&#8217;s another entry in user$ with type 3 which is for schema synonyms:</p>\n<pre><code>SQL&gt; select user#,name,type#,ctime,spare2 from sys.user$ where name like 'DEMO%';\n\n     USER# NAME            TYPE# CTIME         SPARE2\n---------- ---------- ---------- --------- ----------\n       111 DEMO                1 09-NOV-14\n       159 DEMO2               3 28-DEC-14        111\n</code></pre>\n<p>I&#8217;ve selected the SPARE2 because this is where the link to the target schema of the synonym is stored.</p>\n<h3>Usage</h3>\n<p>I can create a table using the schema synonym:</p>\n<pre><code>SQL&gt; create table DEMO2.MYTABLE as select * from dual;\nTable created.\n</code></pre>\n<p>and query it from both:</p>\n<pre><code>SQL&gt; select * from DEMO2.MYTABLE;\n\nD\n-\nX\n\nSQL&gt; select * from DEMO.MYTABLE;\n\nD\n-\nX\n</code></pre>\n<p>the execution plan show the schema synonym DEMO2 as the object owner:</p>\n<pre><code>SQL&gt; explain plan for select * from DEMO2.MYTABLE;\nExplained.\n\nSQL&gt; select operation,object_owner,object_name,object_type from plan_table order by id;\n\nOPERATION            OBJECT_OWN OBJECT_NAM OBJECT_TYP\n-------------------- ---------- ---------- ----------\nSELECT STATEMENT\nTABLE ACCESS         DEMO2      MYTABLE    TABLE\n</code></pre>\n<p>and the rowid shows that data comes from the DEMO table:</p>\n<pre><code>SQL&gt; select rowid, dbms_rowid.rowid_object(rowid),MYTABLE.* from DEMO2.MYTABLE;\n\nROWID                   DBMS_ROWID.ROWID_OBJECT(ROWID) D\n------------------ ------------------------------ -\nAAAXaYAAGAAAuGbAAA                            95896 X\n\nSQL&gt; select owner,object_name,object_id,data_object_id from dba_objects where object_name = 'MYTABLE';\n\nOWNER           OBJECT_NAM  OBJECT_ID DATA_OBJECT_ID\n---------- ---------- ---------- --------------\nDEMO           MYTABLE           95896          95896\n</code></pre>\n<p>The locks are acquired on the base object:</p>\n<pre><code>SQL&gt; select * from DEMO2.MYTABLE for update;\n\nD\n-\nX\n\nSQL&gt; select object_id,locked_mode from v$locked_object;\n\n OBJECT_ID LOCKED_MODE\n---------- -----------\n     95896           3\n\nSQL&gt; select owner,object_name,object_id from dba_objects where object_name = 'MYTABLE';\n\nOWNER      OBJECT_NAM  OBJECT_ID\n---------- ---------- ----------\nDEMO         MYTABLE       95896\n</code></pre>\n<h3>Limits</h3>\n<p>We can use the schema synonym as the default prefix:</p>\n<pre><code>SQL&gt; alter session set current_schema=DEMO2;\nSession altered.\n</code></pre>\n<p>and we cannot drop it when the underlying user is connected:</p>\n<pre><code>SQL&gt; connect DEMO/demo;\nConnected.\nSQL&gt; drop schema synonym DEMO2;\ndrop schema synonym DEMO2\n*\nERROR at line 1:\nORA-42297: cannot drop a schema synonym for a schema of a user who is currently\nconnected\n</code></pre>\n<p>we cannot create synonyms for system schemas:</p>\n<pre><code>SQL&gt; create schema synonym ROOT for SYS;\ncreate schema synonym ROOT for SYS\n                               *\nERROR at line 1:\nORA-42288: may not create a schema synonym for the specified schema\n</code></pre>\n<p>and schema synonyms is in the same namespace as users and roles:</p>\n<pre><code>SQL&gt; create role DEMO2;\ncreate role DEMO2\n            *\nERROR at line 1:\nORA-42294: role name conflicts with another user, role or schema synonym name\n</code></pre>\n<p>Those new error messages include &#8216;or schema synonym name&#8217; when the &#8220;_enable_schema_synonyms&#8221; is enabled.</p>\n<h3>Don&#8217;t use it!</h3>\n<p>Now playing with undocumented stuff comes with unexpected behaviour:</p>\n<pre><code>SQL&gt; truncate table DEMO2.MYTABLE;\nTable truncated.\n</code></pre>\n<p>I&#8217;ve truncated the table using the synonym, then let&#8217;s select from it though the synonym or with the real schema:</p>\n<pre><code>SQL&gt; select * from DEMO2.MYTABLE;\nno rows selected\n\nSQL&gt; select * from DEMO.MYTABLE;\nselect * from DEMO.MYTABLE\n*\nERROR at line 1:\nORA-08103: object no longer exists\n</code></pre>\n<p>Ok it seems that some invalidations didn&#8217;t follow the synonyms&#8230;<br />\nLet&#8217;s try to flush the shared pool:</p>\n<pre><code>SQL&gt; alter system flush shared_pool;\nSystem altered.\n\nSQL&gt; select * from DEMO.MYTABLE;\nno rows selected\n\nSQL&gt; select * from DEMO2.MYTABLE;\nno rows selected\n</code></pre>\n<p>This is what happens when we use features that are not totally implemented&#8230;</p>\n<p>That feature is not yet totally implemented. Do you have a need for it? then maybe create an <a href=\"https://community.oracle.com/community/database/database-ideas/content?filterID=contentstatus[published]~objecttype~objecttype[idea]&amp;sortKey=score&amp;customTheme=otn\">OTN database idea</a>.</p>\n",
    "protected": false
  }
}
