How to remove check constraint? - sql

I am having difficult to remove CHECK using Alter in sql. Can anyone help me please?
CREATE TABLE MyProject_COST (
ID int(4) NOT NULL UNIQUE,
detail varchar2(25) NOT NULL,
cost int(6) CONSTRAINT cost_project CHECK(cost>=500)
);
ALTER TABLE MyProject_COST ALTER COLUMN Cost int(6)

Oracle does have an alter table ... drop constraint syntax for this.
But since you created an anonymous constraint, so this is tricky - because you don't know the name of the constraint.
One option is to use dynamic SQL to retrieve the constraint name, and drop it with an execute immediate command:
declare
c_name varchar2(255 char);
begin
select c.constraint_name into c_name
from all_constraints c
join all_cons_columns cc
on cc.table_name = c.table_name
and cc.constraint_name = c.constraint_name
where
cc.table_name = 'MYPROJECT_COST'
and cc.column_name ='COST'
and c.constraint_type = 'C' ;
if c_name is not null then
execute immediate
'alter table myproject_cost drop constraint "' || c_name || '"';
end if;
end;
/
Demo on DB Fiddle:
create table myproject_cost (
id int not null unique,
detail varchar2(25) not null,
cost int check(cost >= 500)
);
insert into MyProject_COST(id, detail, cost) values(1, 'foo', 0);
-- ORA-02290: check constraint (FIDDLE_XUVVCZVSYWWROHKPBFUF.SYS_C0030623) violated
declare
c_name varchar2(255 char);
begin
select c.constraint_name into c_name
from all_constraints c
join all_cons_columns cc
on cc.table_name = c.table_name
and cc.constraint_name = c.constraint_name
where
cc.table_name = 'MYPROJECT_COST'
and cc.column_name ='COST'
and c.constraint_type = 'C' ;
if c_name is not null then
execute immediate
'alter table myproject_cost drop constraint "' || c_name || '"';
end if;
end;
/
-- 1 rows affected
insert into MyProject_COST(id, detail, cost) values(1, 'foo', 0);
-- 1 rows affected

Related

How to name the constraint when add NOT NULL on ALTER TABLE

ALTER TABLE ACTOR MODIFY FIRST_NAME VARCHAR2(45) NOT NULL;
I know have to set FIST_NAME to NOT NULL, but I don not know how to name this constraint.
The name of this constraint should be "CK_Fanme"
You can use
ALTER TABLE actor MODIFY ( first_name CONSTRAINT not_null_first_name NOT NULL );
and query to see the result through use of user_constraints data dictionary view such as
SELECT constraint_name
FROM user_constraints
WHERE table_name = 'ACTOR'
Demo

Stored procedure for deleting records in Oracle DBMS

Trying to figure out how to create a stored procedure that will delete a customer from the customer table, customer_order table and line_item table. Here are the tables.
CREATE TABLE customer(
customer_ID DECIMAL(10) NOT NULL,
customer_first VARCHAR(30),
customer_last VARCHAR(40),
customer_total DECIMAL(12, 2),
PRIMARY KEY (customer_ID));
CREATE TABLE customer_order (
order_id DECIMAL(10) NOT NULL,
customer_id DECIMAL(10) NOT NULL,
order_total DECIMAL(12,2),
order_date DATE,
PRIMARY KEY (ORDER_ID),
FOREIGN KEY (CUSTOMER_ID) REFERENCES customer);
CREATE TABLE line_item(
order_id DECIMAL(10) NOT NULL,
item_id DECIMAL(10) NOT NULL,
item_quantity DECIMAL(10) NOT NULL,
line_price DECIMAL(12,2),
PRIMARY KEY (ORDER_ID, ITEM_ID),
FOREIGN KEY (ORDER_ID) REFERENCES customer_order,
FOREIGN KEY (ITEM_ID) REFERENCES item);
Here what I have so far for the SP
CREATE OR REPLACE PROCEDURE DELETE_CUSTOMER(
customer_id_arg IN DECIMAL,
first_name_arg IN VARCHAR,
last_name_arg IN VARCHAR
) IS
BEGIN
DELETE FROM CUSTOMER
WHERE customer_id IN (SELECT customer_last
FROM Customer
WHERE customer_id = customer_id_arg);
END;
When I try to run it, it doesn't delete a record and I am confused as for what to do.
Here a sample code to delete data from a parent table cascading to all child tables using the database_dictionary, I had lots of fun writing it ;-)
Note the last line delete from person where pk = '38B567E2909447868ABDDF500B78F2A3'; can easily be generalised. Another thing to add, this script doesn't work if you have primary constraints of two columns or more...
declare
TYPE cur_typ IS REF CURSOR;
procedure delete_from_sub_table_first(p_current_table_name varchar2, l_parent_key_value varchar2) is
c cur_typ;
child_table_pm_key_value varchar2(255);
begin
for childConsRecord in (select ac.table_name child_table, acc.column_name Child_column, rac.table_name, racc.COLUMN_NAME, (select column_name from ALL_CONS_COLUMNS accpm, all_constraints acpm where accpm.constraint_name = acpm.constraint_name and acpm.CONSTRAINT_TYPE = 'P' and ac.TABLE_NAME = acpm.TABLE_NAME) child_table_pm_key
from ALL_CONS_COLUMNS acc, all_constraints ac, ALL_CONS_COLUMNS racc, all_constraints rac
where acc.CONSTRAINT_NAME = ac.CONSTRAINT_NAME
and ac.CONSTRAINT_TYPE = 'R'
and racc.CONSTRAINT_NAME = rac.CONSTRAINT_NAME
and rac.constraint_name = ac.R_CONSTRAINT_NAME
and rac.table_name = p_current_table_name) loop
OPEN c FOR 'select ' || childConsRecord.child_table_pm_key || ' child_value FROM ' || childConsRecord.child_table || ' where ' || childConsRecord.Child_column || ' = :1' using l_parent_key_value;
LOOP
FETCH c INTO child_table_pm_key_value;
EXIT WHEN c%NOTFOUND;
-- process row here
delete_from_sub_table_first(childConsRecord.child_table, child_table_pm_key_value);
END LOOP;
close c;
EXECUTE IMMEDIATE 'DELETE FROM ' || childConsRecord.child_table || ' where ' || childConsRecord.Child_column || ' = :1' using l_parent_key_value;
end loop;
end;
begin
delete_from_sub_table_first('PERSON', '38B567E2909447868ABDDF500B78F2A3');
delete from person where pk = '38B567E2909447868ABDDF500B78F2A3';
end;
/

Drop foreign-key constraint

How to drop a foreign key if I have not named it during creation
create table abc(
id number(10),
foreign key (id) references tab(roll)
);
even
alter table abc drop foreign key mn_ibfk_1;
is not working for me. I am using Oracle 10g.
As you did not specify a constraint name, Oracle generated one for you (something like SYS_034849548).
You need to find the constraint name in order to be able to drop it:
select constraint_name
from user_constraints
where table_name = 'ABC'
and constraint_type = 'R'
will display the constraint name. Then you can drop the constraint using:
alter table abc drop constraint <constraint_name>;
(replace <constraint_name> with the name you retrieved using the SQL statement)
Note that the syntax is alter table ... drop constraint. There is no drop foreign key.
Try this
alter table mn drop constraint mn_ibfk_1;
to find out for sure the name of the constraint try this query
SELECT a.table_name child_table,
b.table_name parent_table,
a.constraint_name child_constraint,
b.constraint_name parent_constraint,
c.column_name child_column,
d.column_name parent_column
FROM user_constraints a,
user_constraints b,
user_cons_columns c,
user_cons_columns d
WHERE a.constraint_type = 'R'
AND b.constraint_type = 'P'
AND b.constraint_name = a.r_constraint_name
AND A.table_name = c.table_name
AND b.table_name = d.table_name
AND a.constraint_name = c.constraint_name
AND b.constraint_name = d.constraint_name
AND c.position = d.position
AND a.table_name = 'mn' ;

How to delete all referential tables in Oracle?

I have table test0. This table referenced by tables:
test1
test2
test3
....
test150
Does it possible write simple short query to delete 1 row in table test0 and if they exist - in all tables test1 ... test150 ?
Try this function to get delete script for all of the child rows of the given parent row:
Create or replace
FUNCTION FN_GET_DELETE_SCRIPT
( Parent_ID IN VARCHAR2, Parent_Table_Name in varchar2
) RETURN varchar2
AS
sql_statement varchar2(200);
script varchar2(4000);
n pls_integer;
Tot Pls_Integer := 0;
Cc_Id Varchar2(500):=Null;
Cursor allTables
Is
Select uc.table_name , ac.column_name
from user_constraints uc , ALL_CONS_COLUMNS AC
Where
R_Constraint_Name = (Select Constraint_Name From User_Constraints Where Constraint_Type = 'P' And Table_Name = upper(Parent_Table_Name))
And Ac.Owner = Uc.Owner
And AC.constraint_name = uc.constraint_name;
Begin
for t in allTables loop
execute immediate 'select count(*) from '||t.table_name ||' where '||t.column_name||' = :1' into n using Parent_ID;
If N > 0 Then
script:='Delete From ' ||t.table_name||' Where '||t.column_name||'='''||Parent_ID||''';'||chr(10)||script;
End if;
End loop;
Return Script;
END FN_GET_DELETE_SCRIPT;
Note that this function gives you a delete script for deleting immediate children of the given parent row.
So this function needs a bit of modification to find all descendants of the given parent rows!
Try like this
CREATE TABLE supplier
( supplier_id numeric(10) not null,
supplier_name varchar2(50) not null,
contact_name varchar2(50),
CONSTRAINT supplier_pk PRIMARY KEY (supplier_id)
);
CREATE TABLE products
(product_id numeric(10) not null,
supplier_id numeric(10) not null,
CONSTRAINT fk_supplier
FOREIGN KEY (supplier_id)
REFERENCES supplier(supplier_id)
ON DELETE CASCADE
);
According to your requirement first drop all constraints and recreate them using on delete cascade as shown in above axample
Delete the supplier, and it will delate all products for that supplier
but be careful while using on delete cascade "You can, by mistake, delete half of your database without even realizing it"
You can do:
alter table table_name drop constraint constraint_name; and then add new constraint with on delete cascade.

How to view all the Metadata of columns of a table in oracle database?

I want to know the Query that allows us to view all the columns that are defined for a table in oracle database.
Elaboration:
Table Name: Some_Table have 10 columns.
I want to know how I can retrieve the all column names, their data type, and any constraints that are defined for any column.
I want to know how I can retrieve the all column names, their data type, and any constraints that are defined for any column.
To do that you can query(depending on privileges granted to you) [user|all|dba]_tab_columns, [user|all|dba]_cons_columns, [user|all|dba]_constraints views.
Here is a quick example:
select decode( t.table_name
, lag(t.table_name, 1) over(order by t.table_name)
, null
, t.table_name ) as table_name -- <- just to eliminate
, t.column_name -- repeated tab_name
, t.data_type
, cc.constraint_name
, uc.constraint_type
from user_tab_columns t
left join user_cons_columns cc
on (cc.table_name = t.table_name and
cc.column_name = t.column_name)
left join user_constraints uc
on (t.table_name = uc.table_name and
uc.constraint_name = cc.constraint_name )
where t.table_name in ('EMPLOYEES', 'DEPARTMENTS');
Result:
TABLE_NAME COLUMN_NAME DATA_TYPE CONSTRAINT_NAME CONSTRAINT_TYPE
------------- ----------------- -------------- -------------------------------
DEPARTMENTS LOCATION_ID NUMBER DEPT_LOC_FK R
DEPARTMENT_ID NUMBER DEPT_ID_PK P
DEPARTMENT_NAME VARCHAR2 DEPT_NAME_NN C
MANAGER_ID NUMBER DEPT_MGR_FK R
EMPLOYEES SALARY NUMBER EMP_SALARY_MIN C
PHONE_NUMBER VARCHAR2
EMPLOYEE_ID NUMBER EMP_EMP_ID_PK P
DEPARTMENT_ID NUMBER EMP_DEPT_FK R
JOB_ID VARCHAR2 EMP_JOB_FK R
MANAGER_ID NUMBER EMP_MANAGER_FK R
COMMISSION_PCT NUMBER
FIRST_NAME VARCHAR2
JOB_ID VARCHAR2 EMP_JOB_NN C
HIRE_DATE DATE EMP_HIRE_DATE_NN C
EMAIL VARCHAR2 EMP_EMAIL_NN C
LAST_NAME VARCHAR2 EMP_LAST_NAME_NN C
EMAIL VARCHAR2 EMP_EMAIL_UK U
17 rows selected
Also to retrieve a complete specification(if needed) of a table, you can use dbms_metadata package and get_ddl function of that package:
select dbms_metadata.get_ddl('TABLE', 'EMPLOYEES') as table_ddl
from dual;
table_ddl
--------------------------------------------------------------------------------
CREATE TABLE "HR"."EMPLOYEES"
("EMPLOYEE_ID" NUMBER(6,0),
"FIRST_NAME" VARCHAR2(20),
"LAST_NAME" VARCHAR2(25) CONSTRAINT "EMP_LAST_NAME_NN" NOT NULL ENABLE,
"EMAIL" VARCHAR2(25) CONSTRAINT "EMP_EMAIL_NN" NOT NULL ENABLE,
"PHONE_NUMBER" VARCHAR2(20),
"HIRE_DATE" DATE CONSTRAINT "EMP_HIRE_DATE_NN" NOT NULL ENABLE,
"JOB_ID" VARCHAR2(10) CONSTRAINT "EMP_JOB_NN" NOT NULL ENABLE,
"SALARY" NUMBER(8,2),
"COMMISSION_PCT" NUMBER(2,2),
"MANAGER_ID" NUMBER(6,0),
"DEPARTMENT_ID" NUMBER(4,0),
CONSTRAINT "EMP_SALARY_MIN" CHECK (salary > 0) ENABLE,
CONSTRAINT "EMP_EMAIL_UK" UNIQUE ("EMAIL")
-- ... other attributes
)
select * from all_tab_columns where table_name='YOUR_TABLE_NAME_IN_CAPS';
-- NOTE:
-- all_tab_columns is a SYSTEM defined Meta Data Table.
-- table_name is also a SYSTEM Command.
-- Don't forget to write your table name in caps as it's case-sensitive.