where oracle foreign key constraint named SYS_C comming from - oracle

my database is oracle 10.2 and my create table sql is like this:
create table T_EP_SYS_COMPANY
(
company_id NUMBER not null,
company_name VARCHAR2(30),
company_address VARCHAR2(100),
is_in_use VARCHAR2(1),
is_canceled VARCHAR2(1),
is_headquarter VARCHAR2(1),
account_id NUMBER not null
)
tablespace USERS
pctfree 10
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
alter table T_EP_SYS_COMPANY
add constraint PK_ESHOP_SYS_COMPANY primary key (COMPANY_ID)
using index
tablespace USERS
pctfree 10
initrans 2
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);
alter table T_EP_SYS_COMPANY
add constraint FK_SYS_COMPANY_PAY_ACCOUNT foreign key (ACCOUNT_ID)
references T_EP_PAY_ACCOUNT (ACCOUNT_ID);
but in my database,I have to 2 FKs on column "account_id":
owner constraint_name table_name column_name position
ESHOPV2 SYS_C009725 T_EP_SYS_COMPANY ACCOUNT_ID null
ESHOPV2 FK_SYS_COMPANY_PAY_ACCOUNT T_EP_SYS_COMPANY ACCOUNT_ID 1
why there are 2 FKs? I did rename the table name,dose the rename ddl has something to do with this?

They aren't both foreign key constraints. The SYS_C is a system-generated name for a constraint you didn't explicitly name; in this case for your not-null check. You can see those immediately after the create:
create table T_EP_SYS_COMPANY
(
company_id NUMBER not null,
company_name VARCHAR2(30),
company_address VARCHAR2(100),
is_in_use VARCHAR2(1),
is_canceled VARCHAR2(1),
is_headquarter VARCHAR2(1),
account_id NUMBER not null
);
select uc.constraint_name, uc.constraint_type, ucc.column_name, ucc.position
from user_constraints uc
join user_cons_columns ucc on ucc.constraint_name = uc.constraint_name
where uc.table_name = 'T_EP_SYS_COMPANY';
CONSTRAINT_NAME CONSTRAINT_TYPE COLUMN_NAME POSITION
------------------------------ --------------- --------------- --------
SYS_C0093988 C COMPANY_ID
SYS_C0093989 C ACCOUNT_ID
The constraint type is C, showing it's a check constraint. You can name those by explicitly adding check constraints rather than specifying them as 'not null' but there is no real benefit - you don't ever need to refer to them by name, e.g. to temporarily disable them.
After you add the primary and foreign key you see those too:
alter table T_EP_SYS_COMPANY
add constraint PK_ESHOP_SYS_COMPANY primary key (COMPANY_ID);
alter table T_EP_SYS_COMPANY
add constraint FK_SYS_COMPANY_PAY_ACCOUNT foreign key (ACCOUNT_ID)
references T_EP_PAY_ACCOUNT (ACCOUNT_ID);
select uc.constraint_name, uc.constraint_type, ucc.column_name, ucc.position
from user_constraints uc
join user_cons_columns ucc on ucc.constraint_name = uc.constraint_name
where uc.table_name = 'T_EP_SYS_COMPANY';
CONSTRAINT_NAME CONSTRAINT_TYPE COLUMN_NAME POSITION
------------------------------ --------------- --------------- --------
SYS_C0093988 C COMPANY_ID
SYS_C0093989 C ACCOUNT_ID
PK_ESHOP_SYS_COMPANY P COMPANY_ID 1
FK_SYS_COMPANY_PAY_ACCOUNT R ACCOUNT_ID 1
These have constraint type P and R, for 'primary key' and 'referential integrity'.
Read more about types of integrity constraints and how they are shown in the data dictionary.

owner constraint_name table_name column_name position
ESHOPV2 SYS_C009725 T_EP_SYS_COMPANY ACCOUNT_ID null
ESHOPV2 FK_SYS_COMPANY_PAY_ACCOUNT T_EP_SYS_COMPANY ACCOUNT_ID 1
why there are 2 FKs?
SYS_C009725 is not a foreign key constraint. It is a CHECK constraint for the NOT NULL condition. If you see the CONSTRAINT_TYPE then you would see it as C. And the name as SYS_C you see is because it is system-generated name.
Too keep it simple, let's see a small example:
SQL> CREATE TABLE t(
2 ID NUMBER NOT NULL
3 );
Table created.
SQL>
SQL> SELECT constraint_name,
2 constraint_type,
3 table_name,
4 search_condition
5 FROM user_constraints
6 WHERE table_name ='T';
CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME SEARCH_CONDITION
--------------- --------------- ---------- ----------------
SYS_C0010726 C T "ID" IS NOT NULL
SQL>

Related

Oracle: detect a NOT INMEMORY column

I have a table that has been created with a NOT INMEMORY column:
CREATE TABLE myTable (
foo VARCHAR2(20 BYTE) NOT NULL,
bar VARCHAR2(20 BYTE) NOT NULL,
baz VARCHAR2(2000 BYTE) NOT NULL,
);
ALTER TABLE myTable INMEMORY;
ALTER TABLE myTable NO INMEMORY ("baz") ;
What I need to do is identify the NO INMEMORY column by querying the static data dictionary views, but it appears all_tables, all_tab_columns and similar don't carry this information, and I can't find mention of one in the documentation. Is there a view which does?
You can use the ALL_TABLES and V$IM_COLUMN_LEVEL views to get the information. The information was found on Oracle-Base.
SQL> select inmemory from all_tables
2* where table_name = 'MYTABLE';
INMEMORY
___________
ENABLED
SQL> SELECT table_name,
2 segment_column_id,
3 column_name,
4 inmemory_compression
5 FROM v$im_column_level
6 WHERE table_name = 'MYTABLE'
7* ORDER BY segment_column_id;
TABLE_NAME SEGMENT_COLUMN_ID COLUMN_NAME INMEMORY_COMPRESSION
_____________ ____________________ ______________ _______________________
MYTABLE 1 FOO DEFAULT
MYTABLE 2 BAR DEFAULT
MYTABLE 3 BAZ NO INMEMORY

Oracle column Datatype from metadata [duplicate]

I want to get the columns names and datatype and its datatype's length .as example
if there is a table
SQL> create table TestTable(
2 ID VARCHAR2(4) NOT NULL,
3 CODE Number(5),
4 MyDate DATE,
5 MyNumber Number(8,2))
I need something like in some_column to identify separately number(5) is for an integer and number(8,2) is for a desimal value...
I tried this
SELECT column_name, data_type, data_length FROM USER_TAB_COLUMNS WHERE table_name = 'some_table'
but this data_length gives me the length in byte so I can't figure out when there is a case like number(5) ,number(8,2)..what I need is like somthing below
TABLE_NAME COLUMN_NAME DATA_TYPE some_column
------------------------------ ------------------------------ --------------------------
TESTTABLE ID VARCHAR2 4
TESTTABLE MYNAME VARCHAR2 5
TESTTABLE MYDATE DATE -
TESTTABLE MYNUMBER NUMBER 8,2
help?
There are data_precision and data_scale columns there.
Please take a look at this example:
create table qwer(
x number,
y number(8,2),
z number(5,0),
a int,
b decimal(5,3)
);
SELECT column_name, data_type, data_precision, data_scale
FROM USER_TAB_COLUMNS
WHERE Table_name = 'QWER'
;
COLUMN_NAME DATA_TYPE DATA_PRECISION DATA_SCALE
------------- --------- -------------- ----------
B NUMBER 5 3
A NUMBER
X NUMBER
Y NUMBER 8 2
Z NUMBER 5 0
EDIT
To find primary key columns you need to join two dictionary views, please see the below example:
CREATE TABLE pk1(
id int primary key,
name varchar2(10)
);
CREATE TABLE pk2(
id int ,
pk1 number(10,0),
pk2 varchar2(5),
name varchar2(10),
constraint my_composite_pk primary key (id, pk1, pk2 )
);
SELECT c.table_name, cols.column_name, cols.position
FROM user_constraints c
JOIN USER_CONS_COLUMNS cols
USING ( CONSTRAINT_NAME )
WHERE c.table_name IN ('PK1', 'PK2' )
and c.constraint_type = 'P' /* P - means PRIMARY KEY */
ORDER BY 1,3
;
TABLE_NAME COLUMN_NAME POSITION
---------- ----------- ----------
PK1 ID 1
PK2 ID 1
PK2 PK1 2
PK2 PK2 3
If this is only for Geetting information then just Press ALT+F1 on the name of the table this will show you the names of the columns with length and data types.
Why don't you try SELECT * FROM information_schema.columns ?
It has columns "table_schema, table_name, column_name, ordinal_position, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision", etc.

how to delete a parent table that is also a child to it's child?

I have two tables both of which reference each other primary keys as foreign keys, I want to drop both but I can't.
I tried this :
alter table my_table drop constraint cons_name;
That gave me :
ORA-02443: Cannot drop constraint - nonexistent constraint
Suppose you have the following tables (Oracle 12c) ...
create table table1 ( column1 primary key )
as
select level
from dual
connect by level <= 10 ;
create table table2 ( column1 primary key )
as
select level
from dual
connect by level <= 10 ;
alter table table1
add constraint fk1
foreign key ( column1 ) references table2( column1 ) ;
alter table table2
add constraint fk2
foreign key ( column1 ) references table1( column1 ) ;
If you want to remove the constraints, make sure that you use the correct
constraint names.
-- find the correct constraint names
select table_name, constraint_name, constraint_type
from user_constraints
where table_name in( 'TABLE1', 'TABLE2' ) ;
TABLE_NAME CONSTRAINT_NAME CONSTRAINT_TYPE
TABLE2 SYS_C0021482 P
TABLE1 SYS_C0021483 P
TABLE1 FK1 R
TABLE2 FK2 R
-- fails: constraint name correct, table name wrong
SQL> alter table table1 drop constraint SYS_C0021482;
ORA-02443: Cannot drop constraint - nonexistent constraint
-- fails: need to disable/remove the FK constraint first
SQL> alter table table1 drop constraint SYS_C0021483;
ORA-02273: this unique/primary key is referenced by some foreign keys
-- okay
SQL> alter table table1 drop constraint FK1 ;
Table TABLE1 altered.
If you just want to drop both tables, including all constraints, use ...
SQL> drop table table1 cascade constraints purge ;
Table TABLE1 dropped.
SQL> drop table table2 cascade constraints purge ;
Table TABLE2 dropped.
Check:
-- any constraints left? no.
SQL> select table_name, constraint_name, constraint_type
2 from user_constraints
3 where table_name in( 'TABLE1', 'TABLE2' ) ;
no rows selected

How to delete the primary key from without using constraint name

CREATE TABLE Persons (
ID int PRIMARY KEY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int
);
How to remove the primary key as there is no constraint defined?
"How to remove PK as there is no constraint defined?"
Actually it's every bit as simple as you might hope:
SQL> create table t23 (id number primary key);
Table created.
SQL> select constraint_name, constraint_type
2 from user_constraints
3 where table_name = 'T23'
4 /
CONSTRAINT_NAME C
------------------------------ -
SYS_C0034419 P
SQL> alter table t23 drop primary key;
Table altered.
SQL> select constraint_name, constraint_type
2 from user_constraints
3 where table_name = 'T23'
4 /
no rows selected
SQL>
run this to get constraint name :
SELECT *
FROM user_cons_columns
WHERE table_name = Persons;
then run
ALTER TABLE Persons
DROP CONSTRAINT <pk constraint>;
Don't think you can do it in 1 SQL command,without knowing the constraint name, but you can know the constraint name as in this case it would be defined by system. Something which starts with SYS.....
Alternatively you can use a PLSQL block to achieve the same.
See the example below for your case.
CREATE TABLE Persons (
ID int PRIMARY KEY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Age int
);
Find constraint name
select CONSTRAINT_NAME
From USER_CONSTRAINTS
where table_name='PERSONS'
AND CONSTRAINT_TYPE='P';
OUTPUT:= SYS_C0012152
Drop Constraint
ALTER TABLE PERSONS
DROP CONSTRAINT SYS_C0012152;
Note: The constraint name SYS_C0012152 is not enclosed in single quotes.
PLSQL Block to do the same
declare
sql_stmt varchar2(255);
cons_name varchar2(30);
begin
select CONSTRAINT_NAME
into cons_name
From USER_CONSTRAINTS
where table_name='PERSONS'
AND CONSTRAINT_TYPE='P';
sql_stmt:=' ALTER TABLE PERSONS
DROP CONSTRAINT '||cons_name;
dbms_output.put_line(sql_stmt);
execute immediate sql_stmt;
end;

How to add primary key constraint on oracle?

CREATE TABLE buses(Bus_no NUMBER(11) NOT NULL ,Bus_name Varchar2(20),Type VARCHAR2(20),Total_seats Number(11),Avail_seats Number(11));
ALTER TABLE buses
ADD CONSTRAINT PK_BUSES UNIQUE(Bus_no);
This is the table I need to create .. and this should be the output:
Name Null? Type
----------------------------------------- -------- ----------------------------
BUS_NO NOT NULL NUMBER(11)
BUS_NAME VARCHAR2(20)
TYPE VARCHAR2(20)
TOTAL_SEATS NUMBER(11)
AVAIL_SEATS NUMBER(11)
CONSTRAINT_NAME
------------------------------
PK_BUSES
However I am getting this extra line SYS-C00403053 along with my output table,please help to remove this.
CONSTRAINT_NAME
------------------------------
SYS_C00403053
PK_BUSES
You haven't added a primary key, you've added a unique constraint. While a unique constraint and a not-null constraint are effectively the same, they are not actually the same as an actual primary key.
As #GurwinderSingh said, the SYS_C00403053 is a system-generated name for the not-null constraint. It is possible, but unusual, to name a not-null constraint:
-- just to clean up what you have in the question, remove the unique constraint
ALTER TABLE buses DROP CONSTRAINT PK_BUSES;
ALTER TABLE buses MODIFY Bus_no NULL;
ALTER TABLE buses MODIFY Bus_no CONSTRAINT BUS_NO_NOT_NULL NOT NULL;
desc buses
Name Null? Type
----------- -------- ------------
BUS_NO NOT NULL NUMBER(11)
BUS_NAME VARCHAR2(20)
TYPE VARCHAR2(20)
TOTAL_SEATS NUMBER(11)
AVAIL_SEATS NUMBER(11)
select constraint_name, constraint_type, search_condition
from user_constraints where table_name = 'BUSES';
CONSTRAINT_NAME C SEARCH_CONDITION
------------------------------ - --------------------------------------------------------------------------------
BUS_NO_NOT_NULL C "BUS_NO" IS NOT NULL
But as you want a primary key anyway, you can drop the separate not-null check, as it's implied by a (proper) primary key:
ALTER TABLE buses MODIFY Bus_no NULL;
ALTER TABLE buses ADD CONSTRAINT PK_BUSES PRIMARY KEY (Bus_no);
desc buses
Name Null? Type
----------- -------- ------------
BUS_NO NOT NULL NUMBER(11)
BUS_NAME VARCHAR2(20)
TYPE VARCHAR2(20)
TOTAL_SEATS NUMBER(11)
AVAIL_SEATS NUMBER(11)
select constraint_name, constraint_type, search_condition
from user_constraints where table_name = 'BUSES';
CONSTRAINT_NAME C SEARCH_CONDITION
------------------------------ - --------------------------------------------------------------------------------
PK_BUSES P
You now only see the primary key constraint listed, but the column is still marked as not nullable, and you get the same error if you try to insert null:
insert into buses (bus_no) values (null);
ORA-01400: cannot insert NULL into ("MY_SCHEMA"."BUSES"."BUS_NO")
SYS_C00403053 is the system generated name given to the NOT NULL constraint on Bus_no column. Your result is as expected only.

Resources