一、PLSQL編程html
1.1概念和目的java
PL/SQL(Procedure Language/SQL)sql
PLSQL是Oracle對sql語言的過程化擴展數據庫
指在SQL命令語言中增長了過程處理語句(如分支、循環),使SQL語言具備過程處理能力編程
1.2程序結構api
經過PLsqlDeveloper工具的Test Windows建立程序模版或者經過語句在SQLWindows編寫oracle
提示:PLSQL語言的大小是不區分的ide
PL/SQL能夠分爲三個部分:聲明部分、可執行部分、異常處理部分工具
[declare] --聲明變量,遊標(無變量聲明能夠省略)oop
begin
--執行部分(方法)處理業務異常
end;
set serveroutput on --sqlplus 命令窗口
begin
DBMS_output.put_line(「Hello world」);
end;
/ ---須要在程序最後添加一個/標識程序的結束
1.3變量
聲明變量的方式
變量名 變量類型(變量長度) --v_name varchar2(20)
1.3.1普通變量(char varchar2 date number boolean long)
(1)直接賦值語句:= --v_name=’zhangsan’
(2)語句賦值,使用select…into…賦值(語法select值into變量)
【示例】打印人員我的信息,包括:姓名、薪水、地址
declare v_name varchar2(20):=’zhangsan’; v_sal number; v_addr varchar2(200); begin v_sal:=1580; select ‘ad’ into v_addr from dual; DBMS_output.put_line(‘姓名:’|| v_name|| ’薪水:’ || v_sal ||‘地址:’||v_addr); end;
【示例】查詢 emp表中7839號員工的我的信息,打印姓名和薪水
declare v_name vachar2(20); v_sal number; begin select ename,sal into v_name,v_sal from emp where empno=7839; DBMS_output.put_line(‘姓名:’|| v_name || ‘,薪水:’|| v_sal); end;
1.3.2特殊變量類型(引用型變量、記錄型變量)
(1)引用型變量
【示例】查詢 emp表中7839號員工的我的信息,打印姓名和薪水
declare v_name emp.ename%TYPE; v_sal emp.sal%TYPE; begin select ename,sal into v_name,v_sal from emp where empno=7839; DBMS_output.put_line(‘姓名:’|| v_name || ‘,薪水:’|| v_sal); end;
使用普通變量定義方式,須要知道表中列的類型,而是用引用類型,不須要考慮列的類型,使用%TYPE是很是好的編程風格,由於它使得PL/SQL更加靈活,更加適應於對數據庫定義的更新。
(2)記錄型變量
接受表中的一行記錄,至關於Java中的一個對象
語法:變量名稱 表名%ROWTYPE
【示例】查詢 emp表中7839號員工的我的信息,打印姓名和薪水…..
declare v_emp emp%ROWTYPE; begin select * into v_emp from emp where empno=7839; DBMS_output.put_line(‘姓名:’|| v_emp.ename || ‘,薪水:’|| v_emp.sal); end;
若是有一個表,有100個字段,若是要使用這100字段名,若是使用引用型變量一個個聲明,會特別麻煩,記錄型變量能夠方便的解決這個問題。
錯誤的使用:
1.記錄型變量只能存儲一個完整的行數據。
2.返回的行太多了,記錄型變量也接受不了。
1.4流程控制
1.4.1條件分支
begin if 條件1 then 執行1 elsif 條件2 then 執行2 else 執行3 end if; end;
【示例】判斷emp表中記錄是否超過20條,10-20之間,或者10條如下
declare --聲明變量接受emp中的數量 v_count number; begin select count(1) into v_count from emp; if v_count>20 then DBMS_output.put_line(‘emp表中的記錄數超過了20條爲:’|| v_count); elsif v_count>=10 then DBMS_output.put_line(‘emp表中的記錄數在10-20條爲:’|| v_count); else DBMS_output.put_line(‘emp表中的記錄數10條如下爲:’|| v_count); end if; end;
1.4.2循環
在oracle中有三種循環方式,loop循環
語法:
begin loop exit when 退出循環條件 end loop; end;
【示例】打印數字1-10
declare v_num number:=1; begin loop exit when v_num>10; dbms_output.put_line(v_num); v_num+=v_num+1; end loop; end;
二、遊標
2.1什麼是遊標
用於臨時存儲一個查詢返回的多行數據(結構集,相似於Java的jdbc鏈接返回的ResultSet集合),經過遍歷遊標,能夠逐行訪問處理該結果集的數據。
遊標的使用方式:聲明--à打開à讀取à關閉
2.2語法
遊標聲明:
cursor 遊標名[(參數列表)] is 查詢語句;
遊標的打開:
open 遊標名;
遊標的取值:
fetch 遊標名 into 變量列表;
遊標的關閉:
close 遊標名;
2.3遊標的屬性
遊標的屬性 |
返回值類型 |
說明 |
%ROWCOUNT |
整型 |
得到fetch語句返回的數據行數 |
%FOUND |
布爾型 |
最近的fetch語句返回一行數據則爲真,不然爲假 |
%NOTFOUNT |
布爾型 |
與%FOUND屬性返回值相反 |
%ISOPEN |
布爾型 |
遊標已經打開時值爲真,不然爲假 |
其中%NOTFOUND是在遊標中找不到元素的時候返回TRUE,一般用來判斷退出循環
2.4建立和使用
無參遊標
【示例】使用遊標查詢emp表中全部員工的姓名和工資,並將其依次打印出來。
declare --聲明遊標 cursor c_emp is select ename,sal from emp; --聲明變量用來接受遊標中的元素 v_ename emp.ename%type; v_sal emp.sal%type; begin --打開遊標 open c_emp; 遍歷遊標 loop --獲取遊標中的數據 fetch c_emp into v_ename,v_sal; --退出循壞條件 exit when c_emp%notfound; dbms_output.put_line(‘姓名:’||v_name||’,薪水:’||v_sal); end loop; --關閉遊標 close c_emp; end;
帶參遊標
【示例】使用遊標查詢並打印某部門的員工的姓名和薪資,部門編號爲運行時手動輸入。
declare --聲明遊標 cursor c_emp(v_deptno emp.deptno%type) is select ename,sal from emp where deptno=v_deptno; --聲明變量用來接受遊標中的元素 v_ename emp.ename%type; v_sal emp.sal%type; begin --打開遊標 open c_emp; 遍歷遊標 loop --獲取遊標中的數據 fetch c_emp into v_ename,v_sal; --退出循壞條件 exit when c_emp%notfound; dbms_output.put_line(v_name || v_sal); end loop; --關閉遊標 close c_emp; end;
三、存儲過程
3.1概念做用
以前咱們編寫的PLSQL語句程序能夠進行表的操做,判斷,循環邏輯處理的工做,但沒法重複調用。能夠理解以前的代碼所有編寫在了main方法中,是匿名程序。Java能夠經過封裝對象和方法來解決複用問題,PLSQL是將一個個PLSQL的業務處理過程存儲起來進行復用,這些被存儲起來的PLSQL程序稱之爲存儲過程。
存儲過程做用:
3.2語法
create or replace procedure 過程名稱[(參數列表)] is begin end [過程名稱];
根據參數的類型,咱們將其分爲3類講解:
不帶參數的
帶輸入參數的
帶輸入輸出參數(返回值)的
3.3無參存儲
3.3.1建立存儲
3.3.2調用存儲
create or replace procedure p_hello as begin dbms_output.put_line(‘hello word’); end p_hello; begin p_hello; end;
exec p_hello; -----sqlplus
注:is和as是能夠會用的,用哪一個都沒有關係;過程當中沒有declare關鍵字,declare用在語句塊中
3.4帶輸入參數的存儲過程
【示例】查詢並打印某個員工(如7839號員工)的姓名和薪水—存儲過程:要求:調用的時候傳入員工編號,自動控制臺打印。
create or replace procedure p_querynameandsal(v_empno in emp.empno%type) is --聲明變量接受查詢結果 v_name emp.ename%type; v_sal emp.sal%type; begin --查詢emp表中某個員工的姓名和薪水並賦值給變量 select ename,sal into v_name,v_sal from emp where empno=v_empno; dbms_output.put_line(v_name || v_sal); end;
declare i integer; begin p_querynameandsal(7839); end exec p_querynameandsal(7839);
3.5帶輸出參數的存儲過程
【示例】輸入員工號查詢某個員工(7839號員工)信息,要求,將薪水做爲返回值輸出,給調用的程序使用。
create or replace procedure p_querysal_out(v_empno in emp.empno%type,o_sal out emp.sal%type) as begin select sal into o_sal from emp where empno=v_empno; end;
declare v_sal emp.sal%type; begin p_querysal_out(7839,v_sal); dbms_output.put_line(v_sal); end
3.6JAVA程序調用存儲過程
需求:若是一條語句沒法實現結構集,好比須要多表查詢,或者須要複雜邏輯查詢,咱們能夠選擇調用存儲出你的結果。
結論:經過 Connection對象的prepareCall方法傳遞一個轉義SQL語句能夠實現調用存儲過程。輸入參數直接調用set方法傳遞,輸出參數須要註冊後,執行存儲過程,經過get方法獲取,參數列表的下標是從1開始的。
public interface CallableStatement
用於執行SQL存儲過程的界面。 JDBC API提供了存儲過程SQL轉義語法,容許以標準方式爲全部RDBMS調用存儲過程。 此轉義語法包含一個結果參數和不包含結果參數的表單。 若是使用,結果參數必須註冊爲OUT參數。 其餘參數可用於輸入,輸出或二者。 參數按順序依次引用,第一個參數爲1。
{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
{call <procedure-name>[(<arg1>,<arg2>, ...)]}
IN參數值使用從PreparedStatement繼承的set方法設置。 全部OUT參數的類型必須在執行存儲過程以前進行註冊; 它們的值經過這裏提供的get方法在執行get 。
import oracle.jdbc.OracleTypes; import java.sql.CallableStatement; import java.sql.DriverManager; import java.sql.Connection; public class JdbcTest{ public static void main(String[] args){ //1.加載驅動 Class.forName(「oracle.jdbc.driver.PracleDriver」); //2.獲取鏈接 String url=」jdbc:oracle:thin:@localhost:1521:xe」; String name=」scott」; String password=」tigger」; Connection conn=DriverManager.getConnection(url,name,password); //3.獲取語句對象 String sql=」{call p_querysal_out(?,?)}」; CallableStatement call=conn.prepareCall(sql); //4.設置輸出參數 call.setInt(1,7839); //5.註冊輸出參數 call.registerOutParameter(2,OracleTypes.DOUBLE); //6.執行存儲過程 call.execute(); //7.獲取輸出參數 double sal=call.getDouble(2); System.out.println(「薪水:」+sal); //8.釋放資源 call.close(); conn.close(); } }
視頻整理:https://www.bilibili.com/video/av46777605