一、Oracle概述
使用Oracle數據庫的好處:
1) Oracle的運行效率比MySQL數據庫好高;2) Oracle數據庫安全性最高;
3) Oracle數據庫對分佈式的支持非常好;
二、Oracle數據庫的安裝
2.1 Oracle數據庫的下載
下載地址:https://www.oracle.com/downloads/index.html2.2 安裝Oracle數據庫的準備工作
1) 保證磁盤有足夠的空間;2) 足夠的內存空間。建議:把運行中的軟件關閉,包括:防火牆和殺毒軟件;
2.3 安裝Oracle數據庫
查看oracle11g的安裝和卸載此文章2.4 Oracle服務
打開服務窗口:控制面板》管理工具》服務,或者在運行中輸入“services.msc”命令。然後找到全部以Oracle開頭的服務。只需要開啓以下兩項即可:
OracleServiceXXX:Oracle的核心服務。如果要訪問Oracle數據庫就必須要啓動該服務。(必須啓動)
OracleOraDb11g_home1TNSListener:監聽器服務。如果要使用圖形化工具訪問Oracle數據庫就必須要啓動該服務。(建議啓動)三、連接Oracle數據庫
3.1 使用Oracle自帶SQLPlus工具
輸入用戶名scott和密碼tiger,然後回車。
如果看SQL>提示符就代表連接成功!
3.2 使用Oracle自帶的SQLDeveloper工具
打開SQLDeveloper工具:第一次啓動SQLDeveloper工具的時候,需要指定JDK1.8的根路徑。
主界面:
接着,點擊左上角綠色的加號 ,然後輸入數據庫連接信息。
主機名:訪問Oracle數據庫的地址。本地地址就是localhost;如果要訪問遠程Oracle數據庫服務器就要輸入服務器的IP地址;
SID:Oracle數據庫的實例名,例如:orcl;
輸入完成之後,然後點擊“連接”。
如果看到左邊出現了菜單樹,就代表登錄成功!
3.3 使用JDBC訪問Oracle
使用JDBC的步驟:第一步:把數據庫的驅動包導入到工程裏面;
第二步:加載驅動;
第三步:獲取數據庫連接;
第四步:創建Statement對象;
第五步:編寫SQL語句,然後就執行SQL語句;
第六步:遍歷結果集;
第七步:關閉資源(ResultSet、Statement、Connection);
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/*
使用JDBC的步驟:
第一步:把數據庫的驅動包導入到工程裏面;
第二步:加載驅動;
第三步:獲取數據庫連接;
第四步:創建Statement對象;
第五步:編寫SQL語句,然後就執行SQL語句;
第六步:遍歷結果集;
第七步:關閉資源(ResultSet、Statement、Connection);
*/
public class Demo1 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
//加載驅動(JDBC4.0)
//Class.forName("oracle.jdbc.OracleDriver");
//獲取數據庫連接
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:orcl", //Oracle的URL地址
"scott", //用戶名
"tiger"); //密碼
//創建Statement對象
stmt = conn.createStatement();
//編寫SQL並執行
rs = stmt.executeQuery("select * from emp");
//遍歷結果集
if (rs != null) {
while (rs.next()) {
int empno = rs.getInt("empno");
String ename = rs.getString("ename");
System.out.println("編號:" + empno + ",姓名:" + ename);
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
//關閉資源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
四、常用的SQLPlus命令
五、DDL(數據定義語言)
DDL命令:創建表、修改表、刪除表。5.1 創建表
* 語法結構:
create table 表名 (列 數據類型 [primary key] auto_increment,
列 數據類型 [default 默認值] [not null],
…,
constraint 約束名 約束類型(列),
…
);
Oracle數據庫的數據類型:
* 約束類型:
唯一約束、非空約束、主鍵約束、外鍵約束、check約束。check約束就是用來限制某一列的值。注意:在Oracle數據庫中沒有auto_increment關鍵字。使用序列來實現主鍵的自增長(後面章程有講解)。
--創建表
create table student (
id number(10) primary key,
name nvarchar2(20) not null,
gender nchar(1) default '男',
constraint uni_student_name unique(name),
constraint chk_student_gender check(gender in ('男', '女'))
);
5.2 複製表
*語法格式:
create table 表名as
select語句;
--複製表(結構和數據)
create table student_bak
as
select * from student where 1=2;
5.3 修改表
*添加列
alter table 表名add (列名 數據類型 [not null]);
--添加列
alter table student
add(score number(3));
注意:如果表裏面已經有數據,那麼添加新的列就不能夠指定not null約束。*修改列的數據類型
alter table 表名modify(列名 數據類型 [not null]);
--修改列的數據類型
alter table student
modify(name nvarchar2(50));
*修改列名
alter table 表名rename column 舊列名 to 新列名;
--修改列名
alter table student
rename column name to student_name;
*刪除列
alter table 表名drop(列1, 列2, …);
--刪除列
alter table student
drop(score);
5.4 刪除表
*語法格式:
drop table 表名 [purge];--刪除表
drop table stduent;
drop table student purge; --永久刪除
注意:如果指定了purge參數,那麼刪除表的時候就不會保留在回收站裏面。六、DML(數據操作語言)
6.1 添加數據
* 語法格式:
insert into 表名(列1, 列2, …)values(值1, 值2, …);
--添加數據
insert into emp(empno, ename)
values(1000, 'JACKY');
6.2 複製數據
*語法格式:
insert into 表1(列1, 列2, …)select 列1, 列2, … from 表2;
--複製表
insert into student_bak(id, name)
select empno, ename from emp;
注意:複製表和被複製表的列的數量和類型要保持一致。6.3 修改數據
* 語法格式:
update 表名 set 列1=值1, 列2=值2, … [where條件];--修改表的數據
update emp
set ename = '張三'
where empno = 1000;
6.4 刪除數據
*語法格式:
delete from 表名 [where條件];--刪除數據
delete from student_bak;
*delete和truncate命令的區別:
1) delete命令先把要刪除的數據查詢出來,然後再進行刪除;truncate命令先把整個表刪除,然後再重新創建表;因此,如果刪除的數量很多,那麼truncate命令的執行效率比delete命令要高;2) delete命令可以刪除指定數據;truncate命令只能夠把整個表刪除;
七、DQL(數據查詢語言)
7.1 多表查詢
多表查詢:同時查詢兩張或兩張以上的表。*執行多表查詢的注意事項:
1) 執行多表查詢的時候,一張表的每一行記錄會跟另外一張表的每一行記錄進行組合,然後產生新的記錄,這種現象也稱爲“笛卡爾積”現象。2) 笛卡爾積現象會產生許多的垃圾數據,因此在實際開發中要儘量避免笛卡爾積現象。如果要消除笛卡爾積,那麼只需要在執行多表查詢的時候添加連接條件:就是一個表的外鍵列等於另外一個表的主鍵列。
注意:執行多表查詢的時候就一定會出現笛卡爾積現象。如果要消除笛卡爾積就必須要添加連接條件。
多表查詢分爲:內連接和外連接。
7.1.1 內連接
內連接分爲:等值連接和非等值連接。等值連接就是指連接條件使用等號的連接。
非等值連接就是指連接條件使用<, <=, >, >=, <>符號的連接。
7.1.2 外連接
7.1.2.1 左外連接
左連接:左邊的表作爲主表,無論條件是否滿足,主表的數據都會被查詢出來。*語法格式:
select 列信息 from 表1 left join 表2 on 連接條件;--查詢所有員工的信息以及該員工所在部門名稱,無論員工的部門編號是否存在,員工的記錄都會被查詢出來。(左連接)
select emp.*, dept.dname
from emp left join dept
on emp.deptno = dept.deptno;
注意:left join左邊的表是主表。7.1.2.2 右外連接
右連接:右連接就是右邊的表作爲主表,無論條件是否滿足,主表的數據都會被查詢出來。*語法格式:
select 列信息 from 表1 right join 表2 on 連接條件;
--查詢所有員工的信息以及該員工所在部門名稱,無論部門是否存在,部門的記錄都會被查詢出來。(右連接)
select emp.*, dept.dname
from emp right join dept
on emp.deptno = dept.deptno;
注意:right join右邊的表是主表。除此以外,外連接還可以這樣:
select 列信息 from 表1, 表2 where 表1.列1 = 表2.列2(+);
如果沒有加號的一方就是主表。有加號的一方就是從表。這種寫法是Oracle方言。一般不推薦使用。
--oracle方言
select emp.*, dept.dname from emp, dept where emp.deptno(+) = dept.deptno;
7.2 分組查詢
*語法結構:
select 組信息 from 表名 group by 分組字段 [having 分組條件];--需求:查詢每一個部門的平均工資
select deptno, avg(sal)
from emp
group by deptno;
組信息:分組字段或聚合函數。面試:
*什麼時候使用where條件,什麼時候使用having條件?
如果是分組前的條件就使用where,如果是分組後的條件就使用having。*select語句:select、from、where、group by、having、order by。
它們的執行順序:from > where > group by > having > select > order by。--需求:統計每一個部門工資大於2000的人數
select count(*)
from emp
where sal > 2000
group by deptno;
--需求:統計每一個部門工資大於2000的人數,但是該部門的人數必須要大於1。
select count(*) as total
from emp
where sal > 2000
group by deptno
having count(*) > 1
order by total asc;
7.3 子查詢
子查詢:在一個查詢中嵌套另外一個查詢。按照子查詢返回的結果:
a) 單行單列:可以放在where後面作爲一條條件。
--需求:查詢工資大於30部門最高工資的員工信息
Select max(sal) from emp where deptno = 30 ; -----2850
Select * from emp where sal > 2850;
===================================================================
select * from emp where sal > (select max(sal) from emp where deptno = 30);
b) 單行多列:可以放在where後面作爲一個條件。
--需求:查詢職位、部門編號與SCOTT用戶的職位和部門編號相同的員工信息。
select job, deptno from emp where ename = 'SCOTT'; -----analyst 20
select * from emp where job = “analyst” and deptno = “20”;
==============================================================
select * from emp where (job, deptno) = (select job, deptno from emp where ename = 'SCOTT');
c) 多行單列:可以放在where後面作爲一個條件。
--需求:獲取所有所在地是NEW YORK的員工信息
select deptno from dept where loc = 'NEW YORK'; -----50 10
select * from emp where deptno in (50,10);
=================================================================
select * from emp where deptno in (select deptno from dept where loc = 'NEW YORK');
d) 多行多列:可以作爲一個臨時表放在from後面。
--需求:查詢所有員工的姓名、職位、工資、所在部門的平均工資
select deptno, avg(sal) avgSal from emp group by deptno; ----查詢出每個部門的平均工資
====================================================
select e.ename, e.job, e.sal, t.avgSal
from emp e, (select deptno, avg(sal) avgSal from emp group by deptno) t
where e.deptno = t.deptno;
除此以外,子查詢還可以放在select後面作爲一列。
--需求:查詢所有員工的姓名、職位、工資、所在部門的平均工資
select e.ename, e.job, e.sal, (select avg(sal) from emp where deptno = e.deptno) from emp e;
八、僞表和僞列
8.1 僞表dual
僞表就是是一個虛擬的表。它的作用就是用來構造一個符合SQL語法的select語句。--查詢當前用戶
select user from dual;
--查詢系統時間
select sysdate, systimestamp from dual;
--調用函數
select to_char(sysdate, 'yyyy-MM-dd') from dual;
--執行運算
select 1+2 from dual;
應用場景:1)查詢系統參數;2)調用函數;3)執行運算:4)生成或查詢序列的值;
8.2 僞列rowid(瞭解)
當用戶往Oracle數據庫添加數據的時候,Oracle數據庫會爲該條數據生成一個ID,該ID是該條記錄在磁盤上的物理地址。僞列rowid的作用就是標識每一行的記錄。正常情況下,一般用戶是不會使用rowid獲取某一條記錄。
8.3 僞列rownum(重點)
當用戶查詢數據庫的時候,Oracle數據庫會對每一條記錄從1開始進行編號。然後把該編號保存在rownum列中。它的作用:實現分頁功能。注意:如果使用rownum作爲條件,是不可以使用>, >=, =符號。因爲每次查詢的時候,rownum的值都不一樣。
*分頁的實現思路:
先查詢前面10條的記錄。然後再查詢的結果作爲一個臨時表。接着再從臨時表的第6條記錄開始查詢。--查詢emp表的第二頁數據,每頁顯示5條記錄
select *
from (select rownum r, emp.* from emp where rownum <= 10)
where r >= 6;
九、運算符
9.1常用的運算符
算術運算符:+ - * /比較運算符:> >= <= < = != in between…and… is null is not null
邏輯運算符:and or not
連接運算符:||
集合運算符:
1) 並集:union(去重複)、union all(有重複)
2) 交集:intersect
3) 減集:minus
--查詢員工的年薪(工資*12+獎金)
select ename, sal * 12 + comm as 年薪 from emp;
--工資大於 2000 的員工信息
select * from emp where sal > 2000;
--工資大於等於 2000,而且工資小於等於 3000 的員工信息
select * from emp where sal between 2000 and 3000;
--查詢所有獎金不爲空的員工信息
select * from emp where comm is not null;
--查詢員工的職位信息
select ename || '的職位是:' || job from emp;
--查詢工資大於 1000 並且小於 2500 的員工名字
select ename from emp where sal > 1000 and sal < 2500;
--查詢工資大於 2000 並且小於 3500 的員工名字
select ename from emp where sal > 2000 and sal < 3500;
--並集
select ename from emp where sal > 1000 and sal < 2500 union select ename from emp where sal > 2000 and sal < 3500;
select ename from emp where sal > 1000 and sal < 2500 union all select ename from emp where sal > 2000 and sal < 3500;
--交集
select ename from emp where sal > 1000 and sal < 2500 intersect select ename from emp where sal > 2000 and sal < 3500;
--減集
select ename from emp where sal > 2000 and sal < 3500 minus
select ename from emp where sal > 1000 and sal < 2500;
9.2 運算符的優先級
9.3 函數
9.3.1 數值函數
--數值函數
select mod(10, 3) from dual;
select round(3.1415, 3), round(1314.1415, -2), round(1314.1415) from dual;
select trunc(3.1415, 3), trunc(1314.1415, -2), trunc(1314.1415) from dual; --3.141 1300 1314
9.3.2 字符型函數
--字符型函數
select * from emp where length(ename) > 5; --查詢姓名的長度大於 5 的員工信息
select replace('明天放假嗎?真的放假嗎?', '放假', '自習') from dual; --替換
select substr('13088888888', 4, 8) from dual; --截取
9.3.3 日期函數
--獲取當前時間
select systimestamp from dual;
--獲取某日期的年份
select extract(year from sysdate) from dual;
--需求:查詢 2016 入職的員工信息
select * from emp where extract(year from hiredate) = 2016;
--獲取昨天的日期
select sysdate - interval '1' day from dual;
select sysdate - interval '1' month from dual;
select systimestamp + interval '1' hour from dual;
9.3.4 轉換函數
--轉換函數
select ename, job, to_char(hiredate, 'yyyy" 年 "MM" 月 "dd" 日 "'), to_char(sal,'$999,999,999') from emp;
select to_date('2017/04/01', 'yyyy/MM/dd') from dual;
select date '2017-04-01' from dual;
select to_timestamp('2017/04/01 12:56:12', 'yyyy/MM/dd hh24:mi:ss') from dual;
select timestamp '2017-04-01 12:56:12' from dual;
9.3.5 其他函數
--給所有入職超過 1 年的員工獎金加 300 update emp
set comm = nvl(comm, 0) + 300 where months_between(sysdate, hiredate) >= 12;
--查詢員工的部門名稱
select ename, deptno, decode(deptno, '10', 'ACCOUNTING', '20', 'SALES', '其他部門') from emp;