Oracle
注:本文中使用Oracle10g
一. 創建表空間
create tablespace itoracle datafile 'C:\Users\24016\Desktop\store\oracle\itoracle.dbf' size 10m --設定存儲空間的大小 autoextend on --如果存儲空間不夠,開啓自動擴展存儲空間 next 10m; --每次擴展10m
二. 刪除表空間
drop tablespace itoracle;
三. 創建用戶
create user itoracle identified by itoracle default tablespace itoracle;--此時用戶並不能登錄,因爲沒有授權
- 給用戶授權
給itoracle角色授予dba角色 grant dba to itoracle; ----------------------------- Oracle中常用角色 connect --連接角色,基本角色 resource --開發者角色 dba --超級管理員角色
四. 切換到itoracle角色登錄
session-log off-all--退出當前登錄 session-log on --以itOracle角色登錄
五. Oracle數據類型
1.Varchar, Varchar2 --表示一個字符串,其中最常用的是Varchar2,Varchar2會自動截掉多餘的字符。 --比如定義一個Varchar2(6),如果只存進去一個字符,那麼取出來的數據長度就是1,而不是6 2.NUMBER --NUMBER(n)表示一個整數,長度是n, --NUMBEr(m,n)表示一個小數,整數是m-n, 3.DATA --表示日期類型 4.CLOB --大對象,存的是文本數據類型,可存4G 5.BLOB --大對象,存的是二進制數據,可存4G,如視頻文件
六. 創建一張person表
create table person( pid number(20), pname varchar2(10) );
- 添加一列
alter table person add gender number(1); 如果是添加多列,則以,隔開
- 修改列
alter table person modify gender char(1);
- 修改列名稱【注意】
alter table person rename column gender to sex;
- 刪除一列
alter table person drop column sex;
- 添加一條記錄(注意:Oracle中的增刪改操作有事務,必須手動提交,或回滾)
insert into person (pid,pname) values (1,'曉麗'); commit;
- 查詢記錄
select * from person;
- 修改記錄
update person set pname='志超' where pid =1; commit;
- 三個刪除
delete from person;--刪除表中全部記錄,但是表結構還在 drop table person;--刪除表結構 truncate table person;--先刪除表,再創建表,效果等同於刪除表中全部記錄 --尤其是在數據量大的情況下,尤其是在帶有索引的情況下,該操作效率高 --索引可以提高查詢效率,但是會影響增刪改的效率 truncate table person;
七. 序列
- 序列並不真的屬於任何一張表,但是可以和表邏輯綁定
- 默認從1開始,依次遞增,主要用來給主鍵賦值使用 s_person(命名規範)
- 創建序列
create sequence s_person;
- 查看序列
select s_person.nextval from dual; 剛創建好序列之後,要想查看當前序列值,必須要先執行一下s_person.nextval,才能查看當前序列值 查看當前序列值 select s_person.currval from dual;
- 使用序列添加記錄
insert into person (pid,pname) values(s_person.nextval,'曉麗'); commit;
八. 虛表/啞表:dual:虛表,無任何實際意義,只是爲了補全語法
九. scott用戶的使用(初學者使用的用戶)
- 解鎖Scott用戶
alter user scott account unlock;
- 解鎖scott用戶的密碼(默認密碼爲tiger)
alter user scott identified by tiger;
- 在OracleXE10g下,默認沒有scott用戶,需要手動創建。【注意】
創建步驟: 1. 登錄數據庫:sqlplus / as sysdba 賬戶:system 密碼:password --本地的口令和密碼 2. 創建scott用戶:create user scott identified by tiger; 3. 爲Scott用戶分配權限:grant connect,resource to scott; 4. 使用Scott用戶登錄:conn scott/tiger 5. 執行scott.sql腳本:@?\scott.sql --其中@?\代表的是路徑D:\Oracle\app\oracle\product\10.2.0\server --將scott.sql文件放到本地oracle安裝目錄下的server目錄下,然後執行上句代碼 6. 使用scott用戶登錄PL/SQL
- scott.sql文件代碼
Rem Copyright (c) 1990 by Oracle Corporation Rem NAME REM UTLSAMPL.SQL Rem FUNCTION Rem NOTES Rem MODIFIED Rem gdudey 06/28/95 - Modified for desktop seed database Rem glumpkin 10/21/92 - Renamed from SQLBLD.SQL Rem blinden 07/27/92 - Added primary and foreign keys to EMP and DEPT Rem rlim 04/29/91 - change char to varchar2 Rem mmoore 04/08/91 - use unlimited tablespace priv Rem pritto 04/04/91 - change SYSDATE to 13-JUL-87 Rem Mendels 12/07/90 - bug 30123;add to_date calls so language independent Rem rem rem $Header: utlsampl.sql 7020100.1 94/09/23 22:14:24 cli Generic<base> $ sqlbld.sql rem SET TERMOUT OFF SET ECHO OFF rem CONGDON Invoked in RDBMS at build time. 29-DEC-1988 rem OATES: Created: 16-Feb-83 GRANT CONNECT,RESOURCE,UNLIMITED TABLESPACE TO SCOTT IDENTIFIED BY TIGER; ALTER USER SCOTT DEFAULT TABLESPACE USERS; ALTER USER SCOTT TEMPORARY TABLESPACE TEMP; CONNECT SCOTT/TIGER DROP TABLE DEPT; CREATE TABLE DEPT (DEPTNO NUMBER(2) CONSTRAINT PK_DEPT PRIMARY KEY, DNAME VARCHAR2(14) , LOC VARCHAR2(13) ) ; DROP TABLE EMP; CREATE TABLE EMP (EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY, ENAME VARCHAR2(10), JOB VARCHAR2(9), MGR NUMBER(4), HIREDATE DATE, SAL NUMBER(7,2), COMM NUMBER(7,2), DEPTNO NUMBER(2) CONSTRAINT FK_DEPTNO REFERENCES DEPT); INSERT INTO DEPT VALUES (10,'ACCOUNTING','NEW YORK'); INSERT INTO DEPT VALUES (20,'RESEARCH','DALLAS'); INSERT INTO DEPT VALUES (30,'SALES','CHICAGO'); INSERT INTO DEPT VALUES (40,'OPERATIONS','BOSTON'); INSERT INTO EMP VALUES (7369,'SMITH','CLERK',7902,to_date('17-12-1980','dd-mm-yyyy'),800,NULL,20); INSERT INTO EMP VALUES (7499,'ALLEN','SALESMAN',7698,to_date('20-2-1981','dd-mm-yyyy'),1600,300,30); INSERT INTO EMP VALUES (7521,'WARD','SALESMAN',7698,to_date('22-2-1981','dd-mm-yyyy'),1250,500,30); INSERT INTO EMP VALUES (7566,'JONES','MANAGER',7839,to_date('2-4-1981','dd-mm-yyyy'),2975,NULL,20); INSERT INTO EMP VALUES (7654,'MARTIN','SALESMAN',7698,to_date('28-9-1981','dd-mm-yyyy'),1250,1400,30); INSERT INTO EMP VALUES (7698,'BLAKE','MANAGER',7839,to_date('1-5-1981','dd-mm-yyyy'),2850,NULL,30); INSERT INTO EMP VALUES (7782,'CLARK','MANAGER',7839,to_date('9-6-1981','dd-mm-yyyy'),2450,NULL,10); INSERT INTO EMP VALUES (7788,'SCOTT','ANALYST',7566,to_date('13-JUL-87')-85,3000,NULL,20); INSERT INTO EMP VALUES (7839,'KING','PRESIDENT',NULL,to_date('17-11-1981','dd-mm-yyyy'),5000,NULL,10); INSERT INTO EMP VALUES (7844,'TURNER','SALESMAN',7698,to_date('8-9-1981','dd-mm-yyyy'),1500,0,30); INSERT INTO EMP VALUES (7876,'ADAMS','CLERK',7788,to_date('13-JUL-87')-51,1100,NULL,20); INSERT INTO EMP VALUES (7900,'JAMES','CLERK',7698,to_date('3-12-1981','dd-mm-yyyy'),950,NULL,30); INSERT INTO EMP VALUES (7902,'FORD','ANALYST',7566,to_date('3-12-1981','dd-mm-yyyy'),3000,NULL,20); INSERT INTO EMP VALUES (7934,'MILLER','CLERK',7782,to_date('23-1-1982','dd-mm-yyyy'),1300,NULL,10); DROP TABLE BONUS; CREATE TABLE BONUS ( ENAME VARCHAR2(10) , JOB VARCHAR2(9) , SAL NUMBER, COMM NUMBER ) ; DROP TABLE SALGRADE; CREATE TABLE SALGRADE ( GRADE NUMBER, LOSAL NUMBER, HISAL NUMBER ); INSERT INTO SALGRADE VALUES (1,700,1200); INSERT INTO SALGRADE VALUES (2,1201,1400); INSERT INTO SALGRADE VALUES (3,1401,2000); INSERT INTO SALGRADE VALUES (4,2001,3000); INSERT INTO SALGRADE VALUES (5,3001,9999); COMMIT; SET TERMOUT ON SET ECHO ON
十. 函數
- 單行函數:作用在一行,返回一個值
- 字符函數
select upper('yes') from dual; select lower('YES') from dual;
- 數值函數
select round(25.5) from dual;--四捨五入 select round(25.87,1) from dual;--四捨五入向後保留一位小數:25.9 select round(25.8,-1) from dual;--四捨五入向前保留一位:30 select trunc(56.16) from dual;--直接截取,小數點後保留0位,其餘全部丟棄:56 select trunc(56.16,1) from dual;--保留小數點後1位,之後的直接丟棄:56.1 select trunc(56.16,-1) from dual;--保留小數點前1位,之後的 直接丟棄:50
- 日期函數
--查詢出系統當前日期 select sysdate from dual; --查詢出emp表中所有員工入職距離現在多少天 select sysdate-e.hiredate from emp e;--oracle中日期以天爲單位,直接計算出的結果就是多少天【重點】 --算出明天此刻時間(就是用系統時間+1--因爲單位是天) select sysdate+1 from dual;--:2021/1/20 18:58:55 --查詢emp表中所有員工入職距離現在多少月 select months_between(sysdate,e.hiredate) from emp e; --只有month月份有between函數,因爲每個月天數不固定,所以需要進行中間值運算 --查詢出emp表中所有員工距離現在幾年 select months_between(sysdate,e.hiredate)/12 from emp e; --查詢出emp表中所有員工入職距離現在幾周 select (sysdate-e.hiredate)/7 from emp e;
- 轉換函數
--日期轉字符串 select to_char(sysdate,'yyyy-mm-dd hh:mi:ss') from dual; --:2021-01-19 07:48:59 select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;--:2021-01-19 19:49:40 select to_char(sysdate,'fm yyyy-mm-dd hh24:mi:ss') from dual;--: 2021-1-19 19:50:22 --字符串改日期 select to_date('2021-01-19 07:48:59','yyyy-mm-dd hh24:mi:ss') from dual;--:2021/1/19 7:48:59
- 通用函數
--算出emp表中所有員工的年薪 select e.sal*12+nvl(e.comm,0)from emp e; --nvl(e.comm,0):去除null值,如果e.comm是null,則使用0代替 --oracle中所有與null進行運算的結果都是null
- 條件表達式
--給person表中pname起英文名 select p.pname, --千萬注意,這裏有個逗號, case p.pname when '志超' then 'Eternal' when '曉麗' then 'Angle' --當不滿足志超時,會自動判斷是否是曉麗 else 'none' --else選項可以不寫 end --end必須要寫 from person p; --注意:這並不能改變原始數據,因爲是select操作
--判斷person表中員工id,如果是pid>3,顯是girl,如果pid<3顯是boy,如果=3,顯是no select p.pid, case when p.pid>3 then 'girl' when p.pid <3 then 'boy' else 'no' end from person p;
- Oracle專用條件表達式
--oracle中,除了起別名,都用單引號。起別名可以不用引號,或者雙引號,包括中文 --給person表中pname起英文名 select p.pname, --注意逗號 decode(p.pname, --decode中緊跟着對哪個字段進行的操作,並且decode中除了最後一個不加逗號,其餘都加 '志超','Eternal', --一個對應一個,直到最後一個沒有對應的,則最後一個就是else的,可以省略 '曉麗','Angle', 'no') 英文名 --沒有end,並且起別名,不需要加單引號 from person p;
- 一般通用條件表達式寫法比較常用
- 多行函數(聚合函數:count()、sum()、max()、min()、avg())
- count()
select count(1) from person; --count(1)==count(*),推薦使用count(1)
- sum()、max()、min()、avg()與mysql中相同
十一. 分組查詢
- 查詢出每個部門的平均工資
select e.deptno,avg(e.sal) from employees e group by e.deptno; --分組查詢中,出現在group by後面的原始列,才能出現在select後面 --沒有出現在group by後面的列,想在select後面,必須加上聚合函數.如:avg(e.sal)
- 查詢平均工資高於2000的部門信息
select e.deptno,avg(e.sal) from employees e group by e.deptno having avg(e.sal)>2000;--條件 --所有的條件(即:where或having等條件語句)都不能使用別名來判斷:因爲查詢的順序是先看條件,再查詢。,二如果在條件中加了別名,則會發生找不到字段的錯誤。
- 查詢出每個部門工資高於800的員工的平均工資
select e.deptno,avg(e.sal) from employees e where e.sal>800 group by e.deptno; --where和having的區別:where是過濾分組前的數據,having是過濾分組後的數據 --表現形式:where必須在group by之前,having必須在group by之後。【重點】
- 查詢出每個部門工資高於800的員工的平均工資,然後再查詢出平均工資高於2000的部門
select e.deptno,avg(e.sal) from employees e where e.sal>800 group by e.deptno having avg(e.sal)>2000;
十二. 多表查詢
- 多表查詢中的一些概念
- 笛卡爾積(與mysql相同)
select * from emp,dept;--得到笛卡爾積
- 等值連接[常用]
select * from emp e,dept d where e.deptno = d.deptno;
- 內連接
select * from emp e inner join dept d on e.deptno = d.deptno; --內連接與等值連接效果相同
- 外連接
- 查詢出所有部門,以及部門下的員工信息
select * from emp e right join dept d on e.deptno = d.deptno;
- 查詢所有員工,以及員工所屬部門
select * from emp e left join dept d on e.deptno = d.deptno;
- oracle中專用外連接
select * from emp e,dept d where e.deptno(+) = d.deptno; --(+)寫在e.deptno後,顯是的是d的全部信息,此時與右外連接效果相同 --當(+)寫在d.deptno後,顯是的是e的全部信息,此時與左外連接效果相同
- 自連接:自連接就是站在不同的角度把一張表看成多張表
- 查詢出員工姓名,員工領導的姓名
select el.ename,e2.ename from emp e1,emp e2 where e1.mgr = e2.empno;
- 查詢出員工姓名、員工部門名稱、員工領導姓名
select e1.ename,d.dname,e2.ename from emp e1,dept d,emp e2 where e1.deptno = d.deptno and e1.mgr = e2.empno;
- 查詢出員工姓名、員工部門名稱、員工領導姓名、員工領導部門名稱
select e1.ename,d1.dname,e2.ename,d2.dname from emp e1,dept d1,emp e2,dept d2 where e1.deptno = d1.deptno and e1.mgr = e2.empno and e2.deptno = d2.deptno;
- 子查詢
- 子查詢返回一個值
- 查詢出工資和SCOTT一樣的員工信息
select * from emp where sal in (select sal from emp where ename = 'SCOTT'); (注意:在與名字進行比較的時候,要考慮公司員工重名的現象,所以不能用=,而是用in)
- 子查詢返回一個集合
- 查詢出工資和10號部門任意員工一樣的員工信息
select * from emp where sal in (select sal from emp where deptno = 10);
- 子查詢返回一張表
- 查詢出每個部門最低工資,和最低工資員工姓名,和該員工所在部門名稱
--1. 先查詢出每個部門最低工資 select deptno,min(sal) msal from emp group by deptno; --2. 三表聯查,得到最終結果[重點] select t.deptno,t.msal,e.ename,d.dname from(select deptno,min(sal) msal from emp group by deptno; ) t,emp e,dept d where t.deptno = e.deptno and t.msal = e.sal and e.deptno = d.deptno;
十三. Oracle中的分頁【重點】
- 行號:rownum
--rownum行號,當我們在做select操作的時候,每查詢出一行記錄,就會在該行上加一個行號rownum。 --rownum不屬於任何一張表,多以不能使用表名/表的別名.rownum 行號從1開始,依次遞增,不能跳着走 --注意:rownum 不能進行 大於一個非0正數的操作。如:where rownum>5(錯)
- emp表工資倒敘排列後,每頁五條記錄,查詢第二頁,即查詢(第6-10條記錄)
--排列操作會影響rownum的順序 select * from( select rownum rn,e.* from( --給內層rownum起別名,供外部調用 select * from emp order by sal desc --先進性逆序排列,此時因爲先執行的select * from emp, --所以已經有了一個行號的排列,在進行逆序排列時候,行號就會變亂, --所以需要外部再對逆序後的數據進行重新對行號排列, --也就是再進行一次select。 ) e where rownum<11 )where rn>5 --此處是調用內部rownum的記錄,因爲內層rownum並沒有重新排列,且已經是內部查詢結果表中的數值, --可以調用,且不是表名/表別名.rownum調用的方式
- 【重點】:記住分頁架構,除了最內部查詢語句外,外兩層除了分頁規則的數字外,都是固定的。
select * from( select rownum rn,e.* from( --外部架構不變 select******可變************* ) e where rownum<11 )where rn>5 --其中,11和5是分頁規則,應該是由程序傳過來的可變值,不能寫死
十四. 視圖
- 視圖的概念:視圖就是提供一個查詢的窗口,所有的數據來源於表
- -創建表可以跨用戶創建
--查詢語句創建表 create table emp as select * from scott.emp;
- 創建視圖【必須有dba權限】
create view v_emp as select ename,job from emp;--創建視圖v_emp,注意視圖命名規範
- -查詢視圖
select * from v_emp;
- 修改視圖:注意:修改視圖,視圖對應的表中數據也修改了。–不建議修改視圖,視圖只用來進行查詢
update v_emp set job='CLERK' where ename = 'ALLEN'; commit;
- 創建只讀視圖
create view v_emp1 as select ename,job from emp with read only;
- 視圖的作用
視圖的作用? 第一:視圖可以屏蔽敏感字段,如(工資) 第二:保證總部和分部數據及時統一(總部修改原表,分部查看視圖)
十五. 索引
索引的概念:在表的列上建立一個二叉樹
達到大幅度提高查詢效率的目的,但是索引會影響增刪改的效率
- 單列索引(建立在單列上)
--單列索引觸發規則:條件必須是索引列中的原始值【面試】 --單行函數,模糊查詢都會影響索引的觸發 select * from emp where ename='SCOTT';
- 複合索引(建立在多列上)
--創建複合索引 create index idx_ename job on emp(ename,job); --複合索引中第一列爲優先檢索列 --如果要觸發複合索引,必須包含有優先檢索列中的原始值。 select * from emp where ename = 'SCOTT' and job='xx';--觸發複合索引 select * from emp where ename = 'SCOTT' or job='xx';--不觸發索引 select * from emp where ename = 'SCOTT';--觸發單列索引
十六. pl/sql編程語言
--pl/sql語言是對sql語言的擴展,使得sql語言具有過程化編程的特性 --pl/sql編程語言比一般的過程化編程語言,更加靈活高效 --pl/sql編程語言主要用來編寫存儲過程和存儲函數等
- pl/sql編程語言定義變量
declare --聲明變量區域,也可在此區域進行變量賦值 begin --執行代碼區域 end --框架固定
declare i number(2) := 10; --定義i變量, := 賦值語句 s varchar2(10):= '小ing'; begin dbms_output.put_line(i); --輸出語句 dbms_output.put_line(s); end;
- 引用型變量和into查詢語句賦值和記錄型變量
declare i number(2) := 10; --定義i變量, := 賦值語句 s varchar2(10):= '小ing'; ena emp.ename%type; --引用型變量:引用一行數據中的某一列,用以存放某一列的值 emprow emp%rowtype; --記錄型變量:引用某一行數據,存放的是一行數據,類似JavaBean begin dbms_output.put_line(i); --輸出語句 dbms_output.put_line(s); select ename into ena from emp where empno = 7788; --使用select語句,查詢一列的值,賦值給引用型變量:ena dbms_output.put_line(ena); select * into emprow from emp where empno = 7788; --使用select語句,查詢一行的值,賦值給記錄型變量:emprow dbms_output.put_line(emprow.ename || '的工作爲:' || emprow.job); --||爲連接符,類似於Java中的+,可進行字符串拼接 end;
- emp.ename%type; --引用型變量:引用一行數據中的某一列,用以存放某一列的值
emprow emp%rowtype; --記錄型變量:引用某一行數據,存放的是一行數據,類似JavaBean- pl/sql中的if判斷
輸入小於18的數字,輸出未成年,輸入大於18小於40的數字,輸出中年人,輸入大於40的數字,輸出老年人 declare i number(3) := &i; --表示輸入一個i值,賦值給i,輸入:&加一個變量(變量名隨意) begin if i<18 then dbms_output.put_line('未成年'); elsif i<40 then --注意是elsif 中間沒有e,也可以省略elsif 直接if,else dbms_output.put_line('中年人'); else dbms_output.put_line('老年人'); end if; --最後if結束才加; end;
- pl/sql中的循環 關鍵字:loop
--用三種方式輸出1-10十個數字 --while循環 declare i number(2) := 1; --定義變量,初始值爲1 begin while i<11 loop --設定循環條件 i<11 ,後面跟上開始循環標誌:loop dbms_output.put_line(i); --循環體 i := i+1; --設定自增,以達到循環結束條件 end loop; --結束循環標誌 end; --exit循環 [常用] declare i number(2) := 1; begin loop --開始循環 exit when i>10; --設立循環結束條件 dbms_output.put_line(i); --循環體 i := i+1; --循環體,設定自增,以達到循環結束條件 end loop; --結束循環 end; --for循環 declare --for循環不需要額外設定變量 begin for i in 1..10 loop --設定i變量,在1-10之間循環,loop開始循環 dbms_output.put_line(i); end loop; --結束循環 end;
- pl/sql中的遊標(類似於Java中的集合,可存放多個變量,用於多行記錄):cursor
- 輸出emp表中所有員工的姓名
declare cursor cl is select * from emp; --cursor:定義遊標的關鍵字 ,此時已經將emp中所有行信息存入右邊cl中 emprow emp%rowtype; --定義一個記錄型變量,因爲遍歷出每行數據都是一整行 begin open cl; --必須打開遊標 loop fetch cl into emprow; --fetch:遍歷取出一行數據,存於emprow中 exit when cl%notfound; --cl%notfound當cl中沒有數據的時候,退出循環 dbms_output.put_line(emprow.ename); end loop; close cl; --關閉遊標 end;
- 給指定部門員工漲工資
declare cursor c2(eno emp.deptno%type) --定義一個帶參數的遊標:c2(eno emp.deptno%type) 參數的變量名:eno, --參數遍歷的類型:emp.deptno%type:與emp.deptno的類型一致 is select empno from emp where deptno = eno; --將eno號部門的員工編號存入遊標c2 en emp.empno%type; begin open c2(10); --打開遊標的同時傳入參數10,即給10號部門員工漲工資 loop fetch c2 into en; --取出遊標中一行數據存入en exit when c2%notfound; update emp set sal=sal+100 where empno = en; commit; end loop; close c2; end;
十七. 存儲過程
存儲過程:存儲過程就是提前已經編譯好的一段pl/sql語言,放置在數據庫端:procedure
可以直接被調用,這一段pl/sql一般都是固定步驟的業務,有Java端直接調用
給指定員工漲工資
create or replace procedure p1(eno emp.empno%type) --如果不寫in/out,則默認是in is begin update emp set sal=sal+100 where empno = eno; commit; end; --存儲過程結構固定 --調用 select * from emp where empno = 7788; --測試存儲過程p1 declare begin p1(7788); end;
- 存儲函數:有返回值,並且調用存儲函數必須有返回值接收:function
計算指定員工的年薪
create or replace function f_yearsal(eno emp.empno%type) return number --number不能指定長度 is s number(10);--定義變量,用於存儲查詢結果,並返回 begin select sal*12+nvl(comm,0) into s from emp where empno = eno; return s; end; --測試存儲函數 declare s number(10); begin s:=f_yearsal(7788); dbms_output.put_line(s); end;
out類型參數
--使用存儲過程來計算年薪 create or replace procedure p_yearsal(eno emp.empno%type,yearsal out number)--定義變量yearsal,用於將結果存入其中 is s number(10); c emp.comm%type; begin select sal*12,nvl(comm,0) into s,c from emp where empno = eno; yearsal := s+c; end; --測試p_yearsal declare yearsal number(10);--定義結果接收參數 begin p_yearsal(7788,yearsal);--調用存儲過程,將結果存入第二個參數中 dbms_output.put_line(yearsal); end;
in和out類型參數的區別
--凡是【參數】涉及到into查詢語句賦值或者:=賦值,都必須使用out來修飾,也就是說, --如果參數需要用into或者:=賦值,都需要定義爲out類型
十八. JAVA連接Oracle,以及其中的存儲函數和存儲過程
- 連接Oracle需要的jar包
--Oracle10g對應:ojdbc14.jar,SID:xe --Oracle11g對應:ojdbc6.jar SID:orcl
- pom.xml文件引入jar包
<dependencies> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc14</artifactId> ---連接Oracle必要的jar包--對應Oracle10g <version>10.2.0.4.0</version> <scope>runtime</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies>
- 連接參數
Dirver="oracle.jdbc.driver.OracleDriver" URL = "jdbc:oracle:thin:@localhost:1521:xe";//xe爲連接oracle的SID,@後爲Oracle服務器所在的IP地址,1521:Oracle端口號 USER = "itoracle"; PASSWORD=""itoracle";" --查看連接Oracle服務器的SID和數據庫名(cmd中) //查看本機的oracle的sid:select instance_name from v$instance; //查看本機的oracle的數據庫名:select name from v$database;
- 具體代碼
- java連接Oracle,執行簡單的sql查詢語句(PreparedStatement類)
@Test public void javaCallOracle() throws Exception{ //加載oracle驅動 Class.forName("oracle.jdbc.driver.OracleDriver"); //得到Connection連接 Connection connection = DriverManager.getConnection(url,user,password); //得到預編譯Statement對象 PreparedStatement pst = connection.prepareStatement("SELECT * FROM person where pid = ?"); //給參數賦值 pst.setObject(1,1); //執行查詢 ResultSet set = pst.executeQuery(); while(set.next()){ System.out.println(set.getString("pname")); } set.close(); pst.close(); connection.close(); }
- java連接Oracle,調用存儲過程(CallableStatement類),注意存儲過程參數的寫法:OracleTypes.NUMBER
@Test public void javaCallOracleProcedure() throws Exception { //加載oracle驅動 Class.forName("oracle.jdbc.driver.OracleDriver"); //得到Connection連接 Connection connection = DriverManager.getConnection(url,user,password); //CallableStatement類就是調用存儲過程和存儲函數的專門的類,使用prepareCall方法。 CallableStatement call = connection.prepareCall("{call p_yearsal(?,?)}");//{call 存儲過程名(參數1,參數2)} call.setObject(1,7788); //調用方法,給存儲過程輸出類型的參數,對應:OracleTypes.NUMBER call.registerOutParameter(2, OracleTypes.NUMBER); //執行sql call.execute(); System.out.println(call.getObject(2)); call.close(); connection.close(); }
- java連接Oracle,調用存儲函數(CallableStatement類),注意存儲函數參數的寫法:返回值類型OracleTypes.NUMBER
@Test public void javaCallOracleFunction() throws Exception{ //加載oracle驅動 Class.forName("oracle.jdbc.driver.OracleDriver"); //得到Connection連接 Connection connection = DriverManager.getConnection(url,user,password); //使用CallableStatement類調用存儲函數 CallableStatement call = connection.prepareCall("{? = call f_yearsal(?)}"); //存儲函數有返回值,所以有一個參數在最前面作爲接收參數 //傳遞參數 call.setObject(1,OracleTypes.NUMBER);//爲接收參數設定類型 call.setObject(2,7788); //執行語句 call.execute(); //輸出返回結果 System.out.println(call.getObject(1)); call.close(); connection.close(); }
- CallableStatement類參數指定方法
/** * CallableStatement類調用存儲過程和存儲函數的參數指定方法 * {call p_yearsal(?,?)} --調用存儲過程,{call 存儲過程名(參數1,參數2)} 存儲過程無返回值,只有兩個參數,一個是輸入的數據,一個是數據類型 * {? = call f_yearsal(?)} --調用存儲函數,因爲存儲函數有返回值 */