oracle培訓第三天

1.約束
約束是數據庫能夠實現業務規則以及保證數據遵循ER模型的一種手段。

約束的語法
列級約束:只能引用一個列,表中可以有多個列級約束
表級約束:引用一個或多個列,通常用來定義主鍵
追加約束:建表後,再通過alter table追加約束


select * from user_constraints;
select * from user_cons_columns;


五種約束的語法
非空約束
列級定義
create table student(no int not null,name varchar(40));

追加非空約束
alter table emp1 modify ename not null;
select * from user_constraints
alter table emp1 modify ename null
alter table emp1 modify ename constraint c_emp1_ename not null;
select * from user_constraints

唯一性約束

列級定義
drop table student;
create table student(no int unique,name varchar(40));
insert into student
values(null,'zzl');
insert into student
values(null,'z');
insert into student
values(1,'zzl');
insert into student
values(1,'z');
表級定義
drop table student;
create table student(no int ,name varchar(40),constraint c_uno unique(no));


追加定義
drop table student;
create table student(no int ,name varchar(40));
alter table student add constraint c_uno unique(no);


主鍵約束
每個表只能建立一個主鍵約束 primary key = unique + not null
主鍵列上需要索引,如果該列沒有索引,則自動創建unique索引,
主鍵約束和唯一約束不能同時建立在一個列上

主鍵約束的六種寫法;
列級定義
drop table student
create table student(no int primary key,name varchar(40));
drop table student
create table student(no int constraint pk_student primary key,name varchar(40));
表級定義
drop table student
create table student(no int,name varchar(40),primary key (no));
drop table student
create table student(no int,name varchar(40),constraint pk_studnet primary key (no));

追加定義
drop table student;
create table student(no int,name varchar(40));
alter table student add primary key (no);
drop table student;
create table student(no int,name varchar(40));
alter table student add constraint pk_student primary key (no);



主鍵和索引關聯的問題
drop table student
create table student(no int ,name varchar(40));
create index index_student_no on student(no);
alter table student add constraint pk_no primary key (no);
drop table student;
create table student(no int ,name varchar(40));
create index index_student_no on student(no);
alter table student add constraint pk_no primary key (no) using index index_student_no;
alter table student drop constraint pk_no;
select * from user_indexes where table_name ='STUDENT';

create table student(no int,name varchar(40),constraint pk_studnet primary key (no) using index(create index index_student_no on student(no)
));



外鍵約束
作用,是爲了和同一個表或其他表的主鍵建立連接關係,外鍵值必須和父表中的值匹配或者爲空

外鍵約束和unique約束都可以有空值
外鍵需要參考主鍵的約束,但也可以參考唯一鍵約束
外鍵和主鍵一般分別在兩個不同的表中,但也可以同處在一個表中


drop table emp1;
create table emp1 as select * from emp;
create table dept1 as select * from dept;

列級定義:
alter table dept1 add constraint pk_dept1 primary key (deptno);
create table emp2 (empno int ,deptno int references dept1(deptno),deptno2 int);

表級定義
create table emp3(empno int ,deptno int,foreign key (deptno) references dept1(deptno));

追加定義
alter table emp1 add constraint fk_emp1 foreign key(deptno) references dept1(deptno);


insert into emp3 values(1,99);

insert into emp3 values(1,null);

delete from dept1 where deptno =10;
alter table emp1 drop constraint fk_emp1;
alter table emp1 add constraint fk_emp1 foreign key(deptno) references dept1(deptno) on delete cascade;

delete from dept1 where deptno =10;
select * from emp1;

alter table emp1 drop constraint fk_emp1;
alter table emp1 add constraint fk_emp1 foreign key(deptno) references dept1(deptno) on delete set null;

delete from dept1 where deptno =10;
select * from emp1;

check 約束
列級定義
create table emp4(empno int ,sal int check(sal>0),comm int)
表級定義
create table emp5(empno int ,sal int,comm int, check(sal>5000))
追加定義
alter table emp5 add constraint e_no_ck check(empno is not null)

insert into emp5
values(null,1,1);

check約束中的表達式中不能使用變量日期函數
alter table emp1 add constraint emp_chk_date check (hiredate < sysdate);
alter table emp1 add constraint emp_chk_date check (hiredate < to_date('2016.08.16','yyyy.mm.dd'))


級聯約束
drop table test;
create table test(
pk number primary key,
fk number,
col1 number,
col2 number,
constraint fk_constraint foreign key (fk) references test,
constraint ck1 check(pk >0 and col1 >0),
constraint ck2 check(col2 > 0)
)


alter table test drop column col2;

alter table test drop column fk;
alter table test drop column pk;
alter table test drop column col1;

alter table test drop column pk cascade constraint//級聯

alter table test drop column col1 cascade constraint



約束的四種狀態
enable validate :無法輸入違反約束的行,而且表中所有行都要符合約束
enable novalidate:表中可以存在不符合約束的狀態,但對新加入數據必須符合約束條件
disable novalidate:可以輸入任何數據,表中或已存在不符合約束條件的數據
disable validate:不能對錶進行插入,更新,刪除等操作,相當於對整個表的read only 設定。

drop table emp1;
create table emp1 as select * from emp;

update emp1 set empno =NULL where empno =7900

select * from emp1
alter table emp1 add constraint ck_emp1 check (empno is not null);
alter table emp1 add constraint ck_emp1 check (empno is not null) enable novalidate;
insert into emp1(empno)
values(null);

將disable novalidate,enable novalidate,enable validate 三種狀態組合起來使用
這種組合,可以避免因有個別不符合條件的數據,而導致大數據量的傳輸失敗
假設a表示源數據,其中有空值,b表示a表的歸檔表,設有非空約束,現將a表插入到b表中

alter table b modify constraint b_nnl disable ,novalidate;
insert into b select * from a;
alter table b modify constraint b_nnl enable,novalidate;

update b set channel = 'NOT KNOWN' where channel is null;
alter table b modify constraint b_nnl enable ,validate;



延遲約束
alter table emp1 add constraint chk_sal check(sal > 500) deferrable;//延遲約束
insert into emp1(empno,sal)
values(3030,100);

set constraint chk_sal immediate;
insert into emp1(empno,sal)
values(3030,100)

set constraint chk_sal deferred;//延遲
insert into emp1(empno,sal)
values(3030,100)


alter table emp1 drop constraint chk_sal;
alter table emp1 add constraint chk_sal check(sal > 500) deferrable initially immediate;
insert into emp1(empno,sal)
values(3030,100);

alter table emp1 drop constraint chk_sal;
alter table emp1 add constraint chk_sal check(sal > 500) deferrable initially deferred;
insert into emp1(empno,sal)
values(3030,100);

2.視圖
爲什麼使用視圖
1)限制數據的存取
用戶只能看到基表的部分信息。方法:賦予用戶訪問視圖對象的權限,而不是表的對象權限
2)使得複雜的查詢變得容易
對於多表連接等複雜語句的映射,或內聯視圖的使用
3)提供數據的獨立性
基表的多個獨立子集的映射


簡單視圖
視圖與基表的記錄一對一,故可以通過視圖修改表


複雜視圖
視圖與基表的記錄一對多,無法修改視圖

特性          簡單視圖        複雜視圖
表的個數      一個            一個或多個
含函數        無              有
含組函數     無               有
含distinct   無               有
DML操作     可以             不一定


語法
create [or replace] [force|noforce] view view_name
[(alias[,alias],...)]
as subquery
[with check option [constraint constraint]]
[with read only];



create view v1 as select empno,sal,deptno from emp1 where deptno =10;

select * from user_views
create view v2 as select empno,sal,sal+100,deptno from emp1 where deptno =10;
create view v2 as select empno,sal,sal+100 as sal2,deptno from emp1 where deptno =10;
create view v3(a1,a2,a3,a4) as select empno,sal,sal+100 ,deptno from emp1 where deptno =10;

drop view v1;
drop table emp1;
create view v3(a1,a2,a3,a4) as select empno,sal,sal+100 ,deptno from emp1 where deptno =10;
create force view v3(a1,a2,a3,a4) as select empno,sal,sal+100 ,deptno from emp1 where deptno =10;
select * from v3
flashback table emp1 to before drop
select * from v3

update v3 set a4=99
select * from v3;
select * from emp1;

--with check option
create or replace view v3(a1,a2,a3,a4) as select empno,sal,sal+100 ,deptno from emp1 where deptno =10 with check option;
update v3 set a4=99
update emp1 set deptno =10 where deptno =99
update v3 set a4=99
update v3 set a1=a1+100

grant connect,resource to zzl identified by bsoft
grant select on v3 to zzl

--zzl用戶
select * from scott.v3
select * from scott.emp1;

複雜視圖
drop table emp1;
drop table dept1;
create table emp1 as select * from emp;
create table dept1 as select * from dept;
create or replace view v5 as select empno,dname from emp1,dept1 where emp1.deptno = dept1.deptno and emp1.deptno =10;
select * from v5
update v5 set dname =3030


  
3.同義詞
同義詞通常是數據庫對象的別名
公有同義詞
公有同義詞一般有DBA創建,使所有用戶都可使用
create user zzl identified by bsoft;
select * from session_privs
grant create session to zzl;
select * from session_privs

創建者需要有create public synonym權限
create public synonym syn1 for scott.v3
--grant select on syn1 to public
--grant public to zzl
zzl用戶執行
select * from syn1;
select * from scott.v3;
--revoke public from zzl;
select * from syn1;
select * from scott.v3;

私有同義詞
create synonym abc for emp1;
grant select on abc to zzl;
select * from scott.abc
select * from scott.emp1
revoke select on abc from zzl
select * from scott.abc
select * from scott.emp1
grant select on emp1 to zzl
select * from scott.abc
select * from scott.emp1

4.序列
create sequence seq1
select seq1.currval from dual;
select seq1.nextval from dual;
select seq1.currval from dual;

create sequence seq2 start with 10 increment by 2 maxvalue 20 cycle nocache;
select seq2.nextval from dual;
alter sequence seq2 increment by 1;
select seq2.nextval from dual
alter sequence seq2 start with 19
select * from user_sequences
drop sequence seq2




5.insert 總結

一次插入一行
create table test(id int,name varchar(10) default 'zzl');

insert into test values(1,'abc');
insert into test values(2,default);
insert into test values(3,null);
insert into test(id) values(4);
insert into (select id from test) values(5);
insert into test values(6,(select dname from dept where deptno =10))


insert with check option
insert into (select id from test where id <10 with check option ) values(10);
insert into (select id from test where id <10 with check option ) values(9);
insert into (select name from test where id <10 with check option ) values('zzl');
insert into (select name from test where id <10  ) values('zzl');
insert into (select id,name from test where id <10 with check option ) values(9,'zzl');
update (select sal from emp1) set sal=(select sal from emp1 where empno =7788);
update (select ename from emp1) set sal=(select sal from emp1 where empno =7788);
delete (select sal from emp1) where sal >3000;


一次插入多行
create table emp1 as select * from emp
insert into emp1 select * from emp where deptno =10;


multiable insert
insert all 

create table test(x number(10),y varchar2(10));
insert into test values(1,'a');
insert into test values(2,'b');
insert into test values(3,'c');
insert into test values(4,'d');
insert into test values(5,'e');
insert into test values(6,'f');
commit;

create table test1 as select * from test where 0=1;
create table test2 as select * from test where 0=1;

insert all into test1 into test2 select * from test;

select * from test1;
select * from test2;



delete from test1;
delete from test2;

insert all when x >= 3 then into test1 when x >=2 then into test2 select * from test;


insert first
delete from test1;
delete from test2;

insert first when x >= 3 then into test1 when x >=2 then into test2 select * from test;


旋轉insert
create table test(empno number(10),week_id number(2),
sal_mon number(8,2),sal_tun number(8,2),
sal_wed number(8,2),sal_thur number(8,2),sal_fri number(8,2))

insert into test values(3030,56,1000,2000,3000,4000,5000)

create table test2(empno number(10),week number(2),sales number(8,2))



insert all
into test2 values(empno,week_id,sal_mon)
into test2 values(empno,week_id,sal_tun)
into test2 values(empno,week_id,sal_wed)
into test2 values(empno,week_id,sal_thur)
into test2 values(empno,week_id,sal_fri)
select empno,week_id,sal_mon,sal_tun,sal_wed,sal_thur,sal_fri from test;



merge
create table emp1 as select * from emp where empno =7788
update emp1 set ename = 'aaa'

insert into emp1(empno,ename)
values(7900,'zzl')
select * from emp1

merge into emp1
using emp
on (emp1.empno = emp.empno)
when matched  then
update set emp1.ename = emp.ename
delete where emp1.empno =7900
when not matched then
insert values(emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,emp.sal,emp.comm,emp.deptno)


6.with 語句
我們可以用一個關鍵字with給一個查詢塊起一個別名。然後在後面的查詢中引用這個查詢塊的別名。
好處:
1.使用with語句,可以避免在select語句中重複書寫相同的語句塊
2.with語句將該子句中的語句塊執行一次並存儲到用戶的臨時表空間中
3.使用with語句可以避免重複解析,提高查詢效率


with
dept_costs as(
select d.dname,sum(e.sal) as dept_total
from emp e,dept d
where e.deptno = d.deptno
group by d.dname),
avg_cost as(
select sum(dept_total)/count(*) as dept_avg from dept_costs)
select * from dept_costs 
where dept_total < (select dept_avg from avg_cost)
order by dname

發佈了43 篇原創文章 · 獲贊 30 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章