Class Exer,CHAPTER 12 -- ALTERING TABLES (COLUMNS and

advertisement
Class Exer,CHAPTER 13 -- ALTERING TABLES (COLUMNS and CONSTRAINTS)
=================================================================
SQL> SET PAGESIZE 200
SQL> SELECT TNAME FROM TAB;
TNAME
-----------------------------BIN$HS7ZCdo/azLgQKjAUQJLcw==$0
BIN$HS7ZCdo3azLgQKjAUQJLcw==$0
BIN$HS7ZCdoYazLgQKjAUQJLcw==$0
BIN$HS7ZCdofazLgQKjAUQJLcw==$0
BIN$HS7ZCdokazLgQKjAUQJLcw==$0
BIN$HS7ZCdoyazLgQKjAUQJLcw==$0
BIN$HTBCOUh5/rzgQKjAUQJSOw==$0
BIN$HTBCOUiA/rzgQKjAUQJSOw==$0
BIN$HTBCOUiF/rzgQKjAUQJSOw==$0
BIN$HTBCOUiT/rzgQKjAUQJSOw==$0
COUNTRIES
CUST
DEPART
DEPARTMENTS
EMPL
EMPLOYEES
JOB_GRADES
JOB_HISTORY
LOCATIONS
MY_EMPLOYEE
 PREVIOUSLY REMOVED (DROPPED) TABLES
BUT NOT PURGED YET
20 rows selected.
SQL> DESC depart
Name
----------------------------------------DEPT#
DNAME
CITY
SQL> DESC empl
Name
----------------------------------------EMP#
LNAME
FNAME
PAY
SDATE
JOB
DEPT#
Null?
-------NOT NULL
NOT NULL
Null?
-------NOT NULL
NOT NULL
NOT NULL
NOT NULL
NOT NULL
Type
-------------------NUMBER(4)
VARCHAR2(25)
VARCHAR2(20)
Type
-------------------NUMBER(7)
VARCHAR2(20)
VARCHAR2(20)
NUMBER(7,2)
DATE
VARCHAR2(15)
NOT NULL NUMBER(4)
SQL> DESC cust
Name
----------------------------------------CUST#
CUSTNAME
CITY
RATING
COMMENTS
SALESREP#
Null?
-------NOT NULL
NOT NULL
NOT NULL
Type
-------------------NUMBER(6)
VARCHAR2(30)
VARCHAR2(20)
CHAR(1)
VARCHAR2(200)
NUMBER(7)
SQL> ALTER TABLE depart
2 ADD COLUMN (PROVINCE CHAR(2) NOT NULL);
ADD COLUMN (PROVINCE CHAR(2) NOT NULL)
*
ERROR at line 2:
ORA-00904: : invalid identifier  you must NOT use word COLUMN here
SQL> ALTER TABLE depart
2* ADD (PROVINCE CHAR(2) NOT NULL);
ALTER TABLE depart
*
ERROR at line 1:
ORA-01758: table must be empty to add mandatory (NOT NULL) column
SQL> ALTER TABLE depart
2* ADD (PROVINCE CHAR(2));
Table altered.
 to non-empty tables you may add only optional columns
SQL> ALTER TABLE empl
2 MODIFY (sdate NULL);
Table altered.
 it is always possible to declare a mandatory column to become optional
SQL>ALTER TABLE empl
2* MODIFY (job VARCHAR2(20));
Table altered.
 it is always possible to increase the column length
SQL> ALTER TABLE empl
2* MODIFY (job VARCHAR2(12));
Table altered.
 it is possible to decrease the column length up to the value that no
existing column value will go over
SQL> ALTER TABLE cust
2 SET UNUSED comments;
SET UNUSED comments
*
ERROR at line 2:
ORA-00905: missing keyword  here you must use word COLUMN
SQL> ALTER TABLE cust
2* SET UNUSED COLUMN comments ;
Table altered.
SQL> SELECT custname, comments FROM cust;
SELECT custname, comments FROM cust
*
ERROR at line 1:
ORA-00904: "COMMENTS": invalid identifier
 after column has been unset, it is promptly removed logically from the
dictionary, but it must be later also physically removed from disk
SQL> ALTER TABLE cust
2 DROP UNUSED COLUMNS;
Table altered.
SQL> DESC depart
Name
----------------------------------------DEPT#
DNAME
CITY
PROVINCE
SQL> DESC empl
Name
----------------------------------------EMP#
LNAME
FNAME
PAY
SDATE
JOB
DEPT#
SQL> DESC cust
Name
----------------------------------------CUST#
CUSTNAME
CITY
RATING
SALESREP#
Null?
-------NOT NULL
NOT NULL
Type
-------------------NUMBER(4)
VARCHAR2(25)
VARCHAR2(20)
CHAR(2)
Null?
-------NOT NULL
NOT NULL
NOT NULL
NOT NULL
Type
-------------------NUMBER(7)
VARCHAR2(20)
VARCHAR2(20)
NUMBER(7,2)
DATE
VARCHAR2(12)
NOT NULL NUMBER(4)
Null?
-------NOT NULL
NOT NULL
NOT NULL
Type
-------------------NUMBER(6)
VARCHAR2(30)
VARCHAR2(20)
CHAR(1)
NUMBER(7)
SQL> SELECT * FROM depart;
DEPT#
---------10
90
190
20
60
50
DNAME
------------------------Administration
Executive
Contracting
Marketing
IT
Shipping
CITY
PR
-------------------- -Seattle
Seattle
Seattle
Toronto
Southlake
South San Francisco
6 rows selected.
SQL> ALTER TABLE depart
2 MODIFY (city NOT NULL);
Table altered.
 it is possible to declare an optional column to become a mandatory one
if there is NO blank value in that column
SQL> INSERT INTO depart (dept#, dname) VALUES (200,'HR');
INSERT INTO depart (dept#, dname) VALUES (200,'HR')
*
ERROR at line 1:
ORA-01400: cannot insert NULL into ("OA301A40"."DEPART"."CITY")
 you must insert values into ALL MANDATORY columns (here is City column
without value and it is previously declared as a mandatory column)
SQL> INSERT INTO depart (dept#, dname,city) VALUES (200,'HR','CHICAGO');
1 row created.
SQL>
2
3
SET
UPDATE empl
SET job = 'Database Analyst'
WHERE UPPER(lname) = 'ERNST' ;
job = 'Database Analyst'
*
ERROR at line 2:
ORA-12899: value too large for column "OA301A40"."EMPL"."JOB" (actual:
16, maximum: 12)
SQL> ALTER TABLE empl
2 MODIFY (job VARCHAR2(16) );
Table altered.
 if you increase the column length then you can modify data accordingly
SQL> UPDATE empl
2 SET job = 'Database Analyst'
3 WHERE UPPER(lname) = 'ERNST';
1 row updated.
SQL> RENAME depart TO dep;
Table renamed.
 you can always rename any database object (table, view, index etc.)
SQL> SELECT * FROM empl
2 WHERE UPPER(lname) = 'ERNST';
EMP# LNAME
FNAME
PAY SDATE
---------- -------------------- -------------------- ---------- -------JOB
DEPT#
---------------- ---------104 Ernst
Bruce
6000 21-MAY-91
Database Analyst
60
SQL> REM Other session that I opened also showed "Database Analyst"
because RENAME (as DDL command) performs AUTO-COMMIT firstly
SQL> INSERT INTO cust VALUES
(&custno,'&custname','&city','&rating',&rep);
Enter value for custno: 701
Enter value for custname: BLUE SKY LTD
Enter value for city: Vancouver
Enter value for rating: B
Enter value for rep: 102
old
1: INSERT INTO cust VALUES
(&custno,'&custname','&city','&rating',&rep)
new
1: INSERT INTO cust VALUES (701,'BLUE SKY
LTD','Vancouver','B',102)
1 row created.
SQL> INSERT INTO cust VALUES
(&custno,'&custname','&city','&rating',&rep);
Enter value for custno: 702
Enter value for custname: MIKE and SAM inc.
Enter value for city: Kingston
Enter value for rating: A
Enter value for rep: 107
old
1: INSERT INTO cust VALUES
(&custno,'&custname','&city','&rating',&rep)
new
1: INSERT INTO cust VALUES (702,'MIKE and SAM
inc.','Kingston','A',107)
1 row created.
SQL> SET VERIFY OFF
 to get rid of old and new lines
SQL> INSERT INTO cust VALUES
(&custno,'&custname','&city','&rating',&rep);
Enter value for custno: 703
Enter value for custname: RED PLANET
Enter value for city: Mississauga
Enter value for rating: C
Enter value for rep: 107
1 row created.
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM cust;
CUST#
---------701
703
702
501
502
503
CUSTNAME
CITY
R
SALESREP#
------------------------------ ----------------------------BLUE SKY LTD
Vancouver
B
102
RED PLANET
Mississauga
C
107
MIKE and SAM inc.
Kingston
A
107
ABC LTD.
Montreal
C
201
Black Giant
Ottawa
B
202
Mother Goose
London
B
202
6 rows selected.
SQL> INSERT INTO cust VALUES
(&custno,'&custname','&city','&rating',&rep);
Enter value for custno: 717
Enter value for custname: BLUE SKY LTD
Enter value for city: Regina
 same Customer Name, but different city
Enter value for rating: D
Enter value for rep: 102
1 row created.
SQL> INSERT INTO cust VALUES
(&custno,'&custname','&city','&rating',&rep);
Enter value for custno: 718
Enter value for custname: Black Giant
Enter value for city: Ottawa
Enter value for rating: A
Enter value for rep: 202
INSERT INTO cust VALUES (718,'Black Giant','Ottawa','A',202)
*
ERROR at line 1:
ORA-00001: unique constraint (OA301A40.CUST_CUSTNAME_CITY_UK) violated
 there is a composite UNIQUE constraint on CustName and City, so that
you can NOT have a same customer name twice in the same city (look in
the table creation script in the Chap9 practice)
SQL> INSERT INTO cust VALUES
(&custno,'&custname','&city','&rating',&rep);
Enter value for custno: 720
Enter value for custname: Big Mouse
Enter value for city: Toronto
Enter value for rating: F
Enter value for rep: 202
INSERT INTO cust VALUES (720,'Big Mouse','Toronto','F',202)
*
ERROR at line 1:
ORA-02290: check constraint (OA301A40.CUST_RATING_CK) violated
 there is a CHECK constraint on column Rating that allows only values
from set {A,B,C,D} to be entered (but not F)
SQL> INSERT INTO cust VALUES
(&custno,'&custname','&city','&rating',&rep);
Enter value for custno: 721
Enter value for custname: Big Mouse
Enter value for city: Toronto
Enter value for rating: D
Enter value for rep: 108
INSERT INTO cust VALUES (721,'Big Mouse','Toronto','D',108)
*
ERROR at line 1:
ORA-02291: integrity constraint (OA301A40.CUST_SALESREP#_FK) violated parent key not found
 there is a FOREIGN KEY constraint on column SalesRep# that allows only
values from the set of values for Emp# column in the parent table EMPL
to be entered (and 108 does not exist as an employee there)
SQL> COMMIT;
Commit complete.
SQL> SELECT * FROM cust;
CUST#
---------701
703
717
702
501
502
503
CUSTNAME
CITY
R
SALESREP#
------------------------------ -------------------- - ------BLUE SKY LTD
Vancouver
B
102
RED PLANET
Mississauga
C
107
BLUE SKY LTD
Regina
D
102
MIKE and SAM inc.
Kingston
A
107
ABC LTD.
Montreal
C
201
Black Giant
Ottawa
B
202
Mother Goose
London
B
202
7 rows selected.
SQL> SELECT constraint_name, constraint_type, search_condition, status
FROM
user_constraints
WHERE
table_name = ‘CUST’
ORDER BY 2;
CONSTRAINT_NAME
CON
SEARCH_CONDITION
STATUS
SYS_C0070132
C
"CUSTNAME" IS NOT NULL
ENABLED
SYS_C0070133
C
"CITY" IS NOT NULL
ENABLED
CUST_RATING_CK
C
Rating IN ('A','B','C','D')
ENABLED
CUST_CUST#_PK
P
ENABLED
CUST_SALESREP#_FK
R
ENABLED
CUST_CUSTNAME_CITY_UK
U
ENABLED
6 rows selected.
 This is the query you may use to find out what constraints are
declared for a table and what is their status and for CHECK (C)
constraints only what is their search condition.
SQL> ALTER TABLE cust DISABLE CONSTRAINT
cust_salesrep#_fk;
Table altered.
SQL> UPDATE cust
SET
salesrep# = 108
WHERE cust# = 501;
 non-existing value in table EMPL
1 row updated.
 The FK constraint is turned off (disabled) and we can put for
salesrep# any value we want (and 108 does not exist in a table EMPL)
SQL> ALTER TABLE cust ENABLE CONSTRAINT
ALTER TABLE cust ENABLE CONSTRAINT
cust_salesrep#_fk;
cust_salesrep#_fk
*
ERROR at line 1:
ORA-02298: cannot validate (OA301B40.CUST_SALESREP#_FK) - parent keys not found
 As any DDL statement, ALTER TABLE firstly auto-commits anything not
saved before and then tries to execute itself (so 108 is saved as
Salesrep# firstly and then it was made an attempt to enable this
constraint that failed, because it had “violation” in that one row)
SQL> UPDATE cust
SET
salesrep# = 107
WHERE cust# = 501;
1 row updated.
 existing value in table EMPL
SQL> ALTER TABLE cust ENABLE CONSTRAINT
cust_salesrep#_fk;
Table altered.
 After fixing the row that caused the violation, the constraint can be
enabled (this is valid for any constraint type)
SQL> ALTER TABLE cust
DROP CONSTRAINT
cust_rating_ck ;
Table altered.
 You can NOT modify the constraint definition, but you need to drop and
add it again with the new definition (here we will add F to the set of
values for column Rating)
SQL> ALTER TABLE cust ADD CONSTRAINT cust_rating_ck
CHECK (rating IN ('A','B','C','D','F')) ;
Table altered.
SQL> SELECT constraint_name, constraint_type, search_condition, status
FROM
user_constraints
WHERE
table_name = ‘DEP’
ORDER BY 2;
CONSTRAINT_NAME
SYS_C0070121
CON
SEARCH_CONDITION
C
"DNAME" IS NOT NULL
STATUS
ENABLED
SYS_C0070138
C
ENABLED
DEPART_DEPT#_PK
P
ENABLED
DEPART_DNAME_UK
U
ENABLED
SQL> ALTER TABLE dep
"CITY" IS NOT NULL
DROP CONSTRAINT depart_dname_uk ;
Table altered.
 Let’s change the UK constraint from single to composite one, so that
you can have only one department name in the same city.
SQL> ALTER TABLE dep ADD CONSTRAINT dep_dname_uk
UNIQUE (dname, city);
Table altered.
Download