Oracle基本操作+Java連接Oracle

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. 序列並不真的屬於任何一張表,但是可以和表邏輯綁定
  2. 默認從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

十. 函數

  1. 單行函數:作用在一行,返回一個值
  • 字符函數
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;
  • 一般通用條件表達式寫法比較常用
  1. 多行函數(聚合函數: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;

十二. 多表查詢

  1. 多表查詢中的一些概念
  • 笛卡爾積(與mysql相同)
select * from emp,dept;--得到笛卡爾積
  1. 等值連接[常用]
select * from emp e,dept d where e.deptno = d.deptno;
  1. 內連接
select *
from emp e inner join dept d
on e.deptno = d.deptno;
--內連接與等值連接效果相同
  1. 外連接
  • 查詢出所有部門,以及部門下的員工信息
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的全部信息,此時與左外連接效果相同
  1. 自連接:自連接就是站在不同的角度把一張表看成多張表
  • 查詢出員工姓名,員工領導的姓名
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;
  1. 子查詢
  1. 子查詢返回一個值
  • 查詢出工資和SCOTT一樣的員工信息
select * from emp where sal in (select sal from emp where ename = 'SCOTT');
(注意:在與名字進行比較的時候,要考慮公司員工重名的現象,所以不能用=,而是用in)
  1. 子查詢返回一個集合
  • 查詢出工資和10號部門任意員工一樣的員工信息
select * from emp where sal in (select sal from emp where deptno = 10);
  1. 子查詢返回一張表
  • 查詢出每個部門最低工資,和最低工資員工姓名,和該員工所在部門名稱
--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是分頁規則,應該是由程序傳過來的可變值,不能寫死

十四. 視圖

  1. 視圖的概念:視圖就是提供一個查詢的窗口,所有的數據來源於表
  2. -創建表可以跨用戶創建
--查詢語句創建表
create table emp as select * from scott.emp;
  1. 創建視圖【必須有dba權限】
create view v_emp as select ename,job from emp;--創建視圖v_emp,注意視圖命名規範
  1. -查詢視圖
select * from v_emp;
  1. 修改視圖:注意:修改視圖,視圖對應的表中數據也修改了。–不建議修改視圖,視圖只用來進行查詢
update v_emp set job='CLERK' where ename = 'ALLEN';
commit;
  1. 創建只讀視圖
create view v_emp1 as select ename,job from emp with read only;
  1. 視圖的作用
視圖的作用?
第一:視圖可以屏蔽敏感字段,如(工資)
第二:保證總部和分部數據及時統一(總部修改原表,分部查看視圖)

十五. 索引

索引的概念:在表的列上建立一個二叉樹

達到大幅度提高查詢效率的目的,但是索引會影響增刪改的效率

  1. 單列索引(建立在單列上)
--單列索引觸發規則:條件必須是索引列中的原始值【面試】
--單行函數,模糊查詢都會影響索引的觸發
select * from emp where ename='SCOTT';
  1. 複合索引(建立在多列上)
--創建複合索引
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編程語言主要用來編寫存儲過程和存儲函數等
  1. 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;
  1. 引用型變量和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;

  1. emp.ename%type; --引用型變量:引用一行數據中的某一列,用以存放某一列的值
    emprow emp%rowtype; --記錄型變量:引用某一行數據,存放的是一行數據,類似JavaBean
  2. 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;
  1. 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;
  1. 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;

十七. 存儲過程

  1. 存儲過程:存儲過程就是提前已經編譯好的一段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;
  1. 存儲函數:有返回值,並且調用存儲函數必須有返回值接收: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,以及其中的存儲函數和存儲過程

  1. 連接Oracle需要的jar包
--Oracle10g對應:ojdbc14.jar,SID:xe
--Oracle11g對應:ojdbc6.jar SID:orcl
  1. 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>
  1. 連接參數
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;
  1. 具體代碼
  1. 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();
    }
  1. 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();
    }
  1. 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();
    }
  1. CallableStatement類參數指定方法
/**
 * CallableStatement類調用存儲過程和存儲函數的參數指定方法
 * {call p_yearsal(?,?)} --調用存儲過程,{call 存儲過程名(參數1,參數2)} 存儲過程無返回值,只有兩個參數,一個是輸入的數據,一個是數據類型
 * {? = call f_yearsal(?)} --調用存儲函數,因爲存儲函數有返回值
 */

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章