Dual table issue - sql

Hi We all know DUAL is the table of SYS and other users have synonym of it.
but when i fire the below commnad
create table dual(x varchar2(1));
it worked. An object of the name DUAL was created.
when there is already a synonym with the name DUAL how can we create another object of same name? why oracle is allowing us to do it.

You can create a table named DUAL because tables and public synonyms have a different namespace. For details, see chapter Database Object Names and Qualifiers of Oracle's SQL Language Reference.
EDIT: To illustrate the mechanism:
If you create your own DUAL table as user scott
CREATE TABLE dual (x VARCHAR2(1));
... then it shows up in the data dictionary:
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
So, the names are unique per owner and namespace. You cannot add yet another table in your schema called DUAL. You cannot create a private synonym named DUAL, but you can create your own synonym for schemas in other objects.
Please make sure to drop the table again. Even simple statements won't work anymore:
SELECT sysdate FROM DUAL;
--
DROP TABLE dual;
SELECT sysdate FROM DUAL;
01.07.2018

I think DUAL is a distraction here. Of course it's a system table and there are side effects if you mess about with it, so don't. But the question is really about why there is no namespace conflict between any object and a public synonym with the same name. For example, I can create a table named ALL_TABLES or DBMS_OUTPUT in my own schema (if I really want to). Or, I can create a table called MYDEMOTABLE and then create a public synonym MYDEMOTABLE for WILLIAM.MYDEMOTABLE.
But then, what restriction are you expecting to exist? There is already both a table (owned by SYS) and a public synonym (owned by PUBLIC) named DUAL. You can create a third object with the same name, as long as it isn't owned by SYS or PUBLIC.

I think I found a way to demonstrate what is going on (without using DUAL or any other SYS object ;-):
If two users create a table with the same name, the tables end up in their own schema as expected:
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
But when one of them creates a public synonym (as SYS did with it's DUAL table), it ends up in a magic schema with the name 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
So, in other words, public synonyms are just synonyms that live in the schema PUBLIC. And you can have only one table, view, sequence, package, synonym with the same name per schema.

There have various schemas in your single database. When you asked about default DUAL table, which actually belongs to 'sys' Schema which is system schema. But your default Database schema is dbo it means when you have executed your query to create DUAL table is actually created in your default schema named dbo.
If you want to check their actual double existence there are many ways to check.
You can apply a query like "select * from sys.DUAL" and "select * from dbo.DUAL". there you will see two different outputs.
you can check all the schemas in "select * from sys.schemas".
Also, you can check their different schemas in with table name
"select * from sys.tables where name ='DUAL'";
the result will be two different tables with two different schema Id's.
Hope this will help you to understand schema basics.

Related

ORA-00942 cannot find table

I ran these statements:
create table SAMPLE(
ID INT
);
INSERT INTO SAMPLE VALUES(1);
COMMIT;
GRANT INSERT, SELECT, UPDATE, DELETE ON SAMPLE TO NEWLEC;
COMMIT;
But Eclipse says cannot find the table.
How can I resolve it?
You are connecting as the newlec user, and unqualified references to tables will look for them in that schema, not under other users.
You can qualify the table name:
SELECT * FROM real_owner.SAMPLE
For example, if you were connected as HR when you created the table, you would do:
SELECT * FROM HR.SAMPLE
You could also create a public synonym, which is probably overkill and can cause other issues and confusion; or create a private synonym for the newlec user which points to the rea table, e.g.:
CREATE SYNONYM SAMPLE FOR real_owner.SAMPLE;
SELECT * FROM SAMPLE;
so the unqualified query now sees the synonym, and through that the real table owned by someone else. Or you could set your current_schema after logon:
ALTER SESSION SET CURRENT_SCHEMA=real_owner;
SELECT * FROM SAMPLE;
so all unqualified queries now see objects owned by that user, not newlec.
However, if this is a basic assignment on a beginner course then you are probably just expected to qualify the name.

How to create a table in Sql from existing table along with it partition and indexs Structure

I have a table in Schema ABC, I have to create an exact replica for that table in the schema XYZ along with its Partition and Index.
Create table XYZ.table1 as Select * from ABC.table2;
Is there any possible way of implementing this?
It is DBMS_METADATA package you should look at.
In your case, to get table description (along with its partitions), you'd use
SELECT DBMS_METADATA.get_ddl ('TABLE', 'EMP', 'SCOTT') FROM DUAL;
(where EMP represents table name, while SCOTT is its owner).
To get its indexes, you'd use
SELECT DBMS_METADATA.get_ddl ('INDEX', index_name, 'SCOTT')
FROM user_indexes
WHERE table_name = 'EMP';
Another option might be to use Data Pump Export and Import utilities which allow you to export not only metadata, but tables' contents.

Are SCHEMA and USER the same thing in Oracle?

Are SCHEMA and USER the same thing in Oracle? Is there is situation where a single user can have two or more schemas?
Strictly speaking a SCHEMA is the set of objects owned by a USER. However, a USER can have only one SCHEMA, so people often use the terms interchangeably.
Here's the difference between USER and SCHEMA. User "A" has granted rights on its PRODUCT table to user "B". User "B" does not have a table of that name.
SQL> show user
USER is "B"
SQL> select count(*) from products
2 /
select count(*) from products
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select count(*) from a.product
2 /
COUNT(*)
----------
2
SQL>
Without a synonym "B" needs to prefix the schema to reference the PRODUCT table. Unless they choose to change the current schema:
SQL> alter session set current_schema = "A"
2 /
Session altered.
SQL> select count(*) from product
2 /
COUNT(*)
----------
2
SQL> show user
USER is "B"
SQL>
Now the user is "B" but the current (default) schema is "A". Which menas they need to prefix the schema when referencing their own tables!
SQL> select table_name from user_tables;
TABLE_NAME
------------------------------
YOUR_TABLE
SQL> select count(*) from your_table;
select count(*) from your_table
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select count(*) from b.your_table;
COUNT(*)
----------
6
SQL>
"Whether a schema can be created separately Without any user ."
No. A SCHEMA must belong to a USER. When we create user Oracle creates a schema, an empty one, automatically.
Confusingly there is a create schema syntax, but that is just a short hand for creating a number of tables (and indexes) in one statement. Find out more.

Select Data from view vs Table of same name

I have a database where a view and a table have same name, when I try to execute query
select * from XXXXXXXXX
from where is this data coming from, view or table? Is there any explicit declaration syntax to tell, to where from select the data?
PS: the DB owner is different so I can't change the structure of view/table or names either.
Objects names are unique per owner, so the table and the view can't be defined for the same owner.
Qualify the table/view name with the right owner.
select * from table_owner.XXXXXXXXX
select * from view_owner.XXXXXXXXX

Oracle SQL - Column has no Corresponding Table

I came across something that makes no sense.
This is the SAAADMS form containing the Curriculum tab. The form has fields (columns) from different sources (tables). Most of these columns have a corresponding table, but the User ID and Activity Date (in the red rectangle) do not have a corresponding table!
You can see that the SOVLCUR_ACTIVITY_DATE and SOVLCUR_USER_ID do not have a corresponding table. It states "N/A." The other two columns I listed (I only listed a couple since there are several) do have a corresponding table.
I am trying to pull data from the two columns with no corresponding table.
The SOVLCUR table I currently have in the code does NOT exist.
How do I find where this SOVLCUR_USER_ID and SOVLCUR_ACTIVITY_DATE data is stored or pull from a column that seems to have no table?
If the data is not really stored in SOVLCUR_USER_ID and SOVLCUR_ACTIVITY_DATE is there a way for me to see where it is stored? find all associated columns?
SELECT
SP.SPRIDEN_ID AS "STUDENT_ID",
SP.SPRIDEN_LAST_NAME AS "LAST",
SP.SPRIDEN_FIRST_NAME AS "FIRST",
SD.SARADAP_TERM_CODE_ENTRY AS "TERM",
SD.SARADAP_APPL_DATE AS "APP_DATE",
SV.SOVLCUR_USER_ID AS "USER_ID", /*SOVLCUR table does not exist*/
SV.SOVLCUR_ACTIVITY_DATE AS "ACTIVITY_DATE", /*SOVLCUR table does not exist*/
SYSDATE
FROM
SPRIDEN SP
JOIN SARADAP SD
ON SPRIDEN_PIDM = SARADAP_PIDM
JOIN SOVLCUR SV /*This table does not exist*/
ON SPRIDEN_PIDM = SOVLCUR_PIDM
WHERE
SP.SPRIDEN_CHANGE_IND IS NULL
AND
SD.SARADAP_TERM_CODE_ENTRY >= '201510'
AND
SV.SOVLCUR_USER_ID NOT IN ('SSmith', 'JJones')
AND
SV.SOVLCUR_ACTIVITY_DATE BETWEEN SYSDATE-1 AND SYSDATE
Oracle provides views/tables that can be query to find out that type of information:
select table_name from all_tab_columns
where column_name = 'COLUMN NAME';
This query will return all the table where that column exists.
As user1261620 said, use ALL_TAB_COLUMNS to see the table_name corresponding to a column_name. But, as you say that few tables does not exist, perhaps, those are not tables, rather VIEWS.
To confirm whether those are TABLE or VIEW, you can query ALL_OBJECTS
SELECT object_name, object_type
FROM all_objects
WHERE object_name = 'SOVLCUR';
If the above returns no rows, that would mean the object really doesn't exist. But, in that case the query won't be executed, as it won't be parsed at all. You would get error : table/view does not exist`.
Also, not all values needs to be always stored in database. The computed values are generally calculated through a query and returned to the user for display. And other than computed values, few static values like SYSDATE can be dynamically generated rather than storing it in database and querying it.
So, I think, those are not tables, rather VIEWS. Follow the steps as I mentioned to have a clear understanding.
Update Based on OP's new inputs
So, now you know that SOVLCUR is a synonym. Execute the following query to see its details :
SELECT * FROM all_synonyms WHERE synonym_name = 'SOVLCUR';
For example,
I am user LALIT, and I create a synonym for EMP table in SCOTT schema.
SQL> show USER
USER is "LALIT"
SQL>
SQL> CREATE OR REPLACE SYNONYM lalit FOR scott.emp
2 /
Synonym created.
SQL>
SQL> SELECT owner, synonym_name, table_owner, table_name
2 FROM all_synonyms
3 WHERE synonym_name = 'LALIT'
4 /
OWNER SYNONYM_NAME TABLE_OWNER TABLE_NAME
---------- --------------- ------------ ----------
LALIT LALIT SCOTT EMP
So, the table_owner and table_name shows the SCHEMA is SCOTT and TABLE is EMP.