1.點擊Tools—>Preferences—>Connection鏈接,填寫鏈接信息:java
2.鏈接Oracle數據庫,默認鏈接方式:mysql
192.168.88.6:表示安裝Oracle數據庫的服務器地址;git
1521:默認端口號github
orcl:默認Oracle安裝數據庫名稱sql
3.使用修改tnsnames.ora文件配置方式鏈接:數據庫
①複製遠程服務器Oracle安裝目錄中的tnsnames.ora到本地的instantclient_12_1軟件目錄下:編程
②修改本地複製的tnsnames.ora配置以下:服務器
③設置本地tnsnames.ora到本地的環境變量配置中:oracle
配置完環境變量以後在繼續登陸PL/SQL去鏈接Oracle數據庫就可使用ORCL去鏈接數據庫了。app
Oracle數據庫是數據的物理存儲。這就包括(數據文件ORA或者DBF、控制文件、聯機日誌、參數文件)。其實Oracle數據庫的概念和其它數據庫不同,這裏的數據庫是一個操做系統只有一個庫。能夠看做是Oracle就只有一個大數據庫。
一個Oracle實例(Oracle Instance)有一系列的後臺進程(Background Processes)和內存結構(Memory Structures)組成。一個數據庫能夠有n個實例。
用戶是在實例下創建的。不一樣實例能夠建相同名字的用戶。
表空間是Oracle對物理數據庫上相關數據文件(ORA或者DBF文件)的邏輯映射。一個數據庫在邏輯上被劃分紅一到若干個表空間。每一個表空間包含了在邏輯上相關的一組結構。每一個數據庫至少有一個表空間(稱之爲system表空間)。
每一個表空間由同一磁盤上的一個或多個文件組成。這些文件叫數據文件(datafile)。一個數據文件只能屬於一個表空間。
數據文件是數據庫的物理存儲單位。數據庫的數據是存儲在表空間中的,真正是在某一個或者多個數據文件中。而一個表空間能夠由一個或多個數據文件組成,一個數據文件只能屬於一個表空間。一旦數據文件被加入到某個表空間後,就不能刪除這個文件,若是要刪除某個數據文件,只能刪除所屬於的表空間才行。
注意:表的數據,是有用戶放入某一個表空間的,而這個表空間會隨機把這些表數據放到一個或者多個數據文件中。
因爲oracle的數據庫不是普通的概念,oracle是有用戶和表空間對數據進行管理和存放的。可是表不是有表空間去查詢的,而是由用戶去查的。由於不一樣用戶能夠在同一個表空間創建同一個名字的表!這裏區分就是用戶了。
表空間是Oracle數據庫的邏輯單元。數據庫--表空間,一個表空間能夠與多個數據文件(物理結構)關聯。
一個數據庫下能夠創建多個表空間,一個表空間能夠創建多個用戶、一個用戶下能夠創建多個表。
create tablespace mytable datafile 'c:\mytable.dbf' size 100m autoextend on next 10m
其中
mytable:爲表空間名稱
datafile:指定表空間對應的數據文件
size:後定義的是表空間的初始大小
autoextend on:自動增加,當表空間存儲都佔滿時,自動增加
next:後指定的是一次自動增加的大小
編寫好sql語句以後,點擊小齒輪按鈕,Excute執行便可。
以下語句是建立表空間語句:
建立用戶並給用戶受權:
切換登陸用戶:
先選擇Log off進行退出當前用戶,再選擇Log on進行登陸;修改登陸用戶名與密碼進行登陸便可;
No | 數據類型 | 描述 |
---|---|---|
1 | varchar,varchar2 | 表示一個字符串,可變長度,經常使用的類型是varchar2 |
2 | NUMBER | NUMBER(n)表示一個整數,長度是n |
3 | NUMBER | NUMBER(m, n)表示一個小數,總長度是m,小數是n,整數是m-n |
4 | DATA | 表示日期類型 |
5 | CLOB | 大對象,表示大文本數據類型,可存4G |
6 | BLOB | 大對象,表示二進制數據,可存4G |
語法:
create table 表名(
字段1 數據類型 [default 默認值],
字段2 數據類型 [default 默認值],
...
)
示例:
添加一列數據,若是多列數據使用(n1, n2):
--- 修改表結構 --- 添加一列 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;
添加數據insert:
---添加一條記錄 insert into person(pid, pname) values (1, '小明'); commit
修改數據update:
---修改一條記錄 update person set pname = '小馬' where pid = 1; commit;
刪除表數據delete/truncate/drop:
---三個刪除 ---刪除表中所有記錄 delete from person; ---刪除表結構 drop table person; ---先刪除表,再次建立表。效果等同於刪除表中所有記錄 ---在數據量大的狀況下,尤爲在表中帶有索引的狀況下,該操做效率高。 ---索引能夠提供查詢效率,可是會影響增刪改效率 truncate table person;
---序列不真的屬於任何一張表,可是能夠邏輯和表作綁定 ---序列:默認從1開始,依次遞增,主要用來給主鍵賦值使用 ---dual:虛表,只是爲了補全語法,沒有任何意義 create sequence s_person; select s person.currval from dual; ---添加一條記錄 insert into person (pid, pname) values (s_person.nextval, '小明'); commit; select * from person;
scott是給初學者學習的用戶,學習者能夠用Scott登陸系統,注意scott用戶登陸後,就可使用Oracle提供的數據庫和數據表,這些都是oracle提供的,學習者不須要本身建立數據庫和數據表,直接使用這些數據庫和數據表練習SQL。
---scott用戶,密碼是tiger ---解鎖scott用戶 alter user scott account unlock; ---解鎖scott用戶的密碼【此句也能夠用來重置密碼】 alter user scott identified by tiger;
單行函數:做用於一行,返回一個值。
多行函數:做用於多行,返回一個值。
字符函數
select upper('yes') from dual; -- YES select lower('YES') from dual; -- yes
數值函數
select round(26.16, 1) from dual; -- 四捨五入,後面的參數表示保留的位數,結果26.2 select round(26.16, -1) from dual; -- 往前保留一位小數,結果30 select trunc(56.16, 1) from dual; -- 直接截取,再也不看後邊位數的數字是否大於5。56.1 select mod(10, 3) from dual; -- 求餘數
日期函數
---查詢出emp表中全部員工入職距離如今幾天 select sysdate-e.hiredate from emp e; ---算出明天此刻 select sysdate+1 from dual; ---查詢出emp表中全部員工入職距離如今幾月 select months_between(sysdate, e.hiredate) from emp e; ---查詢出emp表中全部員工入職距離如今幾年 select months_between(sysdate, e.hiredate)/12 from emp e; ---查詢出emp表中全部員工入職距離如今幾周 select round((sysdate-e.hiredate)/7) from emp e;
轉換函數
日期轉換成字符串
注意:fm表示若是是"04"格式前面會自動省略0,展現爲"4";
---轉換函數 select to_char(sysdate, 'fm yyyy-mm-dd hh24:mi:ss') from dual;
字符串轉日期
---字符串轉日期 select to_date('2018-6-7 16:39:50', 'fm yyyy-mm-dd hh24:mi:ss') from dual;
多行函數(聚合函數)
---多行函數【聚合函數】:做用於多行,返回一個值。 select count(1) from emp; ---查詢總數量 select sum(sal) from emp; ---工資總和 select max(sal) from emp; ---最大工資 select min(sal) from emp; ---最低工資 select avg(sal) from emp; ---平均工資
--- 通用函數 --- 算出emp表中全部員工的年薪 --- 獎金裏面有null值,若是null值和任意數字作算術運算,結果都是null select e.sal*12+nvl(e.comm, 0) from emp e;
計算結果:
如下兩種表達式爲mysql、oracle通用表達式:
第一種:
---條件表達式 ---給emp表中員工起中文名 select e.ename, case e.ename when 'SMITH' then '曹賊' when 'ALLEN' then '大耳賊' when 'WARD' then '諸葛小兒' else '無名' --- 注意:若是else不寫則爲null end from emp e;
第二種:
---判斷emp表中員工工資,若是高於3000顯示高收入;若是高於1500低於3000顯示中等收入;其他顯示低收入 select e.sal, case when e.sal>3000 then '高收入' when e.sal>1500 then '中等收入' else '低收入' end from emp e;
其中"中文名"爲別名,別名使用雙引號,其他都用單引號。
---oracle專用條件表達式 select e.ename, decode(e.ename, 'SMITH', '曹賊', 'ALLEN', '大耳賊', 'WARD', '諸葛小兒', '無名') 中文名 from emp e;
---分組查詢 ---查詢出每一個部門的平均工資 ---分組查詢中,出如今group by 後面的原始列,才能出如今select後面 ---沒有出如今group by後面的列,想在select後面,必須加上聚合函數 ---聚合函數有一個特性,能夠把多行記錄變成一個值 select e.deptno, avg(e.sal) from emp e group by e.deptno;
別名問題:
---查詢出平均工資高於2000的部門信息 select e.deptno, avg(e.sal) asal from emp e group by e.deptno having avg(e.sal)>2000; ---全部條件都不能使用別名來判斷 ---好比下面的條件語句也不能使用別名當條件 select ename, sal s from emp where sal>1500;
分組group by與having問題:
---where是過濾分組前的數據,having是過濾分組後的數據 ---表現形式:where必須在group by以前,having是在group by以後 ---查詢出每一個部門工資高於800的員工的平均工資 ---而後再查詢出平均工資高於2000的部門 select e.deptno, avg(e.sal) asal from emp e where e.sal>800 group by e.deptno having avg(e.sal)>2000;
left join、right join、inner join
oracle中特有的鏈接方式,(+)在的地方表示right join等同
---oracle中專用外鏈接 select * from emp e, dept d where e.deptno(+) = d.deptno;
---查詢出員工姓名,員工領導姓名 ---自鏈接:自鏈接其實就是站在不一樣的角度把一張表當作多張表 select e1.ename, e2.ename from emp e1, emp e2 where e1.mgr = e2.empno;
---rownum行號:當咱們作select操做的時候, ---沒查詢出一行記錄,就會在該行上加上一個行號, ---行號從1開始,依次遞增,不能跳着走 ---emp表工資倒敘排列後,每頁五條記錄,查詢第二頁 ---排序操做會影響rownum的順序 select rownum, e.* from emp e order by e.sal desc ---若是涉及到排序,可是還要使用rownum的話,咱們能夠再次嵌套查詢 select rownum, t.* from( select rownum, e.* from emp e order by e.sal desc) t;
分頁查詢固定格式:
---emp表工資倒敘排列後,每頁五條記錄,查詢第二頁 ---rownum行號不能寫上大於一個正數 select * from( select rownum rn, tt.* from( select * from emp order by sal desc ---這裏能夠寫須要進行分頁的數據 ) tt where rownum < 11 ) where rn > 5;
視圖:視圖就是提供一個查詢的窗口,全部數據來自於原表。
-- 查詢語句建立表 create table emp as select * from scott.emp; select * from emp; -- 建立視圖【必須有dba權限】 create view v_emp as select ename, job from emp; -- 查詢視圖 select * from v_emp; -- 修改視圖[不推薦] update v_emp set job ='CLERK' where ename = 'ALLEN'; commit; -- 建立只讀視圖 create view v_emp as select ename, job from emp with read only;
視圖的做用:
第一:視圖能夠屏蔽掉一些敏感字段;
第二:保證總部和分部數據及時統一;
索引:索引就是在表的列上構建一個二叉樹,達到大幅度提升查詢效率的目的,可是索引會影響增刪改的效率。
索引分爲:單列索引與複合索引。
-- 建立單列索引 create index idx_ename on emp(ename); -- 單列索引觸發規則,條件必須是索引列中的原始值 -- 單行函數,模糊查詢,都會影響索引的觸發 select * from emp where ename = "SOCTT"; -- 複合索引 -- 建立複合索引 create index idx_enamejob 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編程語言是對sql語言的擴展,使得sql語言具備過程化編程的特性。
pl/sql編程語言比通常的過程化編程語言,更加靈活高效。
pl/sql編程語言主要用來編寫存儲過程和存儲函數等。
--- 聲明方法 --- 賦值操做可使用:=也可使用into查詢語句賦值 declare i number(2) := 10; s varchar2(10) := '小明'; ena emp.ename%type; ---引用型變量 emprow emp%rowtype; ---記錄型變量 begin dbms_output.put_line(i); dbms_output.put_line(s); select ename into ena from emp where empno = 7788; dbms_output.put_line(ena); select * into emprow from emp where empno = 7788; dbms_output.put_line(emprow.ename || '的工做爲:' || emprow.job) end;
--- 輸入小於18的數字,輸出未成年 --- 輸入大於18小於40的數字,輸出中年人 --- 輸入大於40的數字,輸出老年人 declare i number(3) := ⅈ begin if i<18 then dbms_output.put_line('未成年'); elsif i<40 then dbms_output.put_line('中年人'); else dbms_output.put_line('老年人'); end if; end;
--- pl/sql中的loop循環 --- 用三種方式輸出1到10是個數字 --- while循環 declare i number(2) := 1; --- 定義變量並賦值 begin while 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 begin for i in 1..10 loop dbms_output.put_line(i); end loop; end;
--- 輸出emp表中全部員工的姓名 declare cursor c1 is select * from emp; emprow emp%rowtype; begin open c1; loop fetch c1 into emprow; exit when c1%notfound; dbms_output.put_line(emprow.ename); end loop; close c1; end; --- 給指定部門員工漲工資 declare cursor c2(eno emp.deptno%type) is select empno from emp where deptno = eno; en emp.empno%type; begin open c2(10); loop fetch c2 into en; exit when c2%notfound; update emp set sal=sal+100 where empno = en; commit; end loop; close c2; end;
存儲過程:存儲過程就是提早已經編譯好的一段pl/sql語言,放置在數據庫中。
--- 給指定員工漲100塊錢 --- 使用or replace create or replace procedure p1(eno emp.empno%type) is begin update emp set sal=sal+100 where empno = eno; commit; end; --- 測試p1 declare begin p1(7788); end;
--- 經過存儲函數實現計算指定員工的年薪 --- 存儲過程和存儲函數的參數都不能帶長度 --- 存儲函數的返回值類型不能帶長度 create or replace function f_yearsal(eno emp.empno%type) return number is s number(10); begin select sal*12+nvl(comm, 0) into s from emp where empno = eno; return s; end; ---測試f_yearsql ---存儲函數在調用的時候,返回值須要接收 declare s number(10); begin s:= f_yearsal(7788); dbms_output.put_line(s); end; ---out類型參數如何使用 out類型參數使用: ---使用存儲過程來算年薪 create or replace procedure p_yearsal(eno emp.empno%type, yearsal out number) 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來修飾
語法區別:關鍵字不同;存儲函數比存儲過程多了兩個return
本質區別:存儲函數有返回值,而存儲過程沒有返回值。
若是存儲過程想實現有返回值的業務,咱們就必須使用out類型的參數。即使是存儲過程使用了out類型的參數,其本質也不是真的有了返回值。而是在存儲過程內部給out類型參數賦值,在執行完畢後,咱們直接拿到輸出類型參數的值。
咱們可使用存儲函數有返回值的特性,來自定義函數。
而存儲過程不能用來自定義函數。
--- 案例需求:查詢出員工姓名,員工所在部門名稱 --- 案例準備工做:把scott用戶下的dept表複製到當前用戶下 create table dept as select * from scott.dept; --- 使用傳統方式來實現案例需求 select e.ename, d.dname from emp e, dept d where e.deptno = d.deptno; ---使用存儲函數來實現提供一個部門編號,輸出一個部門名稱 create or replace function fdna(dno dept.deptno%type) return dept.dname%type is dna dept.dname%type; begin select dname into dna from dept where deptno = dno; return dna; end; --使用fdna存儲函數來實現案例需求:查詢出員工姓名,員工所在部門名稱 select e.ename, fdna(e.deptno) from emp e;
觸發器:就是指定一個規則,在咱們作增刪改操做的時候,主要知足該規則,自動觸發,無需調用。
觸發器分爲:語句級觸發器、行級觸發器
語句級觸發器:不包含有for each row的觸發器。
行級觸發器:包含有for each row的行級觸發器。
--- 語句級觸發器 --- 插入一條記錄,輸出一個新員工入職 create or replace trigger t1 after insert on person declare begin dbms_output.put_line('一個新員工入職'); end; ---觸發t1 insert into person values (1, '小紅'); commit; select * from person;
--- 行級觸發器 --- 不能給員工降薪 --- raise_application_error(-20001~20999之間, '錯誤提示信息'); create or replace trigger t2 before update on emp for each row declare begin if :old.sal > :new.sal then raise_application_error(-20001, '不能給員工降薪'); end if; end; ---觸發t2 select * from emp where empno = 7788; update emp set sal=sal-1 where empno = 7788; commit;
觸發器實現主鍵自增:
用到的是行級觸發器
--- 分析:在用戶作插入操做以前,拿到即將插入的數據。給該數據中的主鍵列賦值 create or replace trigger auid before insert on person for each row declare begin select s_person.nextval into :new.pid from dual; end; ---查詢person表數據 select * from person; ---使用auid實現主鍵自增 insert into person (pname) values ('a'); commit;
oracle10g使用ojdbc14.jar包;
1.建立Maven工程,導入如下依賴jar包:
<dependencies> <dependency> <groupId>com.oralce</groupId> <artifactId>ojdbc14</artifactId> <version>10.2.0.4.0</version> <scope>runtime</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> </dependencies>
String driverName = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@192.168.79.10:1521:orcl";
String username = "scott";
String password = "tiger";
1.執行查詢操做:
@Test public void javaCallOracle() throws Exception { //加載數據庫驅動 Class.forName("oracle.jdbc.driver.OracleDriver"); //獲得Connection鏈接 Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@192.168.88.6:1521:orcl", "scott", "tiger"); //獲得預編譯的Statement對象 PreparedStatement pstm = connection.prepareStatement("select * from emp where empno = ?"); //給參數賦值 pstm.setObject(1, 7788); //執行數據庫查詢操做 ResultSet rs = pstm.executeQuery(); //輸出結果 while(rs.next()){ System.out.println(rs.getString("ename")); } //釋放資源 rs.close(); pstm.close(); connection.close(); }
2.java調用存儲過程:
/** * java調用存儲過程 * {?= call <procedure-name>[(<arg1>,<arg2>, ...)]} 調用存儲函數使用 * {call <procedure-name>[(<arg1>,<arg2>, ...)]} 調用存儲過程使用 * @throws Exception */ @Test public void javaCallProcedure() throws Exception { //加載數據庫驅動 Class.forName("oracle.jdbc.driver.OracleDriver"); //獲得Connection鏈接 Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@192.168.88.6:1521:orcl", "scott", "tiger"); //獲得預編譯的Statement對象 CallableStatement pstm = connection.prepareCall("{call p_yearsal(?, ?)}"); //給參數賦值 pstm.setObject(1, 7788); pstm.registerOutParameter(2, OracleTypes.NUMBER); //執行數據庫查詢操做 pstm.execute(); //輸出結果[第二個參數] System.out.println(pstm.getObject(2)); //釋放資源 pstm.close(); connection.close(); }
3.java調用存儲函數
/** * java調用存儲函數 * {?= call <procedure-name>[(<arg1>,<arg2>, ...)]} 調用存儲函數使用 * {call <procedure-name>[(<arg1>,<arg2>, ...)]} 調用存儲過程使用 * @throws Exception */ @Test public void javaCallFunction() throws Exception { //加載數據庫驅動 Class.forName("oracle.jdbc.driver.OracleDriver"); //獲得Connection鏈接 Connection connection = DriverManager.getConnection("jdbc:oracle:thin:@192.168.88.6:1521:orcl", "scott", "tiger"); //獲得預編譯的Statement對象 CallableStatement pstm = connection.prepareCall("{?= call f_yearsal(?)}"); //給參數賦值 pstm.setObject(2, 7788); pstm.registerOutParameter(1, OracleTypes.NUMBER); //執行數據庫查詢操做 pstm.execute(); //輸出結果[第一個參數] System.out.println(pstm.getObject(1)); //釋放資源 pstm.close(); connection.close(); }
本博客相關文檔筆記均已上傳至GitHub地址: