1. 程式人生 > >Oracle 複習版(型別包括很全面)

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;

 

遊標部分

  1. 四步

定義遊標 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表中empno7876的員工姓名修改為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

{ BEFOREAFTERINSTEAD OF }

  DELETE OR INSERTE [R UPDATE  OF column,…n          

ON [table_nameview_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中。

分析:

  1. 建立表 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;

 

【例】利用觸發器在資料庫XSCJXS表執行插入、更新和刪除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;

【例】利用觸發器在資料庫XSCJXS表執行插入、更新和刪除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;

系統觸發器之logonlogoff觸發器,可以將使用者訪問資料庫的情況記錄在一個日誌表中。

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;