How to delete the primary key from without using constraint name - oracle

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;

Related

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

where oracle foreign key constraint named SYS_C comming from

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>

parent keys not found Oracle 10g

I have two tables :
SQL> desc SEGMENT
Name Null? Type
----------------------------------------- -------- ----------------------------
INDIP NOT NULL VARCHAR2(11)
NOMSEGMENT NOT NULL VARCHAR2(20)
ETAGE
SQL> desc POSTE
Name Null? Type
----------------------------------------- -------- ----------------------------
NPOSTE NOT NULL VARCHAR2(7)
NOMPOSTE NOT NULL VARCHAR2(20)
INDIP VARCHAR2(11)
AD VARCHAR2(3)
TYPEPOSTE VARCHAR2(9)
NSALLE VARCHAR2(7)
I want to add a constraint as the following :
ALTER TABLE "POSTE" ADD CONSTRAINT "FK_POSTE_SEGMENT" FOREIGN KEY ("INDIP") REFERENCES "SEGMENT" ("INDIP") ENABLE;
But I got this error message :
ERROR at line 1: ORA-02298: cannot validate (AIMAD.FK_POSTE_SEGMENT) -
parent keys not found
How can I solve this
You should check what POSTE table does not contain values in INDIP column what don't exist in INDIP column of SEGMENT table.
Like
SQL> create table t (x int primary key);
SQL> insert into t values(1);
SQL> create table t_c (x int);
SQL> insert into t_c values(1);
SQL> insert into t_c values(2);
SQL> commit;
SQL> alter table t_c add constraint t_c_x foreign key(x)
2 references t(x);
alter table t_c add constraint t_c_x foreign key(x)
*
ORA-02298: cannot validate (SCOTT.T_C_X) - parent key not found
SQL> select * from t_c where not exists (select *
2 from t where t.x = t_c.x);
X
-----------------------
2
Also Oracle provides the ability to create constraint in NOVALIDATE status, this prevents Oracle from checking data during contraint creation:
SQL> alter table t_c add constraint t_c_x foreign key(x)
2 references t(x) enable novalidate;
Table altered.
but this can have undesirable side effects because data in both tables are not consistent.

ORACLE: Error on Drop an interim table after dbms_redefinition

I'm working on Oracle11g, and trying to redefine a table with dbms_redefinition. It works ok but when trying to drop the interim table it throws an ORA-02449: unique/primary keys in table referenced by foreign keys error.
I found a query to look for references right here in SO,
select table_name, constraint_name, status, owner
from all_constraints
where r_owner = 'MYSCHEMA'
and constraint_type = 'R'
and r_constraint_name in
(
select constraint_name from all_constraints
where constraint_type in ('P', 'U')
and table_name = 'INTERIM_TABLE'
and owner = 'MYSCHEMA'
)
order by table_name, constraint_name
which gives
table_name |constraint_name |status |owner
---------------------------------------------------------
anotherTable|TMP$$_anotherTable_JOB_ID0|DISABLED|MYSCHEMA
I suppose that this constraint was created during the redefinition process, that's ok, but I also expected that it must be deleted by the same process. Is this wrong? I say, is part of normal behavior that this constraint were not went deleted?
It's safe to just drop the constraint with
alter table anotherTable
drop constraint TMP$$_anotherTable_JOB_ID0
without a loss of data?
Thanks in advance.
-- EDIT --
After thinking about this, I've decided just to delete the constraint to let the interim table be droped.
I've modified the query to drop the constraints of other tables that point to the tables which I want to drop, almost automatically.
DECLARE
my_table varchar2(100);
my_constraint varchar2(100);
BEGIN
select table_name , constraint_name into my_table,my_constraint
from all_constraints
where r_owner = 'MYSCHEMA'
and constraint_type = 'R'
and r_constraint_name in
(
select constraint_name from all_constraints
where constraint_type in ('P', 'U')
and table_name = 'INTERIM_TABLE'
and owner = 'MYSCHEMA'
)
order by table_name, constraint_name;
execute immediate 'ALTER TABLE '||my_table||' DROP CONSTRAINT '|| my_constraint;
END;
/
DROP TABLE MYSCHEMA.INTERIM_TABLE;
This worked for me, but I must note that in my case that query throws just one row (only one dependant table), so this must be modified to drop many constraints by a loop or another method if you know someone.
It would be good if someone can figure out and explain why that constraint was not deleted by the process itself (or if this is a normal behavior).
It's easy enough to force this:
drop table INTERIM_TABLE cascade constraints;
It's because the original and new constraints STATUS changes while running the SYNC and FINISH redefinition procedure as below. You create the fkeys to the interim table from the child tables in a disabled mode. When we finish the redef, we disable the old fkeys and enable the news (without having to validate). Consider:
create table t NOLOGGING
as
select * from all_objects;
alter table t add constraint t_pk primary key(object_id);
create table t1( x references t );
create table t2( y references t );
insert into t1 select object_id from t where rownum <= 100;
100 rows created.
insert into t2 select object_id from t where rownum <= 100;
100 rows created.
create table t_interim similar to t table.
alter table t1 add constraint t1_new_fk foreign key(x) references t_interim disable;
alter table t2 add constraint t2_new_fk foreign key(y) references t_interim disable;
select constraint_name, status from user_constraints where constraint_type = 'R';
CONSTRAINT_NAME STATUS
------------------------------ --------
SYS_C004733 ENABLED <<<== original constraint
T1_NEW_FK DISABLED
SYS_C004734 ENABLED
T2_NEW_FK DISABLED
begin
dbms_redefinition.sync_interim_table( user, 'T', 'T_INTERIM' );
end;
/
PL/SQL procedure successfully completed.
begin
dbms_redefinition.finish_redef_table( user, 'T', 'T_INTERIM' );
end;
/
PL/SQL procedure successfully completed.
select constraint_name, status from user_constraints where constraint_type = 'R';
CONSTRAINT_NAME STATUS
------------------------------ --------
SYS_C004733 DISABLED <<< flip flopped the status
T1_NEW_FK ENABLED
SYS_C004734 DISABLED
T2_NEW_FK ENABLED
drop table t_interim cascade constraints;
select constraint_name, status from user_constraints where
constraint_type = 'R';
CONSTRAINT_NAME STATUS
------------------------------ --------
T1_NEW_FK ENABLED
T2_NEW_FK ENABLED

How can I store NULLs in NOT NULL field?

I just came across NULL values in NOT-NULL fields in our test database. How could they get there? I know that NOT-NULL constraints can be altered with NOVALIDATE clause, but that would change table's last_ddl_time in USER_OBJECTS. And that time is less than the date that those records were created. Is there something else I'm overlooking? Or is that someone's manual work for sure?
Table is partitioned and index-organized if that is relevant.
Oracle version is 9.2
The NOT NULL column condition is not like other constraints: you can disable a NOT NULL constraint but the column won't be considered NOT NULL if you reenable the constraint with NOVALIDATE. Let's build a small example:
SQL> CREATE TABLE tt (ID NUMBER NOT NULL);
Table created
SQL> SELECT column_name, nullable FROM user_tab_columns WHERE table_name = 'TT';
COLUMN_NAME NULLABLE
------------------------------ --------
ID N
now if I disable the constraint and reenable it with NOVALIDATE, the column won't be considered NOT NULLABLE by Oracle:
SQL> SELECT constraint_name, search_condition
2 FROM user_constraints WHERE table_name = 'TT';
CONSTRAINT_NAME SEARCH_CONDITION
------------------------------ ----------------------------
SYS_C00786538 "ID" IS NOT NULL
SQL> ALTER TABLE tt MODIFY CONSTRAINT SYS_C00786538 DISABLE;
Table altered
SQL> ALTER TABLE tt MODIFY CONSTRAINT SYS_C00786538 ENABLE NOVALIDATE;
Table altered
SQL> SELECT column_name, nullable FROM user_tab_columns WHERE table_name = 'TT';
COLUMN_NAME NULLABLE
------------------------------ --------
ID Y
So, I would say that if you have NULL values in a NOT NULLABLE column (as per my last query) you have a bug (contact support?)
Check If the constraint are suspended / Disabled
And you're sure these columns are really null? In other words:
SELECT field
FROM your_table
WHERE not_null_field IS NULL;
returns rows? Perhaps they've just got non-displayable data...

Resources