備註:要進行下面的相關操作練習,請使用oracle內置的帳號scott/tiger進行登錄。下面示例中所用到的表主要是scott內置帳戶提供的emp和dept兩張表。
一、視圖和索引的使用
1、視圖
視圖的語法(視圖的創建必須要有dba的權限)
create view 視圖名稱 as 查詢語句 with read only
案例
create view v_emp as select ename, job from emp
規範:視圖的名稱一般情況下,是由v_加上要查詢的表的表名組成。
eg:視圖的數據來源emp表和user表 -------> v_emp_user
—視圖的作用?
—第一:視圖可以屏蔽掉一些敏感字段。
—第二:保證總部和分部數據及時統一。
2、索引
索引的作用:提高查詢效率。
通過索引提高查詢效率,也是實際開發中,最常用的一種方式。
索引有兩種方式:單列索引和複合索引。
---單列索引
---創建單列索引
create index idx_ename on emp(ename);
---單列索引觸發規則,條件必須是索引列中的原始值。
---單行函數,模糊查詢,都會影響索引的觸發。
select * from emp where ename='SCOTT'
---複合索引
---創建複合索引
create index idx_enamejob on emp(ename, job);
---複合索引中第一列爲優先檢索列
---如果要觸發複合索引,必須包含有優先檢索列中的原始值。
select * from emp where ename='SCOTT' and job='xx';---觸發複合索引
select * from emp where ename='SCOTT' or job='xx';---不觸發索引
select * from emp where ename='SCOTT';---觸發單列索引。
3、oracle中的變量的定義
語法
變量的定義: 變量名 變量類型(oracle中的常用的4種類型:number varchar2 data blob)
變量的賦值 : := value
案例
---賦值操作可以使用:=也可以使用into查詢語句賦值
declare
i number(2) := 10;
s varchar2(10) := '小明';
ena emp.ename%type;---引用型變量
emprow emp%rowtype;---記錄型變量
begin
dbms_output.put_line(i);
dbms_output.put_line(s);
select ename into ena from emp where empno = 7788;
dbms_output.put_line(ena);
select * into emprow from emp where empno = 7788;
dbms_output.put_line(emprow.ename || '的工作爲:' || emprow.job);
end;
二、if判斷、循環和遊標的用法
1、if判斷的使用
示例
---輸入小於18的數字,輸出未成年
---輸入大於18小於40的數字,輸出中年人
---輸入大於40的數字,輸出老年人
declare
i number(3) := ⅈ -- &ii 輸入指令
begin
if i<18 then
dbms_output.put_line('未成年');
elsif i<40 then
dbms_output.put_line('中年人');
else
dbms_output.put_line('老年人');
end if;
end;
2、sql中三種循環的用法
declare
--定義各種變量
begin
--編寫各種業務代碼
end;
while循環、exist、for循環
---while循環
declare
i number(2) := 1;
begin
while i<11 loop
dbms_output.put_line(i);
i := i+1;
end loop;
end;
---exit循環
declare
i number(2) := 1;
begin
loop
exit when i>10;
dbms_output.put_line(i);
i := i+1;
end loop;
end;
---for循環
declare
begin
for i in 1..10 loop
dbms_output.put_line(i);
end loop;
end;
3、遊標的用法(理解爲集合)
遊標----- 理解爲java中的集合,在循環遊標時,可以理解遊標記錄着集合中每一行數據的下標index
---遊標:可以存放多個對象,多行記錄。
---輸出emp表中所有員工的姓名
declare
cursor c1 is select * from emp;
emprow emp%rowtype;
begin
open c1;
loop
fetch c1 into emprow;
exit when c1%notfound;
dbms_output.put_line(emprow.ename);
end loop;
close c1;
end;
-----給指定部門員工漲工資
declare
cursor c2(eno emp.deptno%type) -- 括號中的值 表示的是一個參數
is select empno from emp where deptno = eno;-- 創建一個遊標,來保存emp表中的所有empno的值
en emp.empno%type; -- 定義一個變量叫en,類型爲emp表中的empno字段的類型
begin
open c2(10); -- 打開 遊標c2
loop --開始循環
fetch c2 into en; -- 將遊標c2循環時的每一個值賦值給變量en
exit when c2%notfound; -- 當遊標c2的值爲notfound(循環到最後一行數據)跳出循環
update emp set sal=sal+100 where empno=en;-- 滿足條件時,執行的sql語句
commit; -- 提交事務
end loop; -- 結束循環
close c2; -- 結束遊標c2
end;
三、存儲過程和存儲函數的使用
1、存儲過程作用
將一段獨立邏輯預先實現先,提供給其他程序使用。(類似於java中的封裝)
示例:創建一個“給指定員工漲工資的邏輯代碼)
----給指定員工漲100塊錢
create or replace procedure p1(eno emp.empno%type)
is
begin
update emp set sal=sal+100 where empno = eno;
commit;
end;
調用上面的”存儲過程“
----測試p1
declare
begin
p1(7788);
end;
2、存儲函數的使用
要求:存儲函數的返回值 必須要被接收
存儲函數都會有一個返回值
示例: or replace 語句 都會帶上
create or replace function f_yearsal(eno emp.empno%type) return number
is(as)
s number(10);
begin
select sal*12+nvl(comm, 0) into s from emp where empno = eno;
return s;
end;
定義的函數的用法
----存儲函數在調用的時候,返回值需要接收。
declare
s number(10);
begin
s := f_yearsal(7788);
dbms_output.put_line(s);
end;
3、存儲過程中 in和out關鍵字的用法
存儲過程out關鍵字使用示例
---out類型參數如何使用
---使用存儲過程來算年薪
create or replace procedure p_yearsal(eno emp.empno%type, yearsal out number)
is
s number(10);
c emp.comm%type;
begin
select sal*12, nvl(comm, 0) into s, c from emp where empno = eno;
yearsal := s+c;
end;
示例的使用
declare
yearsal number(10);
begin
p_yearsal(7788, yearsal);
dbms_output.put_line(yearsal);
end;
存儲過程中,什麼時候使用 in ,什麼時候使用 out?
如果把存儲過程理解爲java中的一自定義方法,in 表示方法中的代碼需要使用到的 變量;
方法中賦值的變量如果要提供給調用者使用,則用 out
java示例
// sal表示員工 的月薪;comm表示員工的獎金
public void yearSal(long sal,long comm,long yearSal){
yearSal = sal * 12 + comm;
}
//上面的java代碼,表示使用一個不帶返回值的方法,給變量yearSal來賦值
小結:
無論是存儲過程,還是存儲函數,最終的作用:都是爲了在數據庫層面來實現一個獨立的業務邏輯(實現過程也可以放在java端來實現)。
四、觸發器的使用
1、觸發器的介紹
觸發器是自動觸發的
觸發器只能在數據的 增、刪和改 觸發
2、觸發器的種類:語句級觸發器和行級觸發器
語句級觸發器:
針對數據庫中數據的增、刪、改;不會使用到內置的變量 :old和:new
示例
reate or replace trigger t1 -- 創建一個名稱爲t1的觸發器
after -- 指定觸發器觸發的狀態(before和after)
insert -- 監聽操作的類型(insert / update /delete)
on person --針對哪一張表的上述3種操作
-- sql中編寫語句塊的語法
declare
begin
dbms_output.put_line('一個新員工入職');
end;
觸發器的觸發
insert into person values (1, '小紅');
commit;
行級觸發器
會使用到兩個內置的變量 :old 更新數據之前的目標字段的值 ; :new 更新數據時,傳入的 目標字段的值
示例
---raise_application_error(-20001~-20999之間, '錯誤提示信息');
create or replace trigger t2
before
update
on emp
for each row
declare
begin
if :old.sal>:new.sal then
raise_application_error(-20001, '不能給員工降薪');
end if;
end;
----觸發t2
select * from emp where empno = 7788;
update emp set sal=sal-1 where empno = 7788;
commit;
3、使用觸發器實現主鍵自增
示例
----觸發器實現主鍵自增。【行級觸發器】
---分析:在用戶做插入操作的之前,拿到即將插入的數據,
------給該數據中的主鍵列賦值。
create or replace trigger auid
before
insert
on person
for each row
declare
begin
select s_person.nextval into :new.pid from dual;
end;
--查詢person表數據
select * from person;
---使用auid實現主鍵自增
insert into person (pname) values ('a');
commit;
--表中已經存在 主鍵爲1的數據,但仍然可以成功插入下面的數據
--原因: :new 表示的插入操作的新的那條數據。
-- 在做insert操作時,:new指的就是要新增的這條數據。而觸發器又是監聽的”before“的狀態,所以在新增這條數據時,:new.pid的值就會被觸發器進行修改,所以觸發器一旦被觸發,添加的數據中,”1“就會被觸發器修改。
insert into person values (1, 'b');
commit;
4、關於工具配置
1)plsql developer工具插入中文亂碼
”我的電腦“右鍵屬性----- 高級系統設置-----環境變量
在環境變量中,配置一個系統變量:
NLS_LANG = SIMPLIFIED CHINESE_CHINA.ZHS16GBK
2)關於plsql developer工具中,查看當前用戶下創建的所有表
將 工具---- 瀏覽器
窗口中的 “All Objects” ---- 切換爲 ”My Objectes"