Oracle 複習版(型別包括很全面)
- 這個吧,應付山農期末考試,除了選擇題需要看好課件。理解外,其餘大題簡答基本型別都涵蓋。期末剛考完,很全面。
- 其餘學校不瞭解。
- Oracle的後臺程序主要包括:
- (1)DBWR 資料庫寫入程序:負責將資料庫緩衝區內變動過的資料塊寫回磁碟內的資料檔案,DBWR可有多個。
- 2)LGWR 日誌檔案寫入程序: 負責將重做日誌緩衝區內變動記錄迴圈寫回磁碟內的重做日誌檔案,
- (3)ARCH 歸檔程序(archive process): 歸檔程序ARCH負責在重做日誌檔案切換後將已經寫滿的重做日誌檔案複製到歸檔日誌檔案中,
- (4)CKPT 檢查點程序:檢查點是一個數據庫事件,喚醒DBWR程序,
- (6)RECO 恢復程序: 在Oracle 11g分散式資料庫環境中,RECO處理程式由於網路故障或系統故障掛起的分散式事務。
- (7) SMON 系統監控程序(system monitor): SMON完成例程的恢復工作 (啟動例項,裝載資料庫,開啟資料庫)
- (8) PMON 程序監控程序(process monitor): 當用戶程序失敗時用於完成程序的恢復。
- 一個表空間對應兩個資料檔案,同時對段區管理
- 1 SQL> create tablespace t4
- datafile 'c:\t04.dbf'size 5000k,'c:\t05.dbf'size 5000k;
- extent management local autoallocate
- segment space management auto;
ALTER DATABASE ADD LOGFILE MEMBER 'log3a.rdo' TO GROUP 10;
【分割槽表】【list】列表分割槽
create table part_book1
2 ( bid number(4),
3 bookname varchar2(20),
4 bookpress varchar2(30),
5 booktime date)
6 partition by list(bookpress)
7 (partition part1 values('清華大學出版社') tablespace system,
8 partition part2 values('教育出版社') tablespace users);
insert into part_book1 values(2,'音樂基礎欣賞','教育出版社',to_date('20120102','yyyymmdd'))
【range】範圍分割槽
create table part_book
2 ( bid number(4),
3 bookname varchar2(20),
4 bookpress varchar2(30),
5 booktime date)
6 partition by range(booktime)
7 (partition part1 values less than (to_date('20100101','yyyymmdd'))tablespace system,
8 partition part2 values less than (to_date('20120101','yyyymmdd')) tablespace users,
9 partition part3 values less than (maxvalue) tablespace users);
完整的遊標應用例項:
DECLARE varId NUMBER;
varName VARCHAR2(50);
CURSOR MyCur(v_xb xs.xb%type) IS
SELECT xh, xm FROM xs
WHERE xb=v_xb;
BEGIN OPEN MyCur('男');
FETCH MyCur INTO varId, varName;
dbms_output.put_line('學生編號:'|| varId ||'學生名:'||varName ) ;
CLOSE MyCur;
END;
DECLARE
v_xm varchar2(8):='張瓊';
v_zym varchar2(10):='計算機';
v_zxf number(2):=45; /*定義變數型別*/
BEGIN
UPDATE XS SET zxf=v_zxf
WHERE xm=v_xm;
IF SQL%NOTFOUND THEN
INSERT INTO XS(XH,XM,ZYM,ZXF) VALUES('001',v_xm,v_zym,v_zxf);
END IF;
end;
補充:建立一個儲存過程,以部門號為該儲存過程的in型別引數,查詢該部門的平均工資,並輸出該部門中比平均工資高的員工號、員工名。(for 迴圈遍歷 遊標)
CREATE OR REPLACE PROCEDURE show_emp(
p_deptno emp.deptno%TYPE)
AS
v_sal emp.sal%TYPE;
BEGIN
SELECT avg(sal) INTO v_sal FROM emp WHERE deptno=p_deptno;
DBMS_OUTPUT.PUT_LINE(p_deptno||' '||'average salary is:'||v_sal);
FOR v_emp IN (SELECT * FROM emp WHERE deptno=p_deptno AND sal>v_sal) LOOP
DBMS_OUTPUT.PUT_LINE(v_emp.empno||' '||v_emp.ename);
END LOOP;
END show_emp;
例:為emp表建立一個觸發器,當插入新員工時顯示新員工的員工號、員工名;當更新員工工資時,顯示修改前後員工工資;當刪除員工時,顯示被刪除的員工號、員工名。
• CREATE OR REPLACE TRIGGER t3
• BEFORE INSERT OR UPDATE of sal OR DELETE ON scott.emp
• FOR EACH ROW
• BEGIN
• IF INSERTING THEN
• DBMS_OUTPUT.PUT_LINE(:new.empno||' '||:new.ename);
• ELSIF UPDATING THEN
• DBMS_OUTPUT.PUT_LINE(:old.sal||' '||:new.sal);
• ELSE
• DBMS_OUTPUT.PUT_LINE(:old.empno||' '|| :old.ename);
• END IF;
• END t3;
• 觸發觸發器t3
• Set serveroutput on
• declare
• begin
• update scott.emp set empno=7521 where empno=7522;
• commit;
• end;
建立概要檔案
SQL> create profile p1 limit
failed_login_attempts 3
password_lock_time 7;
將概要檔案分配給使用者
SQL> alter user u1
profile p1;
例:刪除重做日誌組log1a.rdo:
ALTER DATABASE DROP LOGFILE MEMBER 'log1a.rdo';
例:刪除編號為10的重做日誌組:
ALTER DATABASE DROP LOGFILE GROUP 10;
2 ALTER DATABASE ADD LOGFILE ('log1c.rdo', 'log2c.rdo') SIZE 5000k;
3 ALTER DATABASE ADD LOGFILE GROUP 10 ('log1a.rdo', 'log2a.rdo') SIZE 5000k
空間,使用者表空間
1.建立普通表空間
SQL> create tablespace t2
2 datafile 'c:\t02.dbf' size 5000k;
建立臨時表空間
SQL> create temporary tablespace t3
2 tempfile 'c:\t03.dbf'size 5000k;
3.建立回滾表空間
SQL> create undo tablespace t4
2 datafile 'c:\t04.dbf'size 5000k;
4.建立大檔案表空間
SQL> create bigfile tablespace bigtbs
2 datafile 'c:\bigtbs01.dbf' size 5000k
匯入表格 SQL> $imp system/test tables=(Student,Course,SC) file=c:\tian.dmp
增加表空間容量
方法一:自動擴充
SQL> create tablespace t2
2 datafile 'c:\t02.dbf'size 5000k
3 autoextend on
4 next 500k
5 maxsize 20M;
方法二:直接在表空間內增添資料檔案
SQL> alter tablespace t4
add datafile 'c:\t04.dbf'size 5000k;
方法三:修改已存在的資料檔案的大小(注意資料庫級別)
SQL> alter database orcl1
2 datafile 'c:\t06.dbf'resize 10000k;
9.重新命名資料檔案
Alter tablespace oldname rename to newname;
Alter tablespace tablespace_name rename datafile 'oldname' to 'newname'
把一個已經存在的表table1放到表空間users中
alter table table1 move tablespace users;
insert
create table test
2 (xm varchar2(20) not null,
3 zy varchar(30) default('計算機'),
4 nj number not null
insert into xs(xh,xm,zym,xb,cssj,zxf)
2 values('061101','王林','計算機','男',TO_DATE('19860210','YYYYMMDD'),50);
【檢視】
SQL> create or replace view cs_kc
2 as
3 select xs.xh
4 from xs
5 where zym='計算機'
6 with check option;
【索引】
SQL> create index xc
2 on test(nj)
3 tablespace users;
【同義詞】
SQL> CREATE PUBLIC SYNONYM KC
FOR SCOTT.KC;
【序列】
SQL> CREATE SEQUENCE STUDENT_SEQUENCE
2 START WITH 5000
3 INCREMENT BY -2
4 MAXVALUE 5000
5 MINVALUE 1
6 NOCYCLE ;
%type
(1)學生
declare
2 v_xm xs.xm%type;
3 begin
4 select xm into v_xm from xs
5 where xh='007';
6 dbms_output.put_line(v_xm);
7 exception
8 when others then
9 dbms_output.put_line('出現異常');
10 end;
Jame
PL/SQL procedure successfully completed
(2)員工
declare
2 emp_number constant number(4):=7900;
3 emp_name scott.emp.ename%type;
4 emp_job scott.emp.job%type;
5 emp_sal scott.emp.sal%type;
6 begin
7 select ename,job,sal
8 into emp_name,emp_job,emp_sal
9 from scott.emp where empno=emp_number;
10 dbms_output.put_line('查詢的員工號為'||emp_number);
11 dbms_output.put_line('該員工的姓名為'||emp_name);
12 dbms_output.put_line('該員工的職位為'||emp_job);
13 dbms_output.put_line('該員工的工資為'||emp_sal);
14 end;
%rowtype
SQL> declare
2 v_1 xs%rowtype;
3 begin
4 select * into v_1 from xs
5 where xh='061101';
6 dbms_output.put_line(v_1.xm||' '||v_1.zym||' '||v_1.cssj);
7 exception
8 when others then
9 dbms_output.put_line('出現異常');
10 end;
分支結構
SQL> set serveroutput on
SQL> declare
2 v_sal scott.emp.sal%type;
3 v_tax scott.emp.sal%type;
4 begin
5 select sal into v_sal from scott.emp where empno=7788;
6 if v_sal>=3000 then
7 v_tax:=v_sal*0.08;
8 elsif v_sal>=1500 then
9 v_tax:=v_sal*0.06;
10 else
11 v_tax:=v_sal*0.04;
12 end if;
13 dbms_output.put_line('應繳稅金'||v_tax);
14 end;
應繳稅金240
【例題】多分支結構
declare
2 v_deptno scott.emp.deptno%type;
3 v_zj number(4);
4 v_empno scott.emp.empno%type;
5 begin
6 v_empno:='7788';
7 select deptno into v_deptno from scott.emp where empno=v_empno;
8 if v_deptno=10 then v_zj:=100;
9 elsif v_deptno=20 then v_zj:=150;
10 elsif v_deptno=30 then v_zj:=200;
11 else v_zj:=300;
12 end if;
13 update scott.emp set sal=sal+v_zj where empno='7788';
14 end;
【例題】迴圈結構LOOP-EXIT-WHEN-END迴圈
SQL> declare
2 s number:=1;
3 n number:=2;
4 begin
5 LOOP
6 s:=s*n;
7 n:=n+1;
8 exit when n>10;
9 end loop;
10 dbms_output.put_line(to_char(s));
11 end;
3628800
【例題】WHILE-LOOP-END迴圈
SQL> declare
2 s number:=1;
3 n number:=2;
4 begin
5 while n<=10
6 LOOP
7 s:=s*n;
8 n:=n+1;
9 end loop;
10 dbms_output.put_line(to_char(s));
11 end;
3628800
【例題】用FOR-IN-LOOP-END迴圈結構求10的階乘
SQL> declare
2 s number:=1;
3 n number:=2;
4 begin
5 for n in 2..10
6 LOOP
7 s:=s*n;
8 end loop;
9 dbms_output.put_line(to_char(s));
10 end;
異常處理
SQL> declare
2 v_result xs.xm%type;
3 begin
4 select xh into v_result
5 from xs where xm='王林';
6 dbms_output.put_line('The student number is'||v_result);
7 exception
8 when TOO_MANY_ROWS then
9 dbms_output.put_line('There has TOO_MANY_ROWS error');
10 when NO_DATA_FOUND then
11 dbms_output.put_line('There has NO_DATA_FOUND error');
12 when OTHERS then
13 dbms_output.put_line('錯誤情況不明');
14 end;
遊標部分
- 四步:
定義遊標 DECLARE CURSOR 遊標名 (引數列表) IS <SELECT語句>;
開啟遊標 OPEN cursor_name(引數);
檢索遊標 FETCH cursor_name INTO 變數列表;
關閉遊標 CLOSE cursor_name;
遊標舉例
declare cursor my_cursor is select xh from xs;
v_xh xs.xh%type;
Begin open my_cursor;
fetch my_cursor into v_xh;
dbms_output.put_line(v_xh);
dbms_output.put_line(my_cursor%rowcount);
Close my_cursor;
Exception when others then
dbms_output.put_line(sqlcode||sqlerrm);
end;
遊標的遍歷
一、while迴圈遍歷
SQL> declare
2 v_xh char(6);
3 v_zxf number(2);
4 cursor c_1
5 is select xh,zxf from xs;
6 begin
7 open c_1;
8 fetch c_1 into v_xh,v_zxf;
9 while c_1 %found
10 loop
11 dbms_output.put_line(v_xh||' '||v_zxf);
12 fetch c_1 into v_xh,v_zxf;
13 end loop;
14 close c_1;
15 end;
二、for迴圈
SQL>
declare cursor c_2 is select deptno,avg(sal) a1 from scott.emp group by deptno;
Begin for v_2 in c_2
Loop dbms_output.put_line(v_2.deptno||' '||v_2.a1);
end loop;
end;
三、帶for update的遊標
declare
2 cursor c_emp is select * from scott.emp for update;
3 v_zl number;
4 v_emp c_emp%rowtype;
5 begin
6 for v_emp in c_emp
7 loop
8 case v_emp.deptno
9 when 10 then v_zl:=100;
10 when 20 then v_zl:=150;
11 when 30 then v_zl:=200;
12 else v_zl:=250;
13 end case;
14 update scott.emp set sal=sal+v_zl where current of c_emp;
15 end loop;
16 end;
四、帶update的遊標
DECLARE v_empno scott.emp.empno%TYPE; v_sal scott.emp.sal%TYPE; CURSOR c_cursor IS SELECT empno,sal FROM scott.emp; BEGIN OPEN c_cursor; LOOP FETCH c_cursor INTO v_empno, v_sal; EXIT WHEN c_cursor%NOTFOUND; IF v_sal<=1200 THEN UPDATE scott.emp SET Sal=Sal+50 WHERE empno=v_empno; DBMS_OUTPUT.PUT_LINE('編碼為'||v_empno||'工資已更新!'); END IF; DBMS_OUTPUT.PUT_LINE('記錄數:'|| c_cursor %ROWCOUNT); END LOOP; CLOSE c_cursor;END; 五、用於更新的遊標
declare cursor c_1 is select empno,sal from emp for update of sal nowait; v_sal emp.sal%type; begin for cursor_1 in c_1 loop if cursor_1.sal<=1000 then v_sal:=1500; else v_sal:=cursor_1.sal*1.5; if v_sal>10000 then v_sal:=10000; end if; end if; update emp set sal=v_sal where current of c_1; end loop;end;
例1:建立一儲存過程update_emp,該過程用於將emp表中empno為7876的員工姓名修改為candy
- create or replace procedure update_emp
- as
- begin
- update scott.emp set ename='candy' where empno=7876;
- end update_emp;
【例2】計算指定系總學分大於40的人數。(建立procedure count_grade )
分析: CREATE OR REPLACE PROCEDURE count_grade
- ( v_zym in varchar2,person_num out number )
- AS
- BEGIN
- SELECT COUNT(ZXF)
- INTO person_num
- FROM XS
- WHERE ZYM=v_zym and zxf>=40;
- END count_grade;
執行procedure count_grade
declare
person_n number(3);
begin
count_grade('計算機',person_n);
dbms_output.put_line(person_n);
end;
注意:person_n引數模式為out,需要先定義,IN 引數時需要賦初值
【例4】編寫一儲存過程,用於計算指定系學生的總學分。
分析:儲存過程使用了一個輸入引數和一個輸出引數。
create or replace procedure totalcredit(v_zym in varchar2,v_total out number)
is
begin
select sum(zxf) into v_total from xs
where zym=v_zym;
end totalcredit;
執行
declare
v_total number;
begin
totalcredit('計算機',v_total);
dbms_output.put_line(v_total);
end;
例 5: 建立一個儲存過程,以部門號為引數,返回該部門的人數和最高工資。
- CREATE OR REPLACE PROCEDURE return_deptinfo(
- p_deptno IN scott.emp.deptno%TYPE,
- p_avgsal OUT scott.emp.sal%TYPE,
- p_count OUT scott.emp.sal%TYPE)
- AS
- BEGIN
- SELECT avg(sal),count(*) INTO p_avgsal,p_count
- FROM scott.emp
- WHERE deptno=p_deptno;
- EXCEPTION
- WHEN NO_DATA_FOUND THEN
- DBMS_OUTPUT.PUT_LINE('The department don’t exists!');
- END return_deptinfo;
- 儲存過程的執行
- declare
- p_avgsal scott.emp.sal%TYPE;
- p_count scott.emp.sal%TYPE;
- begin
- return_deptinfo(20,p_avgsal,p_count);
- dbms_output.put_line(p_avgsal||' '||p_count);
- end;
觸發器
CREATE OR REPLACE TRIGGER trigger_name
{ BEFORE∣AFTER∣INSTEAD OF }
DELETE OR INSERTE [R UPDATE OF column,…n
ON [table_name∣view_name
FOR EACH ROW [ WHEN(condition) ] ]
DECLARE…
BEGIN…
EXCEPTION….
END [trigger_name];
- 觸發事件
Insert |delete|update of column
在行級觸發,為了獲得某列在修改前後的資料,---標誌符:old和:new
【例】增加一新表XS_HIS,表結構和表XS相同,用來存放從XS表中刪除的記錄。建立一個觸發器,當XS表被刪除一行,把刪除的記錄寫到日誌表XS_HIS中。
分析:
- 建立表 xs_his
Create table xs_his as select * from xs;
2. 觸發時間: before
3. 觸發事件: delete
4. 觸發級別: 行級 for each row
CREATE OR REPLACE TRIGGER del_xs
BEFORE DELETE ON XS FOR EACH ROW
BEGIN
INSERT INTO XS_HIS (XH,XM,ZYM,XB,CSSJ,ZXF) VALUES(:OLD.XH,:OLD.XH, :OLD.ZYM, :OLD.XB, :OLD.CSSJ,:OLD.ZXF);
END del_xs;
【例】利用觸發器在資料庫XSCJ的XS表執行插入、更新和刪除3種操作後在sql_info中給出相應提示。
Create table sql_info(info varchar(10));
CREATE TRIGGER cue_xs
AFTER INSERT OR UPDATE OR DELETE ON XS FOR EACH ROW
DECLARE
Infor varchar2(10);
BEGIN
IF INSERTING THEN
Infor:='插入';
ELSIF UPDATING THEN
Infor:='更新';
ELSE
Infor:='刪除';
END IF;
INSERT INTO SQL_INFO VALUES(infor);
END cue_xs;
為emp表建立一個觸發器,當執行插入操作時,統計操作後員工人數;當執行更新工資操作時,統計更新後員工平均工資;當執行刪除操作時,統計刪除後各個部門剩餘的人數(遊標)。 ★
- CREATE OR REPLACE TRIGGER t4 AFTER INSERT OR UPDATE OR DELETE ON scott.emp
- DECLARE
- v_count NUMBER;v_sal NUMBER(6,2);
- BEGIN
- IF INSERTING THEN
- SELECT count(*) INTO v_count FROM scott.emp;
- DBMS_OUTPUT.PUT_LINE(v_count);
- ELSIF UPDATING THEN
- SELECT avg(sal) INTO v_sal FROM scott.emp;
- DBMS_OUTPUT.PUT_LINE(v_sal);
- ELSE
- FOR v_dept IN (SELECT deptno,count(*) num FROM scott.emp GROUP BY deptno) LOOP
- DBMS_OUTPUT.PUT_LINE(v_dept.deptno||' '||v_dept.num);
- END LOOP;
- END IF; END t4;
建立一個觸發器,在修改dept表的部門號後,同時更新emp表中相應的員工的部門號。★
分析:觸發事件 update of deptno
表 scott.dept
觸發時間 after
create or replace trigger tr_update_dept
after update of deptno on scott.dept
for each row
begin
update scott.emp set deptno=:new.deptno
where deptno=:old.deptno;
end;
【例】利用觸發器在資料庫XSCJ的XS表執行插入、更新和刪除3種操作後在sql_info中給出相應提示。
Create table sql_info(info varchar(10));
CREATE TRIGGER cue_xs
AFTER INSERT OR UPDATE OR DELETE ON XS FOR EACH ROW
DECLARE
Infor varchar2(10);
BEGIN
IF INSERTING THEN
Infor:='XS表插入';
ELSIF UPDATING THEN
Infor:='XS表更新';
ELSE
Infor:='XS表刪除';
END IF;
INSERT INTO SQL_INFO VALUES(infor);
END cue_xs;
系統觸發器之logon和logoff觸發器,可以將使用者訪問資料庫的情況記錄在一個日誌表中。
create table u_log
(username varchar2(50),
activity varchar2(20),
eventdate DATE
);
登陸資料庫
、Create or replace trigger st1
after logon on database
begin
insert into u_log values(user,'LOGON',SYSDATE);
END;
退出資料庫
create or replace trigger st2
Before logoff on database
begin
insert into u_log values(user,'LOGOFF',SYSDATE);
END;
示例:為PUBLIC使用者組授予CREATE SESSION系統許可權
GRANT CREATE SESSION TO PUBLIC;
注:普通使用者一般只具有CREATE SESSION系統許可權。
示例:將scott模式下的emp表的SELECT、UPDATE、 INSERT許可權授予user1使用者。
GRANT SELECT,INSERT,UPDATE ON scott.emp
TO u_1 with grant option;
物件許可權的回收
語法結構
REVOKE obj_priv_list | ALL ON [schema.]object FROM user_list|role_list;
revoke SELECT,INSERT,UPDATE ON scott.emp from u_1;
使用者的鎖定與解鎖
- 鎖定使用者
- ALTER USER test ACCOUNT LOCK;
- 解鎖使用者
ALTER USER test ACCOUNT UNLOCK;
建立角色
語法結構
CREATE ROLE role_name
[NOT IDENTIFIED ][ IDENTIFIED BY password ] [WITH ADMIN OPTION]
示例
CREATE ROLE high_manager_role
CREATE ROLE middle_manager_role
IDENTIFIED BY middlerole;
CREATE ROLE low_manager_role
IDENTIFIED BY lowrole;
建立一個新的角色role3,它只能建立使用者,而不能執行其他DBA級命令,將role3 賦值給user2。
create role role3;
grant create session,create user to role3;
Grant role3 to user2;
建立使用者
SQL> create user u1
2 identified by test
3 default tablespace system
4 temporary tablespace temp
5 quota 10M on system;
使用者的鎖定與解鎖
SQL> alter user author account lock|unlock;
授予與回收系統許可權
SQL> Grant|revoke create session to username;
SQL> conn u1/test;
SQL> conn system/test;
使用者許可權
SQL> Grant update on scott.emp to u1;
SQL> conn u1/test;
SQL> update scott.emp set sal=5555 where empno=7369;
建立角色
SQL> create role role2;
SQL> grant create session,create user,alter user to role2;
將角色賦給使用者
SQL> Grant role2 to user1;