Oracle檢視和PL SQL程式設計.
Oracle中的檢視
在Oracle資料庫中檢視是資料庫中特有的物件。檢視主要用於資料查詢,它不會儲存資料(物化檢視除外)。這是檢視和資料表的重要區別。
檢視的資料來源於一個或等多個表中的資料,可以利用檢視進行查詢、插入、更新和刪除資料,操作檢視就是間接操作資料庫表。
通常情況下,檢視主要用於查詢,不提倡通過檢視而更新與檢視相關的表,因為檢視中的資料只是一個或多個表中的區域性資料。
關係檢視
關係檢視是四種檢視中比較簡單和常用的檢視。可以將關係檢視看做對簡單或複雜查詢的定義。它的輸出可以看作一個虛擬的表,該表的資料是由其它基礎資料表提供的。由於關係檢視並不儲存真正的資料,因此佔用資料庫資源也較少
create or replace view view_name AS select 表or其他檢視......
create or replace view view_communic_address AS select email,address,tel from students;
select * from view_communic_address --查詢檢視
提示:檢視中的資料來源於實際的物理表,修改檢視中的資料實際就是更改檢視資料的來源表,在通常情況下不提倡通過檢視修改資料;
只讀關係檢視
只讀檢視單一提供資料的查詢
create or replace view vw_employees AS
select employee_id,employee_name,employee_position,employee_age
from employees
with read only;
Drop View 檢視名稱;--刪除檢視物件
內嵌檢視
內嵌檢視是非存在於Oracle資料庫中的物件,它只是查詢過程中生成的結果資料集;內嵌檢視通常以子查詢的方式出現在SQL操作中。
內嵌檢視通常對於資料庫的開銷有更大的優勢,可以適當使用。
內嵌檢視的建立不使用create關鍵字建立,通常在查詢語句中建立內嵌檢視,在執行完sql操作後,內嵌檢視自動銷燬。
物化檢視
物化檢視也叫快照,物化檢視和表一樣生成物理檔案並佔用磁碟空間,對於資料庫及磁碟空間都有一定的開銷維護,在物化檢視上可以像普通表一樣建立索引。
Create materializedview 檢視名稱AS Select * from 表名
PL/SQL程式設計
PL/SQL是過程化SQL語言(Procedural Language/SQL)。
PL/SQL是對SQL語句的擴充套件,增加了程式語言的特點,所以PL/SQL就是把資料操作和查詢語句組織在PL/SQL程式碼的過程性單元中,通過邏輯判斷、迴圈等操作實現複雜的功能,在定義複雜業務的函式、過程及建立觸發器時使用。
PL/SQL中通常只能使用資料DML(資料操縱)語音和DCL(資料控制)語言,諸如:insert、update、select into、delete、commit、rollback、savepoint。不允許使用DDL(資料定義)語言 create、drop、alter......
PL/SQL塊的組成結構
DECLARE --宣告單元(可選)
變數1 型別[(長度)];
變數2 型別[(長度)];
BEGIN --執行單元(必須)
資料處理語句;
exception --異常處理單元(可選)
異常處理語句;
END;
宣告單元
PLSQL使用DDECLARE關鍵字宣告變數定義,此單元必須在PLSQL的最前面。
l通常變數名稱可以包括字母、下劃線、數字、#、$
l變數名稱不能超過30個字元
l第一個字元必須是字母
l不區分大小寫
l不能使用任何關鍵字
declare
name varchar(24);--宣告變數
age int:=25;--宣告變數並賦預設值
address String(64);--宣告程式設計型別變數
PL SQL程式設計變數型別
lchar定長字元型別,包括子類character、string、rowid、Nchar最長限制在2000個字元
lvarchar2可變字元型別,包括子類varchar、string、nvarchar2最長限制在4000個字元
lnumber(p,s) 值型別,包括子類int、integer、smallint、dec、double
ldate 日期型
lboolean 布林型別
l%type 複合型別變數
l%rowtype 行符合型別變數
%rowtype自定義符合型別
%rowtype是%type型別的擴充套件,可儲存查詢返回數表的一個未知列數量及型別的功能,使用更加方便
declare
R_var student% rowtype;
begin
select * into R_var from students where id=’stu001’;
dbms_output.put_line(R_var.name);
end;
PL SQL邏輯控制語句
IF Else基本邏輯語句if可以單獨使用,Else必須結合if使用
Elsif 等價於java的else if語句
Case when 類似於Java的Switch Case
if 布林表示式 then 滿足if執行的語句;
elsif 布林表示式 then 滿足if執行的語句;
else對應else執行的語句;
end if;
case
when布林表示式then執行語句;
when布林表示式then執行語句;
else 執行語句;
end case;
loop迴圈
loop
[業務處理語句;] [exit;]--退出迴圈
endloop;
while迴圈
while布林表示式loop
[業務處理語句;] [迴圈變數更新;]
endloop;
for迴圈
for in1..5 loop
[業務處理語句;]
endloop;
-- 建立關係檢視 create or replace view view_emp_tab_salary AS select e.NAME,s.grantdate,s.should,s.actual from emp_tab e inner join salary s on e.ID = s.emp_id; select * from view_emp_tab_salary; --查詢檢視 update view_emp_tab_salary SET NAME='任我行' WHERE NAME='張敏'; --不允許修改 update view_emp_tab_salary SET should=should+50 WHERE NAME='任我行'; --不允許修改 select * from salary; --建立只讀關係檢視 create view view_dep_emp as select d.id,d.NAME dname,e.NAME ename from dep_table d inner join emp_tab e on d.id = e.dep_id with read only select * from view_dep_emp --更改只讀檢視的資料(會導致系統報錯) update view_dep_emp set ename = '火雲邪神' where ename = '張無忌'; select * from emp_tab; -- PL SQL declare name string(64); age int:=17;--初始化預設值 BEGIN NAME:='白無瑕'; age:=age+1; dbms_output.put_line('此人的名字是 '||name); END; --使用自定義符合型別%rowtype對映資料行 select * from emp_tab; DECLARE row_emp emp_tab%ROWTYPE; id_ STRING(64):='NO003'; BEGIN select * into row_emp from emp_tab where id = id_; dbms_output.put_line(row_emp.ID); dbms_output.put_line(row_emp.NAME); dbms_output.put_line(row_emp.address); dbms_output.put_line(row_emp.age); END; -- if 邏輯判斷語句 declare age int:=16; message string(64):='是成年人'; message2 string(31):='是未成年人'; begin if age >= 18 then dbms_output.put_line(message); else dbms_output.put_line(message2); end if; end; -- if elsif 語句 declare score number :=-2; begin if (score >= 0 and score <= 100) then if score>=90 then dbms_output.put_line('優秀'); elsif score >=80 then dbms_output.put_line('良好'); elsif score >=70 then dbms_output.put_line('中等'); elsif score >=60 then dbms_output.put_line('及格'); else dbms_output.put_line('不及格'); end if; else dbms_output.put_line('成績非法必須在0-100之間'); end if; end; --case when 分支語句 declare score number :=70; begin if (score >= 0 and score <= 100) then case when score>=90 then dbms_output.put_line('優秀★★★★★'); when score>=80 then dbms_output.put_line('良好★★★★'); when score>=70 then dbms_output.put_line('中等★★★'); when score>=90 then dbms_output.put_line('及格★★'); else dbms_output.put_line('不及格★'); end case; else dbms_output.put_line('成績非法必須在0-100之間'); end if; end; -- PL SQL 迴圈 --基本loop 迴圈 --判斷及統計1到100之間有多少個能被3整除的數 declare num int:=1; counts int:=0; BEGIN LOOP if (num>100)then exit;--退出迴圈 end if; if(num MOD 3 = 0)THEN counts:=counts+1; dbms_output.put_line(num); END IF; num:=num+1; END LOOP; dbms_output.put_line('1到100之間能夠被3整除的數一共有 '||to_char(counts)); END; --使用while迴圈完成1到100之間累加和的計算 declare num INT:=1; sums int:=0; BEGIN while(num <=100) LOOP sums:=sums+num;--計算累加和 num:=num+1; END LOOP; dbms_output.put_line('1到100之間整數的累加和是:'||to_char(sums)); END; --使用for迴圈計算1到100之間的偶數和 DECLARE num INT:=1; sums INT:=0; BEGIN FOR i IN 1..100 LOOP if(num MOD 2=0)THEN sums:=sums+num;--統計偶數的累加和 END IF; num:=num+1;--變數自增 END LOOP; dbms_output.put_line('1到100之間所有偶數的累加和是 '||to_char(sums)); END;
--1 使用SQL語句建立關係型檢視,檢視資料來源於department和emp表,包含部門名稱,員工姓名,地址,電話和郵箱號碼; create or replace view view_department_emp as select d.name 部門名稱,e.name 員工姓名,e.address 地址,e.phone 電話,e.email 郵箱號碼 from dept d inner join emp e on d.id = e.depid select * from view_department_emp; /*2 連線department和emp表和sales表建立關係型只讀檢視,要求包含,部門名稱,員工姓名,產品程式碼, 銷售數量,銷售單價,銷售日期並未檢視建立列別名*/ create view view_dept_emp_sales as select d.name 部門名稱,e.name 員工姓名,s.id 產品程式碼,s.salquantity 銷售數量,s.price 銷售單價, to_char(s.saldate,'yyyy-MM-dd') 銷售日期 from (dept d inner join emp e on d.id = e.depid)inner join sales s on s.eid = e.id with read only select * from view_dept_emp_sales /*1 定義一段PL SQL 塊,宣告2個值型別變數,分別用來儲存銷售部和研發部們員工數量, 利用sql查詢獲取銷售部和研發部們的員工數量並儲存在2個變數中,對人數進行比較, 最後在輸出視窗顯示2個部門的人數差,必需是正數;*/ select * from emp; select * from dept; declare sales_department number; develop_department number; results number; BEGIN select count(DEPID) into sales_department from emp where depid = 'NO300'; select count(DEPID) into develop_department from emp where depid = 'NO200'; dbms_output.put_line('銷售部人數 '||sales_department); dbms_output.put_line('研發部人數 '||develop_department); select abs(sales_department-develop_department) into results from dual; dbms_output.put_line('部門人數差 '||results); END; /*2 定義一段PL SQL 塊,宣告型別為number型別的變數用來儲存emp表的某個id值; 宣告定義一個自定義%type型別的變數及描述用來封裝儲存department表部門名稱, emp表員工姓名,emp表員工地址,emp表員工生日, inner join 內連線查詢emp 和 department表,限制條件時emp表id等於以上number型別的變數值,查詢儲department表部門名稱, emp表員工姓名,emp表員工地址,emp表員工生日欄位為自定義%type型別進行賦值,在輸出視窗輸出 4個欄位的獲取後資訊。*/ declare zengyu varchar2(64):='671'; row_emp emp%ROWTYPE; BEGIN select * into row_emp from emp where id = zengyu; dbms_output.put_line(row_emp.id); dbms_output.put_line(row_emp.name); dbms_output.put_line(row_emp.address); dbms_output.put_line(to_char(row_emp.birth,'yyyy-mm-dd')); END; --1 利用迴圈語句完成在輸出視窗列印九九乘法表; declare num_i number:=1; num_j number:=1; begin FOR num_i IN 1..9 LOOP FOR num_j IN 1..9 LOOP dbms_output.put_line(num_i||'x'||num_j||'='||num_i*num_j); END LOOP; END LOOP; end; --pl sql輸出不換行 declare i number(8):=0; -- 定義迴圈所需的初始值 a varchar2(1000):=''; -- 定義一個空字串 begin -- 開啟迴圈 loop i:=i+1; -- 改變迴圈變數的值 exit when i>100; -- 退出迴圈條件 a:=a||i||' '; -- 拼接字串 end loop; dbms_output.put_line(a); -- 輸出結果 end; --網上參考答案 --1 利用迴圈語句完成在輸出視窗列印九九乘法表; BEGIN FOR i IN 1..9 LOOP FOR j IN 1..9 LOOP IF (j<=i) THEN dbms_output.put(to_char(j)||'*'||to_char(i)||'='||to_char(i*j)||' '); END IF; END LOOP; dbms_output.new_line(); END LOOP; END; --2 運用pl/sql語句塊列印6*4矩形 DECLARE a INT := 6; b INT := 4; BEGIN FOR i IN 1..a LOOP FOR j IN 1..b LOOP IF(i=1 OR i=a) THEN dbms_output.put('*'); ELSIF(j=1 OR j=b) THEN dbms_output.put('*'); ELSE dbms_output.put(' '); END IF; END LOOP; dbms_output.new_line(); END LOOP; END; --3 利用迴圈分別計算1-100之內的能被7整除和能被3整除數的累加和,並比較二者之間的差,列印輸出差的正數值。 DECLARE sums7 INT := 0; sums3 INT := 0; num INT := 1; differences INT := 0; BEGIN WHILE(num<=100) LOOP IF(num MOD 3 = 0) THEN sums3 := sums3+num; ELSIF(num MOD 7 = 0) THEN sums7 := sums7+num; END IF; num := num + 1; END LOOP; dbms_output.put_line('能被3整除的數的累加和是 '||to_char(sums3)); dbms_output.put_line('能被7整除的數的累加和是 '||to_char(sums7)); differences := abs(sums3-sums7); dbms_output.put_line('兩數之差是 '||to_char(differences)); END;