OraclePLSQL編程

PL/SQL編程java

pl/sql(procedural language/sql)是Oracle在標準的sql語言上的擴展。pl/sql不只容許嵌入式sql語言,還能夠定義變量和常量,容許使用條件語句和循環語句,容許使用例外處理各類錯誤。這樣使得他的功能變的更強大。缺點是移植性很差。sql

編寫一個存儲過程,向表中添加數據。數據庫

  1. create table mytest (name varchar2(30),passwd varchar2(30));
  2. create or replace procedure xxc_pro1 is

begin編程

insert into mytest values ('小紅','m123');c#

end;數組

  1. 調用過程  exec  過程名(參數1,參數2…)或call 過程名參數1,參數2…)

①    exec xxc_pro1;   或者是安全

②    call xxc_pro1;oracle

pl/sql能夠作什麼?ide

塊:包括過程、函數、觸發器、包。函數

編寫規範:

  1. 註釋  --:單行註釋

eg:select * from emp where empno=7788;--取得員工信息

    /*……*/多行註釋

  1. 表示符號(變量)的命名規範:

①    當定義變量時,建議用v_做爲前綴:v_ename

②    當定義常量時,建議用c_做爲前綴:c_rate

③    當定義遊標時,建議用_cursor做爲後綴:emp_cursor

④    當定義例外時,建議用e_做爲前綴:e_error

塊(block)是pl/sql的今本程序單元,編寫pl/sql程序實際上就是在編寫pl/sql塊;pl/sql塊由三部分組成:定義部分,執行部分,例外處理部分。

declare  --可選部分

/*定義部分:定義常量,變量,遊標,例外,複雜數據類型*/

begin   --必選部分

/*執行部分:要執行的pl/sql語句和sql語句*/

exception  --可選部分

/*例外處理部分:處理運行的各類錯誤*/

 

實例1:只包含執行部分的pl/sql塊

SQL> set serveroutput on  --打開輸出

SQL> begin

  2  dbms_output.put_line('hello');

  3  end;

  4  /

說明:dbms_output是oracle提供的包,該包包含一些過程,put_line就是其中之一。

實例2:包含定義部分和執行部分

SQL> declare

  2  v_ename varchar2(5);

  3  begin

  4  select ename into v_ename from emp where empno = &no;

  5  dbms_output.put_line('僱員名'||v_ename);

  6  end;

  7  /

說明:&:從控制檯輸入變量,會彈出一個對話框。

實例3.同時輸出僱員名和工資

SQL> declare

  2  v_ename varchar2(20);

  3  v_sal number(10,2);

  4  begin

  5  select ename,sal into v_ename,v_sal from emp where empno=&no;

  6  dbms_output.put_line('僱員名:'||v_ename||' 工資:'||v_sal);

  7  end;

  8  /

包含定義,執行,和例外處理的pl/sql塊。

實例4.當輸入的員工號不存在時

SQL> declare

  2  v_ename varchar2(20);

  3  v_sal number(10,2);

  4  begin

  5  select ename,sal into v_ename,v_sal from emp where empno =&no;

  6  dbms_output.put_line('僱員名:'||v_ename||' 工資:'||v_sal);

  7  exception   --異常處理部分

  8  when no_data_found then

  9  dbms_output.put_line('請輸入正確的員工號!');

 10  end;

 11  /

以上爲塊的基礎,下面來介紹塊的各個組成:過程,函數,觸發器,包。

過程

過程用於執行特定的操做,當執行過程的時候,能夠指定輸入參數(in),也能夠指定輸出參數(out)。經過在過程當中使用輸入參數,能夠講數據輸入到執行部分,經過使用輸出參數,能夠將執行部分的數據輸出到應用環境,在pl/sql中可使用create procedure命令來建立過程。

編寫一個存儲過程,能夠輸入僱員名和新工資來改變員工工資。

--案例

create or replace procedure xxc_pro3(newname in varchar2,newsal in number) is 

begin

update emp set sal=newsal where ename=newname;

end;

調用   exec xxc_pro3(‘SCOTT’,2900);[A1] 

--in表示是輸入參數,能夠不寫,默認是in,但out必須寫。

在java程序中調用存儲過程來修改工資;

//演示java程序調用oracle中的存儲過程

 

package TestOraPro;//根據不一樣的包,包名不一樣

import java.sql.*;

 

public class TestOraPro {

 

    /**

     * @param args

     */

    public static void main(String[] args) {

       // TODO Auto-generated method stub

       try{

       //加載驅動

       Class.forName("oracle.jdbc.driver.OracleDriver");

       //獲得鏈接   1521爲端口號

       Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:CUIXIAO2","scott","xxc");

       //建立callablestatement

       CallableStatement cs=ct.prepareCall("{call xxc_pro3(?,?)}");

       //給?賦值

       cs.setString(1, "SMITH");

       cs.setInt(2,2600);

       //執行

       cs.execute();

      

       }catch(Exception e){

            e.printStackTrace();

       } finally{

           //關閉資源

           cs.close();

           ct.close();

}

    }

}

以上爲過程基礎,後會詳細講。

 

函數

函數用於返回特定的數據,當創建函數時,在函數頭部必須包含return子句,而在函數體內必須包含return語句來返回數據,可使用create function來創建函數。

案例1.返回工人年工資。

--函數案例

create or replace function xxc_fun1(newname varchar2)

return number is yearSal number(10,2);

begin

select sal*12+nvl(comm,0)*12 into yearSal from emp where ename=newname;

return yearSal;

end;

在sqlplus中調用函數

sql>var income number;

sql>call xxc_fun1(‘SCOTT’) into: income;

sql>print income;

在java中調用函數

select xxc_fun1(‘SCOTT’) from dual;

這樣能夠經過rs.setInt(1)獲得返回結果。

 

包用於在邏輯上組合過程和函數,它由包規範和包體兩部分組成。

1.咱們能夠用create(or replace) package命令來建包;

    實例:create package xxc_package is

           Procedure update_sal (name varchar2,newsal number);

           Function annual_sal(name varchar2) return number;

           End;

包規只包含過程和函數的說明,可是沒有函數和過程的實現代碼。[A2] 

包體用於實現包規範中的過程和函數。

2.創建包體能夠用create package body命令。

    create package body xxc_package is

    Procedure update_sal(name varchar2,newsal number) is

    begin

    update emp set sal=newsal where ename=name;

    end;

    function annual_sal(name varchar2) return number is

    annual_salary number;

    begin

    select sal*12+nvl(comm,0)*12 into annual_salary from emp    where ename=name;

    return;

    end;

    end;

[A3] 3.如何調用包中的過程和函數。

    在過程和函數前加上包名。

    exec xxc_package.update_sal(‘SCOTT’,120);

觸發器

觸發器是指隱含的存儲過程,當定義觸發器是,必須指定觸發事件和觸發的操做,經常使用的觸發操做有insert、update和delete。觸發器操做其實是一個pl/sql塊,可使用create trigger命令來建立觸發器。由於觸發器內容不少,會在後面詳細介紹,觸發器是很是有用的,能夠用來維護數據庫的安全和一致性。

 

在編寫pl/sql塊時能夠定義的變量和常量;

  1. 標量類型(scalar);
  2. 複合類型(composite);
  3. 參照類型(reference);
  4. lob(large ofject);

 

標量類型(scalar)—經常使用類型

語法格式(即前邊最多見的格式)

變量名 [constant] datatype [not null] [:=/default expr]

expr:指定初始值的pl/sql表達式,能夠是文本,其餘變量,函數等。

定義標量案例

①    定義一個變長字符串

V_ename varchar2(10);

②    定義一個小數,範圍在-9999.99~9999.99

v_sal number(6,2);

③    定義一個小數並賦初值  :=是pl/sql的賦值符號;

v_sal number(6,2):=12.3;

④    定義一個日期類型數

v_birthday date;

⑤    定義一個布爾類型變量,不能爲空,默認是false;

v_valid boolen not null default false;

[A4] 下面以輸入員工號,顯示員工姓名,工資,我的所得稅(稅率爲0.03)爲例,說明變量的使用。

declare

c_tax_rate number(3,2):=0.03;

v_ename varchar2(5);

v_sal number(10,2);

v_tax_sal number(10,2);

begin

select ename,sal into v_ename,v_sal from emp where empno=&no;

v_tax_sal:=v_sal*c_tax_rate;

dbms_output.put_line(‘員工名:’||v_ename||’工資:’||v_sal||’繳稅:’||v_tax_sal);

end;

 

對於上邊的pl/sql塊,有一個問題。

若是員工的名字長於5個字符,就會出現錯誤,爲了下降pl/sql的維護工做量,可使用%type屬性來定義變量,這樣它會按照數據庫列來肯定你定義的變量的類型和長度。

變量名  表名.列名%type

對於上例的改動

v_ename emp.ename%type;

v_sal emp.sal%type;

複合類型(composite)-介紹

用於存放多個值的變量,主要包括這幾種:

① pl/sql記錄;

② pl/sql表;

③ 嵌套表;

④ varray;

其中① ② 用的多,③ ④ 用的少。

1.pl/sql的記錄。

相似於高級語言的結構體,當引用pl/sql記錄成員的時候,必需要加記錄變量做爲前綴(記錄變量.記錄成員)。

如:declare

type emp_record_type is record(name emp.ename%type, salary emp.sal%type,title emp.job%type);[A5] 

xxc_record emp_record_type;

begin

select ename,sal,job into xxc_record from emp where empno=&no;

dbms_output.put_line(‘員工名:’||xxc_record.name||’工資:’||xxc_record.salary);

end;

2.pl/sql

至關於高級語言中的數組,須要注意的是高級語言中的數組的下標不能爲負,但表的下標沒有限制,能夠爲負。[A6] 

例如:declare           -- binary_integer表示下標是整數

type xxc_table_type is table of emp.ename%type index by binary_integer;

xxc_table xxc_table_type;

begin        --下標0能夠是任何整數,-1,-2,23均可以,但輸出的時候也要是同一個數,否則會出錯。

select ename into xxc_table(0) from emp where empno=7788;

dbms_output.put_line(‘員工名:’||xxc_table(0));

end;

在這個實例中,若是把where子句去掉,就會出錯,由於你只請求了一個數據,而返回了多行數據。解決辦法是使用參照變量。

參照變量

參照變量是指用於存放數據指針的變量,經過使用參照變量可使得應用程序共享相同的對象,從而下降佔用的空間。在編寫pl/sql程序時,可使用遊標變量(ref cursor)和對象類型變量(ref obj_type)這兩種參照變量,用得多的是遊標變量。

遊標變量

定義遊標是,不須要指定select語句,但當使用遊標(open)時,須要指定select語句,這樣一個遊標就與一個遊標就與一個select語句結合了。

實例:① 編寫一個pl/sql塊,輸入部門號,顯示全部員工名和工資。

       declare

       type xxc_emp_cursor is ref cursor;

test_cursor xxc_emp_cursor;

       v_ename emp.ename%type;

       v_sal emp.sal%type;

       begin

open test_cursor for select ename,sal from emp where deptno=&no;

loop

fetch test_cursor into v_ename,v_sal;

exit when test_cursor%notfound;

dbms_output.put_line(‘名字:’||v_ename||’工資:’||v_sal);

end loop;

close test_cursor;

[A7] end;

②  在① 的基礎上,若是員工的工資低於2000,加100

declare

       type xxc_emp_cursor is ref cursor;

test_cursor xxc_emp_cursor;

       v_ename emp.ename%type;

       v_sal emp.sal%type;

       begin

open test_cursor for select ename,sal from emp where deptno=&no;

loop

fetch test_cursor into v_ename,v_sal;

exit when test_cursor%notfound;

if v_sal<2000 then

update emp set sal=sal+100 where ename=v_ename;

v_sal=v_sal+100;

end if;

dbms_output.put_line(‘名字:’||v_ename||’工資:’||v_sal);

end loop;

close test_cursor;

end;

[A8] Pl/sql分支控制語句

1.條件分支語句

    if…then   if…then…else   if…then…eslif…then…else…

當if語句結束時要有end if。

    不等於號是<>,不是!=,

    if job=’MANAGER’,是單引號,不是雙引號。

2.循環語句 

--loop是pl/sql中最簡單的循環語句,這種循環以loop開始,以end loop結束,此循環至少會被執行一次。

例:編寫一個循環過程,可輸入用戶名,並循環添加10個用戶到user表中,用戶編號從1開始。

Sql>create table user(userid number(10),username varchar2(20));

Sql>create procedure xxc_insert_user1(name varchar2) is

       declare

       v_Num number:=1;  --不用指定大小嗎?

       begin

       loop

       insert into user values(v_num,name);

       exit when v_num=10;[A9] 

       v_num:=v_num+1;  --Oracle中沒有++符號

       end loop;

       end;

--while循環

當while條件爲真時,執行循環體。

以while…loop開頭,以end loop結尾。

例:上題,用戶號從11開始,添加10名用戶。

create procedure xxc_insert_user2(name varchar2) is

declare

v_Num number:=11;  --不用指定大小嗎?

    begin

    while v_num<=20 loop

    insert into user values(v_num,name);

    v_num:=v_num+1;

    end loop;

    end;

--for循環

循環基本結構以下:

begin

    for i in reverse 1..10 loop

    insert into users(I,’小紅’);

    end loop;

    end;

順序控制語句   --goto,null

Goto語句會增長程序的複雜性,下降可讀性,通常不使用,但有時會很方便。

基本語法     goto lable ,lable是定義好了的標籤。

例:declare

    i int:=1;

    begin

    loop

    dbms_output.put_line(‘i=’||i);

    if i=10 then

    goto end_loop;

    end if;

    end loop;

<<end_loop>>    --此爲標籤,注意格式

dbms_output.put_line(‘循環結束’);

end;

null語句不執行任何操做,好處是能夠提升程序的可讀性。

例:if sal<2000 then

       update emp set sal=sal+100 where ename=name;

       else

       null;

 

編寫分頁過程

從易到難,先寫簡單的過程。

寫無返回值的過程,並被Java程序調用,前邊已寫過,再也不重寫。如今寫一個有返回值的過程,並用Java程序調用。

例:輸入員工號,輸出員工姓名。

Create procedure xxc_pro4 (empid in number,empname out varchar2) is

Begin

Select ename into empname from emp where empno = empid;

End;

Java程序調用。

import java.sql.*;

 

public class TestOraPro1 {

 

    /**

     * @param args

     */

    public static void main(String[] args) {

       // TODO Auto-generated method stub

       try{

       //加載驅動

       Class.forName("oracle.jdbc.driver.OracleDriver");

       //獲得鏈接   1521爲端口號

       Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:CUIXIAO2","scott","xxc");

       //建立callablestatement

       CallableStatement cs=ct.prepareCall("{call xxc_pro4(?,?)}");

       //給第一個?賦值

       cs.setInt(1,7788);

       //給第二個?賦值

       cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);

       //執行

       cs.execute();

       //取出返回值,要注意?的順序,第幾個?是返回值就寫幾。

       String name = cs.getString(2);

       System.out.println(「7788的名字是」+name);

      

       }catch(Exception e){

            e.printStackTrace();

       }finally{

           //關閉資源

           cs.close();

           ct.close();

}

    }

}

案例擴展:輸入一個員工號,輸出該員工的名字,工資和崗位。

create procedure xxc_pro5(empid in number,empname out varchar2,empsal out number,empjob out varchar2) is

begin

select ename,sal,job into empname,empsal,empjob from emp where empno=empid;

end;

Java調用

import java.sql.*;

 

public class TestOraPro1 {

 

    /**

     * @param args

     */

    public static void main(String[] args) {

       // TODO Auto-generated method stub

       try{

       //加載驅動

       Class.forName("oracle.jdbc.driver.OracleDriver");

       //獲得鏈接   1521爲端口號

       Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:CUIXIAO2","scott","xxc");

       //建立callablestatement

       CallableStatement cs=ct.prepareCall("{call xxc_pro4(?,?,?,?)}");

       //給第一個?賦值

       cs.setInt(1,7788);

       //給後3個?賦值

       cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);

       cs.registerOutParameter(3,oracle.jdbc.OracleTypes.DOUBLE);

       cs.registerOutParameter(4,oracle.jdbc.OracleTypes.VARCHAR);

       //執行

       cs.execute();

       //取出返回值,要注意?的順序,第幾個?是返回值就寫幾。

       String name = cs.getString(2);

       String job = cs.getString(4);

       System.out.println(「7788的名字是」+name+」 工做是」+job);

      

       }catch(Exception e){

            e.printStackTrace();

       }finally{

           //關閉資源

           cs.close();

           ct.close();

}

    }

}

帶有返回值的存儲過程(結果集是個列表)。

案例:編寫個存儲過程,輸入部門號,輸出該部門的全部員工的信息。

分析以下:

因爲Oracle的存儲過程沒有返回值,它的全部返回值都是經過out參數來替代的,列表一樣也不例外,但因爲是個集合,因此不能用通常參數,必需要用package。因此分爲兩部分。

① 建立一個包,在包中定義一個test_package,是個遊標;

create package test_package as type test_cursor is ref cursor;

End test_package;

②    建立存儲過程

create procedure xxc_pro6(xxcno in number,xxc_cursor out test_package.test_cursor) is

begin

open xxc_cursor for select * from emp where deptno=xxcno;

end;

在Java中調用此存儲過程

import java.sql.*;

 

public class TestOraPro1 {

 

    /**

     * @param args

     */

    public static void main(String[] args) {

       // TODO Auto-generated method stub

       try{

       //加載驅動

       Class.forName("oracle.jdbc.driver.OracleDriver");

       //獲得鏈接   1521爲oracle端口號

       Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:CUIXIAO2","scott","xxc");

       //建立callablestatement

       CallableStatement cs=ct.prepareCall("{call xxc_pro6(?,?)}");

       //給第一個?賦值

       cs.setInt(1,10);

       //給第二個?賦值

       cs.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR);

       //執行

       cs.execute();

       //獲得結果集

       ResultSet rs = (ResustSet)cs.getObject(2);

       While(rs.next()){

       System.out.println(rs.getInt(1)+」 」+rs.getString(2)+」 」+rs.getString(3));

       }

       }catch(Exception e){

            e.printStackTrace();

       }finally{

           //關閉資源

           cs.close();

           ct.close();

}

    }

}

開始編寫分頁過程。

例:請編寫一個存儲過程,要求能夠輸入表名、每頁顯示記錄數、當前頁,返回總記錄數、總頁數和返回的結果集。

如今先回顧一下分頁的語句,這是個模板。

select * from (select t1.*,rownum rn from (select * from emp)  t1 where rownum<=10) where rn>=6;

① 建立一個包,在包中定義一個test_package2,是個遊標;

create package test_package2 as type test_cursor2 is ref cursor;

End test_package2;

② 建立存儲過程;

create procedure fenye is

(tablename in varchar2,  --表名

rowsize in number,  --每頁記錄數

pagenow in number,  --當前頁

recordnum out number,  --總記錄數

pagenum out number,    --總頁數

set_cursor out test_package2.test_cursor2  --結果集的遊標

) is

v_sql varchar2(1000);

v_begin nuber:=(pagenow-1)*rowsize+1;

v_end nuber:=pagenow*rowsize;

begin

--v_sql是鏈接字符串,有點繞,看仔細

 

 v_sql := 'SELECT * FROM (SELECT T.*,ROWNUM rn FROM (SELECT * FROM ' ||

           TABLENAME || ' ) T WHERE ROWNUM <= ' || V_END ||

           ' ) WHERE rn >= ' || V_BEGIN;

--打開遊標,把遊標和sql語句結合起來

open set_cursor for v_sql;

--計算recordnum和pagenum

v_sql:= 'SELECT COUNT(*) FROM ' || TABLENAME;

execute immediate v_sql into recordnum;

if mod(recordnum,rowsize)=0 then

    pagenum:=recordnum/rowsize;

else

    pagenum:=recordnum/rowsize+1;

end if;

close set_cursor;

end;

用Java程序調用:

import java.sql.*;

 

public class TestOraPro1 {

 

    /**

     * @param args

     */

    public static void main(String[] args) {

       // TODO Auto-generated method stub

       try{

       //加載驅動

       Class.forName("oracle.jdbc.driver.OracleDriver");

       //獲得鏈接   1521爲端口號

       Connection ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:CUIXIAO2","scott","xxc");

       //建立callablestatement

       CallableStatement cs=ct.prepareCall("{call fenye(?,?,?,?,?,?)}");

       //給?賦值

       cs.setString(1,」emp」);

       cs.setInt(2,5);

       cs.setInt(3,1);

       //註冊總記錄數

       cs.registerOutParameter(4,oracle.jdbc.OracleTypes.INTEGER);

       //註冊總頁數

cs.registerOutParameter(5,oracle.jdbc.OracleTypes.INTEGER);

//註冊結果集

cs.registerOutParameter(6,oracle.jdbc.OracleTypes.CURSOR);

 

       //執行

       cs.execute();

//取出返回值,要注意?的順序,第幾個?是返回值就寫幾。

       int rnum=cs.getInt(4);

       int pnum=cs.getInt(5);

       ResultSet rs=(ResultSet)cs.getObject(6);

      

       System.out.println(」記錄數是:」+rnum+」 總頁數是:」+pnum);

       while(rs.next()){

           System.out.println(」編號:」+rs.getInt(1)+」姓名:」+rs.getString(2));

       }

       }catch(Exception e){

            e.printStackTrace();

       }finally{

           //關閉資源

           cs.close();

           ct.close();

}

    }

}

 

例外處理

例外處理分爲預約義例外,其餘預約義例外和自定義例外。

案例:當輸入的僱員編號不存在時

declare

v_ename emp.ename%type;

begin

select ename into v_name from emp where empno=&no;

dbms_output.putline(’名字是:’||v_name);

exception

when no_data_found then

dbms_output.putline(’編號不存在!’);

end;

 

no_data_found就是一個預約義例外,在執行select語句時會出異常,但在執行update等語句時不會觸發該例外。

 

預約義例外是由pl/sql所提供的系統例外。當pl/sql違反Oracle的規定時就會隱含觸發一個內部例外。

經常使用的例外:

  1. case_no_found 當編寫pl/sql塊中編寫case語句時,若是在when子句中沒有包含必須的條件分支,就會觸發case_no_found例外。

例:create or replace procedure xxc_pro7(no number) is

    v_sal emp.sal%type;

    begin

    select sal into v_sal from emp where empno=no;

    case

    when v_sal<1000 then

       update emp set sal=sal+200 where empno=no;

    when 1000<=v_sal<2000 then

       update emp set sal=sal+300 where empno=no;

    end case;

    exception

when case_no_found then

    dbms_output.putline(’case中沒有和’||v_sal||’相匹配的條件’);

end;

  1. 2.       cursor_already_open例外:

declare

cursor emp_cursor is select ename,sal from emp;

begin

open emp_cursor;

for emp_record1 in emp_cursor loop

dbms_output.putline(emp_cursor.ename);

end loop;

exception

when cursor_already_open then

dbms_output.putline(’遊標已打開!’);

end;

3.dup_val_on_index例外

    在惟一索引所對應的列上插入重複的值時,會隱含的觸發此例外。

    begin

    insert into dept values(10,’公關部’,’北京’);

    exception

    when dup_val_on_index then

    dbms_output.putline(’在deptno列上不能有重複值!’);

end;

4.invaild_cursor

當試圖在不合法的遊標上執行操做時,就會觸發該例外。例如當試圖從沒有打開的遊標提取數據或是關閉沒有打開的遊標時,就會觸發。

    declare

cursor emp_cursor is select ename,sal from emp;

emp_record emp_cursor%rowtype;

    begin

    --open emp_cursor; --打開遊標(但被註釋掉了)

    fetch emp_cursor into emp_record;

    dbms_output.putline(emp_cursor.ename);

    close emp_cursor;

    exception

    when invalid_cursor then

    dbms_output.putline(’請檢查遊標是否打開’);

    end;

5.invalid_number例外

當輸入的數據有誤時,會觸發該例外。好比把100寫成1oo就會觸發。

    begin

    update emp set sal=sal+’1oo’;

    exception

    when invalid_number then

    dbms_output.putline(’輸入的數字不正確!’);

    end;

6.too_many_rows例外

    當執行select into語句時,若是返回超過了一行,則會觸發該例外。

    declare

    v_ename emp.ename%type;

    begin

    select ename into v_ename from emp;

    exception

    when too_many_rows then

    dbms_output.putline(’返回了多行!’);

    end;

7.zero_divide例外    2/0,即0作分母的時候觸發。

8.value_error例外

當在執行賦值操做時,若是變量的長度不足以容納實際數據,就會觸發該例外。

    declare

    v_ename varchar2(5);

begin

    select ename into v_ename from emp where empno=&no;

    dbms_output.putline(’名字是:’||v_ename);

    exception

    when value_error then

    dbms_output.putline(’數據超出變量長度!’);

    end;

其餘預約義例外。

  1. login_denide  當用戶非法登陸時,會觸發該例外。
  2. not_logged_on  若是用戶沒有登陸就執行dml操做,就會觸發。
  3. storage_error  若是超過了內存空間或內存被破壞,就會觸發。
  4. timeout_on_resoure  若是oracle在等待資源是出現了超時,觸發。

自定義例外

預約義例外是和oracle的錯誤相關的,而自定義例外於oracle錯誤沒有任何關係,它是由開發人員爲特定的狀況所定義的例外。

例:編寫一個pl/sql塊,接收一個僱員號,並給該僱員的工資增長1000元,若是該僱員不存在,請提示。

create or replace procedure test_ex(no number) is

declare

myex exception; --定義一個例外

begin

update emp set sal=sal+1000 where empno=no;

if sql%notfound then  -- sql%notfound表示沒有更新數據

raise myex;   --觸發myex

end if;

exception

when myex then

dbms_output.putline(’未更新成功!’);

end;

視圖

視圖與表的區別

  1. 表須要佔用磁盤空間,視圖不須要;
  2. 視圖不能添加索引;
  3. 使用視圖能夠簡化複雜查詢;
  4. 視圖能夠提升安全性

建立視圖

create view 視圖名 as select語句 [with read only];

例:建立視圖,把emp表的sal<1000的僱員映射到該視圖;

create view myview as select * from emp where sal<1000;

爲簡化操做,用視圖顯示員工編號,姓名和所在部門

create view myview2 as select emp.empno,emp.ename,dept.dname from emp,dept where emp.deptno=dept.deptno;

建立或修改視圖

create or replace view 視圖名 as select語句 [with read only];

刪除視圖

drop view 視圖名;


 [A1]

調用過程,必須這麼寫

begin

   xxc_pro3('SCOTT',2900);

end;

 [A2]

相似Java的Interface接口

 [A3]報錯

 [A4]如何定義變量

 [A5]至關於Java的POJO

實體類

 [A6]至關於Java的數組

 [A7]遊標就是C的指針

這裏面用的循環,至關於while循環

 [A8]展現了循環集合,而後修改集合對象的屬性

 [A9]Java中的break

相關文章
相關標籤/搜索