【Oracle基礎】視圖,索引,pl/sql基本語法
1. 視圖
視圖就是封裝了一條複雜查詢的語句。視圖就是提供一個查詢的窗口,所有數據來自於原表。
- 語法一
CREATE VIEW 視圖名稱 AS 子查詢
首先我們可以將scott用戶下的emp表複製到system,通過system用戶操作,(因爲創建視圖必須擁有dba權限)
--查詢語句創建表
create table emp as select * from scott.emp
--創建視圖【必須有dba權限】
create view v_emp as select ename ,job from emp
視圖創建完畢就可以使用視圖來查詢,
--查詢視圖
select * from v_emp
- 語法二:
CREATE OR REPLACE VIEW 視圖名稱 AS 子查詢
如果視圖已經存在我們可以使用語法 2 來創建視圖,這樣已有的視圖會被覆蓋。
create or replace view v_emp as select * from emp
--修改視圖[不推薦]
update v_emp set job='CLERK' where ename='ALLEN';
commit;
修改視圖我們會發現視圖所查詢的表的字段值被修改了。所以我們一般不會去修改視圖。
我們可以設置視圖爲只讀。
- 語法三
CREATE OR REPLACE VIEW 視圖名稱 AS 子查詢 WITH READ ONLY
--創建只讀視圖
create view v_emp1 as select ename ,job from emp with read only;
- 視圖的作用?
- 第一:視圖可以屏蔽掉一些敏感字段。
- 第二:保證總部和分部數據及時統一。
2. 索引
索引是用於加速數據存取的數據對象。 合理的使用索引可以大大降低 i/o 次數,從而提高數據訪問性能。索引有很多種我們主要介紹常用的幾種:
- 單列索引
單列索引是基於單個列所建立的索引,比如:
CREATE index 索引名 on 表名(列名)
--單例索引
---創建一個單例索引
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';--觸發單例索引
- 索引的使用原則:
- 在大表上建立索引纔有意義
- 在 where 子句後面或者是連接條件上的字段建立索引
- 表中數據修改頻率高時不建議建立索引
3. pl/sql基本語法
- 什麼是 PL/SQL?
PL/SQL(Procedure Language/SQL),PLSQL 是 Oracle 對 sql 語言的過程化擴展,指在 SQL 命令語言中增加了過程處理語句(如分支、循環等),使 SQL 語言具有過程處理能力。把 SQL 語言的數據操縱能力與過程語言的數據處理能力結合起來,使得 PLSQL 面向過程但比過程語言簡單、高效、靈活和實用。
範例 1: 爲職工漲工資,每人漲 10%的工資。
update emp set sal=sal*1.1
範例 2: 例 2: 按職工的職稱長工資,總裁漲 1000 元,經理漲 800 元,其他人員漲 400 元。
這樣的需求我們就無法使用一條 SQL 來實現,需要藉助其他程序來幫助完成,也可以使用 pl/sql。
3.1 pl/sql程序語法
- 程序語法:
declare
說明部分 (變量說明, 遊標申明,例外說明 〕
begin
語句序列 (DML 語句〕 …
exception
例外處理語句
end;
3.2 常量和變量定義
在程序的聲明階段可以來定義常量和變量。
- 變量的基本類型就是 oracle 中的建表時字段的變量如 char, varchar2, date, number,boolean, long
定義語法: varl char(15);
psal number(9,2);
說明變量名、數據類型和長度後用分號結束說明語句。
常量定義: married constant boolean:=true
- 引用變量
myname emp.ename%type;
引用型變量,即 myname 的類型與 emp 表中 ename 列的類型一樣
在 sql 中使用 into 來賦值.
declare
emprec emp.ename%type;
begin
select t.ename into emprec from emp t where t.empno = 7369;
dbms_output.put_line(emprec);
end;
- 記錄型變量
emprec emp%rowtype
記錄變量分量的引用
emprec.ename:='ADAMS';
declare
p emp%rowtype;
begin
select * into p from emp t where t.empno = 7369;
dbms_output.put_line(p.ename || ' ' || p.sal);
end;
3.3 if分支
- 語法一:
IF 條件 THEN
語句 1;
語句 2;
END IF;
- 語法二:
IF 條件 THEN
語句序列 1;
ELSE
語句序列 2;
END IF;
- 語法三:
IF 條件 THEN
語句;
ELSIF 語句 THEN
語句;
ELSE
語句;
END IF;
--pl/sql中的if判斷
--輸入小於18的數字,輸出未成年
--輸入大於18小於40的數字,輸出中年人
--輸入大於40的數字,輸出老年人
declare
i number(3) := &1;
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;
3.4 LOOP循環語句
- 語法一:
WHILE total <= 25000 LOOP
.. .
total : = total + salary;
END LOOP;
- 語法二:
Loop
EXIT [when 條件];
……
End loop
- 語法三:
FOR I IN 1 . . 3 LOOP
語句序列 ;
END LOOP ;
--pl/sql中的loop循環
---用三種方式輸出1-10的數字
---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
i number(2) :=1;
begin
for i in 1..10 loop
dbms_output.put_line(i);
end loop;
end;
3.5 遊標Cursor
在寫 java 程序中有集合的概念,那麼在 pl/sql 中也會用到多條記錄,這時候我們就要用到遊標,遊標可以存儲查詢返回的多條數據。
遊標:可以存放多個對象,多行記錄
- 語法:
CURSOR 遊標名 [ (參數名 數據類型,參數名 數據類型,...)] IS SELECT 語句;
cursor c1 is select ename from emp;
- 遊標的使用步驟:
- 打開遊標: open c1; (打開遊標執行查詢)
- 取一行遊標的值: fetch c1 into pjob; (取一行到變量中)
- 關閉遊標: close c1;(關閉遊標釋放資源)
- 遊標的結束方式 exit when c1%notfound
- 注意: 上面的 pjob 必須與 emp 表中的 job 列類型一致:
定義: pjob emp.empjob%type;
--遊標:可以存放多個對象,多行記錄
--輸出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;
en emp.empno%type;
begin
open c2(10);
loop
fetch c2 into en;
exit when c2%notfound;
update emp set sal = sal + 100 where empno=en;
commit;
end loop;
close c2;
end;