基於oracle 的PL/SQL程式設計 -變數使用
1. 需要開啟的服務: 本機安裝的oracle ,預設是開機啟動服務的,開機時間太慢,關閉了,需要手動開啟:
OracleDBConsoleorcl
OracleOraDb10g_home1iSQL*Plus
OracleOraDb10g_home1TNSListener
OracleServiceORCL 這個後面的ORCL就是資料庫名字,官方術語叫做資料庫sid
2.開啟PL/SQL工具,使用者名稱scott 登陸sid為ORCL的資料庫, 密碼 tiger
3.開啟一個測試視窗,如下
-- Created on 2018/6/3 by ADMINISTRATOR declare -- 宣告本地變數的地方,包括遊標(結果集型別變數),如果沒有,declare可以去掉 --相當於java的 public class A{} i integer; begin -- 執行部分 --相當於Java的public static void main(String[] args) --異常處理 end;
4.列印helloworld
結果如下:
dbms_output是oracle的程式包,put_line()是呼叫的方法
在命令列中列印:需要先設定 set serveroutput on ,才會將列印語句打印出來,否則只執行不列印。
5. PLSQL變數的使用:
PLSQL中的變數分兩種:
(1)普通資料型別:char varchar2 date number(整數和小數) boolean long
(2)特殊變數型別(引用變數、記錄型變數)
變數的宣告方式為:變數名 變數型別(變數長度) ,例如:v_name varchar2(20)
變數賦值:
(1)宣告時使用 := 直接賦值:v_name varchar2(20) := ‘zhangsan’ 只寫=,則是進行比較
(2)語句賦值: select 值 into 變數名
5.1 普通變數的使用
-- 宣告一個人的資訊 姓名 薪水 地址 declare -- 姓名 不能使用name,這是保留字 v_name varchar2(50) := '張三'; -- 薪水 小數:number(總長度(小數加整數的位數),小數位數) v_sal number(6,2) --1000.00 v_sal number; --地址 v_addr varchar2(200); begin --直接賦值 v_sal := 15000; --語句賦值 select '上海市南京路' into v_addr from dual; --實際工作中應該是from 某個表 -- 列印變數 || 是拼接符,相當於java 的+ dbms_output.put_line('姓名:' || v_name || ',薪水:' || v_sal || ',地址:' || v_addr); end;
執行結果:
5.2 引用變數的使用
引用變數:變數的型別和長度取決於表中欄位的型別和長度(變數的型別和長度引用表中欄位的型別和長度),通過 表名.列名%TYPE 指定變數的型別和長度,例如 v_name emp.ename%TYPE
引用型變數的好處:使用普通變數定義方式,需要知道表中列的型別,而使用引用型別不需要考慮列的型別,使用%TYPE是非常號的程式設計風格,因為它使得PL/SQL更加靈活,更加適應於對資料庫定義的更新。
-- 查詢emp表中7839號員工的個人資訊,列印姓名和薪水 declare -- 姓名 定義的是引用變數 v_ename emp.ename%TYPE; -- 薪水 v_sal emp.sal%TYPE; begin --查詢姓名和薪水並賦值給變數,。使用select into 語句賦值 select ename, sal into v_ename, v_sal from emp where empno = 7839; dbms_output.put_line('姓名:' || v_ename || ',薪水:' || v_sal); end;
結果:
5.3 記錄型變數
記錄型變數 預設接接收 表中的一行資料,不能指定欄位,相當於java中的一個物件。
語法: 變數名稱 表名%ROWTYPE 例如 v_emp emp%rowtype; 通過 變數名.欄位名 的方式獲取變數中的值
--記錄型變數示例:用該變數接收表中一行sql的資訊 declare -- 記錄型變數 v_emp emp%ROWTYPE; begin --查詢所有欄位並賦值給變數,欄位名用v_emp.欄位名 表示 select * into v_emp from emp where empno = 7839; dbms_output.put_line('姓名:' || v_emp.ename || ',薪水:' || v_emp.sal); end;
結果:
6.流程控制:
6.1 條件分支,語法:
BEGIN
IF 條件1 then 執行1;
Elsif 條件2 then 執行2 ; --注意不是 elseif ,是elsif
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;
執行結果:
select * 結果如下:
6.2 loop迴圈.此處只記錄loop迴圈的使用。 迴圈兩個要點:1.迴圈變數初值,迴圈體中迴圈變數值要發生變化
-- 迴圈列印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;
7.特殊的變數—— 遊標,本質上是一條查詢語句的結果的封裝,只能往前,不能往後
用於臨時儲存一個查詢返回的多行資料(結果集,類似於Java的jdbc連線返回的resultset集合),通過遍歷遊標,可以逐行訪問處理該結果集的資料
遊標使用方法:宣告 開啟 讀取 關閉
語法:
遊標宣告: CURSOR 遊標名[(引數列表)] IS 查詢語句
遊標開啟: Open 遊標名;
遊標的取值: FETCH 遊標名 into 變數列表;
遊標關閉: CLOSE 遊標名
遊標屬性:
%NOTFOUND 是在遊標中找不到元素時返回TRUE,通常用於判斷,退出迴圈
7.1 不帶引數的遊標 示例:
-- 使用遊標查詢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; --c_emp%notfound 沒有資料時返回true dbms_output.put_line('姓名:' || v_ename || ',薪水:' || v_sal); end loop; --關閉遊標 close c_emp; end;
結果如下:
7.2 帶輸入引數的遊標:
-- 使用遊標查詢emp表中某個部門員工的姓名和工資,並將其依次打印出來 declare -- 宣告帶引數的遊標,在宣告時加上形參,select語句裡面加上查詢條件 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(10); -- 開啟遊標時加上實參 loop -- 遍歷遊標 fetch c_emp into v_ename, v_sal; --獲取遊標中的資料,如果有的話就賦值給變數 --在判斷之前先獲取一下資料,看有還是沒有 exit when c_emp%notfound; --c_emp%notfound 沒有資料時返回true dbms_output.put_line('姓名:' || v_ename || ',薪水:' || v_sal); end loop; close c_emp; --關閉遊標 end;
上述遊標使用語句,相當於一個匿名的函式,當測試視窗關閉,語句也就沒有了,無法實現複用。如果想要在視窗關閉了之後還能使用上面那段語句,就需要儲存過程了。參見下文儲存過程學習記錄。