Oracle入门教程与实战
前言
Oracle 數據庫系統是美國 Oracle 公司(甲骨文)提供的以分布式數據庫為核心的一組軟件產品,是目前最流行的客戶/服務器 (Client/Server) 或 B/S 體系結構的數據庫之一,比如 SilverStream 就是基于數據庫的一種中間件。 Oracle 數據庫是目前世界上使用最為廣泛的數據庫管理系統,作為一個通用的數據庫系統,它具有完整的數據管理功能;作為一個關系型數據庫,它是一個完備關系的產品;作為分布式數據庫它實現了分布式處理功能,但它的所有知識,只要在一種機型上學習了 Oracle 知識,便能在各種類型的機器上使用它。
Oracle 的基本使用
連接命令
sqlplus /nolog
進入 sqlplus 環境。其中 /nolog 是不登陸到數據庫服務器的意思,如果沒有 /nolog 參數, sqlplus 會提示你輸入用戶名和密碼。
C:\Users\Administrator>sqlplusSQL*Plus: Release 11.1.0.7.0 - Production on 星期三 10月 16 10:30:42 2019Copyright (c) 1982, 2008, Oracle. All rights reserved.請輸入用戶名:conn[etc]
用法: conn 用戶名 / 密碼 @網絡服務名 [as sysdba/sysoper] 當用特權用戶身份連接時,必須帶上 as sysdba 或是 as sysoper
以系統管理員 (sysdba) 身份連接數據庫
SQL> conn / as sysdba 已連接。創建用戶
SQL> create user huang identified by 123456;用戶已創建。用戶授權
SQL> grant create session,connect,resource to huang;授權成功。連接到數據庫
SQL> conn huang/123456 已連接。show user
顯示當前用戶名
SQL> show user USER 為 "HUANG"passw[ord]
用于修改用戶的密碼,如果要想修改其它用戶的密碼,需要用 sys/system 登錄。
SQL> passw 更改 HUANG 的口令 舊口令: 新口令: 重新鍵入新口令: 口令已更改disc[onnect]
用于斷開與當前數據庫的連接 (不退出 sqlplus )
SQL> disc 從 Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 斷開 SQL>exit
用于斷開與當前數據庫的連接 (同時退出 sqlplus )
SQL> exit 從 Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - Production With the Partitioning, OLAP, Data Mining and Real Application Testing options 斷開C:\Users\Administrator>文件操作命令
start 和 @
運行 SQL 腳本
SQL> @ d:\c.sql表已創建。或是
SQL> start d:\c.sql表已創建。edit
該命令可以編輯指定的 SQL 腳本
SQL> edit d:\c.sql這樣會把 d:\c.sql 這個文件打開
spool
該命令可以將 sqlplus 屏幕上的(查詢)內容輸出到指定文件中去
SQL> spool d:\d.sql SQL> select ASSETNUM 序號,DESCRIPTION 描述 from ASSET; SQL> spool off交互式命令
&
可以替代變量,而該變量在執行時,需要用戶輸入, Oracle 會提示用戶輸入值
SQL> select * from ACCOUNTDEFAULTS where ORGID='&ORGID'; 輸入 orgid 的值:顯示和設置環境變量
可以用來控制輸出的各種格式,如果希望永久的保存相關設置,可以修改 glogin.sql 腳本
linesize
設置顯示行的寬度,默認是 80 個字符
SQL> show linesize linesize 80 SQL> set linesize 90 SQL> show linesize linesize 90pagelize
設置每頁顯示的行數目,默認是 14 ,用法和 linesize 一樣
SQL> show pagesize pagesize 14 SQL> set pagesize 20 SQL> show pagesize pagesize 20Oracle 用戶管理
創建用戶
在 Oracle 中要創建一個新的用戶使用 create user 語句, 一般是具有 dba (數據庫管理員)的權限才能使用。
create user 用戶名 identified by 密碼 ; SQL> create user zhangsan identified by 123456; create user zhangsan identified by 123456* 第 1 行出現錯誤: ORA-01031: 權限不足我們連接到 sysdba 創建用戶
SQL> conn / as sysdba 已連接。 SQL> create user zhangsan identified by 123456;用戶已創建。給用戶修改密碼
如果給自己修改密碼可以直接使用
password 用戶名 SQL> password huang 更改 huang 的口令 舊口令: 新口令: 重新鍵入新口令: 口令已更改如果給別人修改密碼則需要具有 dba 的權限,或是擁有 alter user 的系統權限
alter user 用戶名 identified by 新密碼 SQL> alter user zhangsan identified by 12345678;用戶已更改。刪除用戶
一般以 dba 的身份去刪除某個用戶, 如果用其它用戶去刪除用戶則需要具有 drop user 的權限。
drop user 用戶名 [cascade] SQL> drop user zhangsan;用戶已刪除。如果要刪除的用戶,已經創建了表,那么就需要在刪除的時候帶一個參數 cascade ;
權限和角色
權限
創建的新用戶是沒有任何權限的, 甚至連登陸的數據庫的權限都沒有, 需要為其指定相應的權限;要使用有能力授權的用戶,如 sys 、 system 。
權限包含系統權限和對象權限
- 系統權限:用戶對數據庫的相關權限
- 對象權限:用戶對其他用戶的數據對象操作的權限
角色
角色是指由系統權限集合。通常給某個用戶授予權限時如果沒有角色存在的話,那么需要一條一條的操作,角色的存在就是使得授權變得很方便。通常一個角色由多個系統權限組成。常用的角色有三個 connect (7種權限)、 dba 、 resource (在任何表空間建表)。
connect 角色:是授予最終用戶的典型權利,最基本的
- alter session 修改會話
- create cluster 建立聚簇
- create database link 建立數據庫鏈接
- create sequence 建立序列
- create session 建立會話
- create synonym 建立同義詞
- create view 建立視圖
resource 角色: 是授予開發人員的
- create cluster 建立聚簇
- create procedure 建立過程
- create sequence 建立序列
- create table 建表
- cteate trigger 建立觸發器
- create type 建立類型
dba 角色:擁有系統所有系統級權限
使用 grant 命令給用戶分配權限:
grant 【權限名】 to 【用戶名】
- 分配角色
- 收回權限
用戶管理的綜合案例
SQL> create user zhangsan identified by 123456; /*創建用戶*/用戶已創建。SQL> conn zhangsan/123456; /*新建用戶沒有 session (登陸)權限*/ ERROR: ORA-01045: 用戶 ZHANGSAN 沒有 CREATE SESSION 權限; 登錄被拒絕警告: 您不再連接到 ORACLE。 SQL> show user USER 為 "" SQL> conn / as sysdba; 已連接。 SQL> grant create session to zhangsan; /*使 zhangsan 能夠被連接*/授權成功。SQL> conn zhangsan/123456; 已連接。 SQL> show user; USER 為 "ZHANGSAN" SQL> conn / as sysdba; 已連接。 SQL> grant resource to zhangsan; /*讓zhangsan 能夠在任何表空間下建表*/授權成功。SQL> create table users(name varchar(10),age number(3)); /*在 sys 角色下創建一個簡單的表 users */表已創建。SQL> insert into users values('張三',22); /*插入數據*/已創建 1 行。SQL> insert into users values('李四',24);已創建 1 行。SQL> select * from users; /*查詢*/NAME AGE -------------------- ---------- 張三 22 李四 24SQL> conn zhangsan/123456; 已連接。 SQL> select * from sys.users; /*新建的用戶沒有查詢 sys 表的權限*/ select * from sys.users* 第 1 行出現錯誤: ORA-00942: 表或視圖不存在SQL> conn / as sysdba; 已連接。 SQL> grant select on users to zhangsan; /*登錄到 sys 給 zhangsan 授權讓 zhangsan 可以查看 sys 下的 users 表*/授權成功。SQL> conn zhangsan/123456; 已連接。 SQL> select * from sys.users; /* 登錄到 zhangsan 下查看 users 表*/NAME AGE -------------------- ---------- 張三 22 王五 24SQL> update sys.users set name='張小三' where name='張三'; /*這時如果想要更新 sys.users 中的數據,會提示 "ORA-01031: 權限不足 " 。因為 sys 只給了 zhangsan 查看的權利,如果仍然想更新,要到 sys 下進行授權*/ update sys.users set name='張小三' where name='張三'* 第 1 行出現錯誤: ORA-01031: 權限不足SQL> conn / as sysdba 已連接。 SQL> grant update on users to zhangsan; /*登錄到 sys 給 zhangsan 授權讓 zhangsan 可以更新 sys 下的 users 表*/授權成功。SQL> conn zhangsan/123456; 已連接。 SQL> update sys.users set name='張小三' where name='張三';已更新 1 行。SQL> select * from sys.users;NAME AGE -------------------- ---------- 張小三 22 王五 24SQL> revoke resource from zhangsan; /*登陸到 sys 下回收 resource 權限*/撤銷成功。SQL> revoke select on users from zhangsan; /*登陸到 sys 下回收 select 權限*/撤銷成功。SQL> conn zhangsan/123456; 已連接。 SQL> select * from sys.users; /* 這時 sys 就不能再查詢 sys.users 的數據了*/ select * from sys.users* 第 1 行出現錯誤: ORA-00942: 表或視圖不存在使用 profile 管理用戶口令
profile 是口令限制,資源限制的命令集合。當建立數據庫時, Oracle 會自動建立名稱為 default 的 profile。當建立用戶沒有制定 profile 選項,那 Oracle 就會將 default 分配給用戶。
帳號鎖定
指定登錄時最多可以輸入密碼的次數,也可以指定用戶鎖定的時間,以天為單位。一般用 dba 的身份去執行命令。
指定用戶 huang 最多只能嘗試三次登錄,鎖定時間為 2 天。
SQL> conn / as sysdba; 已連接。 SQL> create profile lock_account limit failed_login_attempts 3 password_lock_time 2;配置文件已創建SQL> alter user huang profile lock_account;用戶已更改。按 CTRL + C 退出來驗證賬號鎖定
C:\Users\Administrator>sqlplusSQL*Plus: Release 11.1.0.7.0 - Production on 星期三 10月 30 11:13:48 2019Copyright (c) 1982, 2008, Oracle. All rights reserved.請輸入用戶名: huang 輸入口令: ERROR: ORA-01017: 用戶名/口令無效; 登錄被拒絕請輸入用戶名: huang 輸入口令: ERROR: ORA-01017: 用戶名/口令無效; 登錄被拒絕請輸入用戶名: huang 輸入口令: ERROR: ORA-28000: 帳戶已被鎖定SP2-0157: 在 3 次嘗試之后無法連接到 ORACLE, 退出 SQL*Plus賬戶解鎖
SQL> alter user huang account unlock;用戶已更改。SQL> conn huang; 輸入口令: 已連接。終止口令
為了讓用戶定期修改密碼,可以使用終止口令的指令完成,同樣這個命令也要 dba 身份來操作。
給 huang 創建一個 profile 文件,要求該用戶每隔 10 天要修改登錄密碼,寬限期 2 天
SQL> create profile huang limit password_life_time 10 password_grace_time 2;配置文件已創建SQL> alter user huang profile huang;用戶已更改。解鎖方式同上
口令歷史
如果希望用戶在修改密碼時,不能使用以前用過的密碼,可以使用口令歷史,這樣 Oracle 就會將口令修改的信息存放在數據字典中,這樣當用戶修改密碼時, Oracle 就會對新密碼與就得進行對比,如果一樣提示用戶重新輸入。
SQL> create profile password_history limit password_life_time 10 password_grace_time 2 password_reuse_time 10;配置文件已創建SQL> alter user huang profile password_history;用戶已更改。SQL> alter user huang identified by 12345678;用戶已更改。SQL> alter user huang identified by 12345678; alter user huang identified by 12345678 * 第 1 行出現錯誤: ORA-28007: 無法重新使用口令password_reuse_time 10 表示 10 天后口令可重復使用。
刪除 profile
SQL> drop profile password_history cascade;配置文件已刪除。cascade 表示如果已經將 profile分 配給某個用戶時,仍要刪除 profile,就要加上 cascade。
Oracle 表的管理
表名和列的命名規則
- 必須以字母開頭
- 長度不能超過 30 個字符
- 不能使用 Oracle 的保留字
- 只能使用如下字符 A-Z , a-z , 0-9 , $ , # 等
Oracle 支持的數據類型
字符型
char 定長,最長2000字符
例如: char(10) 存儲內容為“小黃”時,前4個字符放‘小黃’,后六位由空格補齊
優點是:效率高,查詢速率快。如身份證的字段可以設置成 char(18)
varchar2 變長最大 4000 字符( Oracle 推薦使用)
varchar2(10) 存儲內容為“小黃”時, Oracle 分配 4 個字符
clob(character large object) 字符型大對象,最大 4G
數字類型
number 范圍 -10 的 38 次方到 10 的 38 次方,可以是整數,也可以是小數
number(5,2) 表示一個小數有5位有效數字, 2 位是小數
例如:定義一個范圍在 -999.99-999.99 的數字可以用 number(5,2),定義一個范圍在 -99999-99999 可以用 number(5)
日期類型
date 包含年月日和時分秒
timestamp Oracle 對 date 類型的擴展,可以精確到毫秒。
圖片類型
blob 二進制數據,可以存放圖片,音頻,視頻最大 4G ,這個類型允許我們將大文件存儲進數據庫,但是一般在數據庫里,存放的應該是這些文件的路徑,如果對安全性有要求,可以將文件放入數據庫(一般來講,在真實項目中是不會把圖片和聲音真的往數據庫里存放的)。
建表語句
建表
- 學生表
- 班級表
修改表
SQL> alter table student add (c_id number(2)); /*添加字段*/表已更改。SQL> alter table student modify (name varchar2(50)); /*修改字段的長度*/表已更改。SQL> alter table student modify (name char(20)); /*修改字段的類型(表中不能有數據)*/表已更改。SQL> alter table student rename column name to s_name; /*修改字段的名字(表中不能有數據)*/表已更改。SQL> alter table student drop column sex; /*刪除一個字段(慎重使用)*/表已更改。SQL> rename student to stu; /*修改表的名字*/表已重命名。SQL> desc stu;名稱 是否為空? 類型----------------------------------------- -------- ----------------------------ID NUMBER(4)S_NAME CHAR(20 CHAR)BIRTHDAY DATESAL NUMBER(6,2)C_ID NUMBER(2)SQL> drop table stu; /*刪除表*/表已刪除。SQL> desc stu; ERROR: ORA-04043: 對象 stu 不存在操作表
使用 student 表
SQL> insert into student values(1,'張三','男','01-1月-19',8888.88); /*添加數據,所有字段必須都插入, Oracle 中默認的日期格式‘DD-MON-YY’ (日-月-年)*/已創建 1 行。SQL> select * from student;ID NAME SEX BIRTHDAY ---------- ---------------------------------------- ---- --------------SAL ----------1 張三 男 01-1月 -198888.88SQL> set linesize 300; /*設置行的寬度,這樣就好看多了*/ SQL> select * from student;ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- -------------- ----------1 張三 男 01-1月 -19 8888.88SQL> alter session set nls_date_format='YYYY-MM-DD'; /*修改日期的默認格式。注意,這種修改方法,只對當前會話有效。而不是當前的 sql*plus 窗口。即如果你這樣修改之后,又使用 connect 命令以其他用戶連接到數據庫或者是連接到其他的數據庫,則這個日期格式就失效了,又恢復到缺省的日期格式。要想永久改變日期輸入格式是需要改注冊表的,還有一個方法是使用函數。*/會話已更改。SQL> insert into student values(2,'李四','男','2019-01-02',8888.88);已創建 1 行。SQL> select * from student;ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------1 張三 男 2019-01-01 8888.882 李四 男 2019-01-02 8888.88SQL> insert into student(id,name) values(3,'王五'); /*插入部分字段,前提是未插入的字段允許為 null */已創建 1 行。SQL> select * from student;ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------1 張三 男 2019-01-01 8888.882 李四 男 2019-01-02 8888.883 王五SQL> insert into student(id,name,sex) values(4,null,null); /*插入空值*/已創建 1 行。SQL> select * from student;ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------1 張三 男 2019-01-01 8888.882 李四 男 2019-01-02 8888.883 王五4SQL> select * from student where name=null; /*查詢 name 為空的一條記錄,錯誤的做法*/未選定行SQL> select * from student where name is null; /*查詢 name 為空的一條記錄,正確的做法*/ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------4SQL> select * from student where name is not null; /*查詢 name 不為空的一條記錄*/ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------1 張三 男 2019-01-01 8888.882 李四 男 2019-01-02 8888.883 王五SQL> update student set sex='女' where id='1'; /*修改一個字段*/已更新 1 行。SQL> select * from student;ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------1 張三 女 2019-01-01 8888.882 李四 男 2019-01-02 8888.883 王五4SQL> update student set sex='女',name='李小四' where id='2'; /*修改多個字段*/已更新 1 行。SQL> select * from student;ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------1 張三 女 2019-01-01 8888.882 李小四 女 2019-01-02 8888.883 王五4SQL> update student set name='趙六' where name is null; /*修改含有 null 值的字段*/已更新 1 行。SQL> select * from student;ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------1 張三 女 2019-01-01 8888.882 李小四 女 2019-01-02 8888.883 王五4 趙六SQL> insert into student values(1,'張三','女','2019-01-01',8888.88); /*增加一條重復的記錄*/已創建 1 行。SQL> select * from student;ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------1 張三 女 2019-01-01 8888.882 李小四 女 2019-01-02 8888.883 王五4 趙六1 張三 女 2019-01-01 8888.88SQL> select distinct id,name from student; /*取消重復行,查詢時在 select 后面加上 distinct 即可將重復數據略去*/ID NAME ---------- ----------------------------------------3 王五2 李小四1 張三4 趙六SQL> delete from student where id='4'; /*刪除數據,刪除一條記錄*/已刪除 1 行。SQL> select * from student;ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------1 張三 女 2019-01-01 8888.882 李小四 女 2019-01-02 8888.883 王五1 張三 女 2019-01-01 8888.88SQL> delete from student; /*刪除所有記錄,表結構還在,會記錄日志,這種刪除是可以恢復的,速度會稍慢*/已刪除4行。SQL> select * from student;未選定行SQL> truncate table student; /*刪除所有記錄,表結構還在,不記錄日記,所有這種刪除無法找回數據,但是速度很快*/表被截斷。SQL> desc student;名稱 是否為空? 類型----------------------------------------- -------- ----------------------------ID NUMBER(4)NAME VARCHAR2(20 CHAR)SEX CHAR(2 CHAR)BIRTHDAY DATESAL NUMBER(6,2)SQL> drop table student; /*刪除表的結構和數據*/表已刪除。SQL> desc student; ERROR: ORA-04043: 對象 student 不存在SQL> create table student( /*表名*/ /*恢復數據,用 delete from student 時數據可恢,使用 student 表*/2 id number(4), /*學號*/3 name varchar2(20), /*姓名*/4 sex char(2), /*性別*/5 birthday date, /*出生日期*/6 sal number(6,2) /*獎學金*/7 );表已創建。SQL> insert into student values(1,'張小三','女','2019-01-01',8888.88); /*插入數據*/已創建 1 行。SQL> insert into student values(2,'李小四','女','2019-01-01',8888.88);已創建 1 行。SQL> select * from student;ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------1 張小三 女 2019-01-01 8888.882 李小四 女 2019-01-01 8888.88SQL> savepoint sp; /*首先要設置一個保存點*/保存點已創建。SQL> delete from student; /*刪除數據*/已刪除2行。SQL> select * from student; /*查詢驗證數據是否被刪掉*/未選定行SQL> rollback to sp; /*回滾數據*/回退已完成。SQL> select * from student; /*查詢驗證數據回滾是否成功,可以設置多個保存點,但是如果不做處理,新的保存點會默認覆蓋前一個保存點*/ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- ---------- ----------1 張小三 女 2019-01-01 8888.882 李小四 女 2019-01-01 8888.88Oracle 的基本查詢
PL/SQL 軟件中兩個命令
SQL> clear /*清屏命令*/ SQL> set timing on; /*打開顯示操作時間*/ SQL> select * from student;ID NAME SEX BIRTHDAY SAL ---------- ---------------------------------------- ---- -------------- ----------1 張小三 女 01-1月 -19 8888.882 李小四 女 01-1月 -19 8888.88已用時間: 00: 00: 00.00 /*這里顯示操作時間*/ SQL> set timing off; /*關閉操作時間*/ SQL> select count(*) from student; /*查詢所有記錄數*/COUNT(*) ----------2注意
Oracle 的字段不區分大小寫,實體區分大小寫。
表基本查詢
scott 用戶存在的幾張表 ( emp , dept ),本次實例采用 emp 和 dept 表。
使用算術表達式
顯示每個雇員的月收入
SQL> select ename "姓名",sal 月工資 from emp;姓名 月工資 -------------------- ---------- SMITH 800 ALLEN 1600 WARD 1250 JONES 2975 MARTIN 1250 BLAKE 2850 CLARK 2450 SCOTT 3000 KING 5000 TURNER 1500 ADAMS 1100姓名 月工資 -------------------- ---------- JAMES 950 FORD 3000 MILLER 1300已選擇14行。顯示每個雇員的年收入
SQL> select ename "姓名",sal * 12 as "年收入" from emp;姓名 年收入 -------------------- ---------- SMITH 9600 ALLEN 19200 WARD 15000 JONES 35700 MARTIN 15000 BLAKE 34200 CLARK 29400 SCOTT 36000 KING 60000 TURNER 18000 ADAMS 13200姓名 年收入 -------------------- ---------- JAMES 11400 FORD 36000 MILLER 15600這里的中文最好用引號引上,盡量不要用中文。
如果計算表達式中有一個 null 值,那么計算結果就為 null ,如何處理 null 值?
SQL> select sal * 13 + nvl(comm,0) * 13 "年薪",ename,comm from emp;年薪 ENAME COMM ---------- -------------------- ----------10400 SMITH24700 ALLEN 30022750 WARD 50038675 JONES34450 MARTIN 140037050 BLAKE31850 CLARK39000 SCOTT65000 KING19500 TURNER 014300 ADAMS年薪 ENAME COMM ---------- -------------------- ----------12350 JAMES39000 FORD16900 MILLER已選擇14行。nvl(comm,0) 的意思是:如果 comm 為 null ,那么按 0 計算,不是 0 按本身計算。
用 “||” 來連接字符串
SQL> select ename || ' is a ' || job from emp; /*這句話表示:姓名為 XX 是做 XX 工作的*/ENAME||'ISA'||JOB ------------------------------------------------------------------------------------------------------ SMITH is a CLERK ALLEN is a SALESMAN WARD is a SALESMAN JONES is a MANAGER MARTIN is a SALESMAN BLAKE is a MANAGER CLARK is a MANAGER SCOTT is a ANALYST KING is a PRESIDENT TURNER is a SALESMAN ADAMS is a CLERKENAME||'ISA'||JOB ------------------------------------------------------------------------------------------------------ JAMES is a CLERK FORD is a ANALYST MILLER is a CLERK已選擇14行。使用 where 字句
顯示工資高于 3000 的員工
SQL> select ename,sal from emp where sal > 3000;ENAME SAL -------------------- ---------- KING 5000查找 1982-1-1 后入職的員工
SQL> select ename from emp where hiredate > '1982-1-1';ENAME -------------------- SCOTT ADAMS MILLER查找工資在 2000-2500 之間的員工,并且顯示員工的工資
SQL> select ename,sal from emp where sal >=2000 and sal <=2500;ENAME SAL -------------------- ---------- CLARK 2450使用 like 操作符
%:表示 0 到多個字符
_:表示任意單個字符
顯示首字母為 S 的員工
SQL> select ename from emp where ename like 'S%';ENAME -------------------- SMITH SCOTT顯示第三個字母為大寫 O 的所有員工的姓名和工資
SQL> select ename,sal from emp where ename like '__O%'; /*注意: 兩個 _ 符號*/ENAME SAL -------------------- ---------- SCOTT 3000在 where 條件中使用 in
顯示 empno 為 7844 , 7839 , 123 , 456 的雇員情況
SQL> select * from emp where empno in(7844,7839,123,456);EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ----------7839 KING PRESIDENT 1981-11-17 5000 107844 TURNER SALESMAN 7698 1981-09-08 1500 0 30這種查詢效率很高
使用 is null 操作符
顯示沒有上級的雇員情況
SQL> select * from emp where mgr is null;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ----------7839 KING PRESIDENT 1981-11-17 5000 10使用邏輯操作符號
查詢工資高于 500 或者是崗位為 MANAGER 的雇員,同時還要滿足他們的姓名首字母為大寫的 J
SQL> select * from emp where (sal >500 or job='MANAGER') and ename like 'J%';EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ----------7566 JONES MANAGER 7839 1981-04-02 2975 207900 JAMES CLERK 7698 1981-12-03 950 30這里的括號不可以忘記,否則條件就變了,因為 and 的優先級高于 or 。
使用 order by 子句
按照工資從高到低的順序顯示雇員和工資
SQL> select ename,sal from emp order by sal desc;ENAME SAL -------------------- ---------- KING 5000 FORD 3000 SCOTT 3000 JONES 2975 BLAKE 2850 CLARK 2450 ALLEN 1600 TURNER 1500 MILLER 1300 WARD 1250 MARTIN 1250ENAME SAL -------------------- ---------- ADAMS 1100 JAMES 950 SMITH 800已選擇14行。desc 為降序, asc 為升序(默認)
照部門號升序而雇員工資降序排列(知道某和部門最高工資的員工和最低工資的員工是誰)
SQL> select * from emp order by deptno asc,sal desc;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ----------7839 KING PRESIDENT 1981-11-17 5000 107782 CLARK MANAGER 7839 1981-06-09 2450 107934 MILLER CLERK 7782 1982-01-23 1300 107788 SCOTT ANALYST 7566 1987-04-19 3000 207902 FORD ANALYST 7566 1981-12-03 3000 207566 JONES MANAGER 7839 1981-04-02 2975 207876 ADAMS CLERK 7788 1987-05-23 1100 207369 SMITH CLERK 7902 1980-12-17 800 207698 BLAKE MANAGER 7839 1981-05-01 2850 307499 ALLEN SALESMAN 7698 1981-02-20 1600 300 307844 TURNER SALESMAN 7698 1981-09-08 1500 0 30EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ----------7654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 307521 WARD SALESMAN 7698 1981-02-22 1250 500 307900 JAMES CLERK 7698 1981-12-03 950 30已選擇14行。使用列的別名排序
SQL> select ename,sal * 12 "年薪" from emp order by "年薪" asc;ENAME 年薪 -------------------- ---------- SMITH 9600 JAMES 11400 ADAMS 13200 WARD 15000 MARTIN 15000 MILLER 15600 TURNER 18000 ALLEN 19200 CLARK 29400 BLAKE 34200 JONES 35700ENAME 年薪 -------------------- ---------- SCOTT 36000 FORD 36000 KING 60000已選擇14行。Oracle 的復雜查詢
在實際應用中經常需要執行復雜的數據統計,經常需要現實多張表的數據,所以經常要用到數據分組函數如 max() , min() , avg() , sum() , count() 等。
分組函數
顯示所有員工中最高工資和最低工資
SQL> select max(sal),min(sal) from emp;MAX(SAL) MIN(SAL) ---------- ----------5000 800注意
如果列里面有一個分組函數,其它的都必須是分組函數, 否則就出錯;如本例中不能寫成:
因為: max 是分組函數,而 ename 不是分組函數。
查詢最高,最低工資的員工(利用子查詢)
SQL> select ename,sal from emp where sal = (select max(sal) from emp);ENAME SAL -------------------- ---------- KING 5000SQL> select ename,sal from emp where sal = (select min(sal) from emp);ENAME SAL -------------------- ---------- SMITH 800顯示工資最高的員工的名字,工作崗位
SQL> select ename,job from emp where sal = (select max(sal) from emp);ENAME JOB -------------------- ------------------ KING PRESIDENT顯示工資高于平均工資的員工信息
首先我們可以查詢所有員工的平均工資
SQL> select avg(sal) from emp;AVG(SAL) ---------- 2073.21429然后再查詢高于平均工資的員工信息
SQL> select * from emp where sal > 2073;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ----------7566 JONES MANAGER 7839 1981-04-02 2975 207698 BLAKE MANAGER 7839 1981-05-01 2850 307782 CLARK MANAGER 7839 1981-06-09 2450 107788 SCOTT ANALYST 7566 1987-04-19 3000 207839 KING PRESIDENT 1981-11-17 5000 107902 FORD ANALYST 7566 1981-12-03 3000 20已選擇6行。當然也可以利用子查詢
SQL> select * from emp where sal > (select avg(sal) from emp);EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ----------7566 JONES MANAGER 7839 1981-04-02 2975 207698 BLAKE MANAGER 7839 1981-05-01 2850 307782 CLARK MANAGER 7839 1981-06-09 2450 107788 SCOTT ANALYST 7566 1987-04-19 3000 207839 KING PRESIDENT 1981-11-17 5000 107902 FORD ANALYST 7566 1981-12-03 3000 20已選擇6行。如果這里不是 * 號而是 ename,sal 等字段與分組函數那么在語句的最后要加上 group by ename,sal…(與 select 后的字段一致)
SQL> select ename,sal from emp where sal > (select avg(sal) from emp) group by ename,sal;ENAME SAL -------------------- ---------- JONES 2975 SCOTT 3000 KING 5000 BLAKE 2850 CLARK 2450 FORD 3000已選擇6行。group by 和 having 子句
group by 用于對查詢結果分組統計
having 子句用于限制分組顯示結果
顯示每個部門的平均工資和最高工資
SQL> select avg(sal),max(sal),deptno from emp group by deptno;AVG(SAL) MAX(SAL) DEPTNO ---------- ---------- ---------- 1566.66667 2850 302175 3000 20 2916.66667 5000 10分組字段依據必須出現在查詢結果中,否則結果可讀性太差。
顯示每個部門的每種崗位的平均工資和最低工資
SQL> select avg(sal),min(sal),deptno,job from emp group by job,deptno;AVG(SAL) MIN(SAL) DEPTNO JOB ---------- ---------- ---------- ------------------2975 2975 20 MANAGER5000 5000 10 PRESIDENT1300 1300 10 CLERK1400 1250 30 SALESMAN3000 3000 20 ANALYST2850 2850 30 MANAGER2450 2450 10 MANAGER950 950 30 CLERK950 800 20 CLERK已選擇9行。顯示平均工資低于 2000 的部門號和它的平均工資與最高工資
SQL> select avg(sal),max(sal),deptno from emp group by deptno having avg(sal) < 2000;AVG(SAL) MAX(SAL) DEPTNO ---------- ---------- ---------- 1566.66667 2850 30對分組函數的總結
- 分組函數只能出現在選擇列表, having , group by , order by 子句中
- 如果在select語句中同時包含有 group by , having , order by ,那么順序為 group by , having , order by
- 在選擇列中如果有列,表達式,和分組函數,那么這些列表達式必須有一個出現在 group by 子句中,否則出錯 如:
多表查詢
基于兩個或兩個以上的表或是視圖的查詢,查單表滿足不了要求,如部門和員工的關系。
SQL> select a.ename,a.sal,b.dname from emp a,dept b where a.deptno = b.deptno;ENAME SAL DNAME -------------------- ---------- ---------------------------- CLARK 2450 ACCOUNTING KING 5000 ACCOUNTING MILLER 1300 ACCOUNTING JONES 2975 RESEARCH FORD 3000 RESEARCH ADAMS 1100 RESEARCH SMITH 800 RESEARCH SCOTT 3000 RESEARCH WARD 1250 SALES TURNER 1500 SALES ALLEN 1600 SALESENAME SAL DNAME -------------------- ---------- ---------------------------- JAMES 950 SALES BLAKE 2850 SALES MARTIN 1250 SALES已選擇14行。如果不加 where 子句,就會產生笛卡爾集,所謂笛卡爾集,就是不加篩選,將所有的都查詢出來。
結論:
兩張表關聯,至少需要一個條件排除笛卡爾集
三張表關聯,至少需要二個條件排除笛卡爾集
以此類推:多表查詢中,判斷條件至少是表的個數 -1。
顯示部門號為10的部門名,員工名和工資
SQL> select d.dname,e.ename,e.sal from emp e,dept d where e.deptno = d.deptno and d.deptno = 10;DNAME ENAME SAL ---------------------------- -------------------- ---------- ACCOUNTING CLARK 2450 ACCOUNTING KING 5000 ACCOUNTING MILLER 1300顯示各個員工的姓名,工資及工資的級別
SQL> select * from salgrade; /*先查看 salgrade 的表結構和記錄*/GRADE LOSAL HISAL ---------- ---------- ----------1 700 12002 1201 14003 1401 20004 2001 30005 3001 9999SQL> select e.ename,e.sal,s.grade from emp e,salgrade s where e.sal between s.losal and s.hisal;ENAME SAL GRADE -------------------- ---------- ---------- SMITH 800 1 JAMES 950 1 ADAMS 1100 1 WARD 1250 2 MARTIN 1250 2 MILLER 1300 2 TURNER 1500 3 ALLEN 1600 3 CLARK 2450 4 BLAKE 2850 4 JONES 2975 4ENAME SAL GRADE -------------------- ---------- ---------- SCOTT 3000 4 FORD 3000 4 KING 5000 5已選擇14行。這里用到了 between … and 子句,表示在 losal 和 hisal 之間。
顯示雇員名,雇員工資及所在部門的名字,并部門排序
SQL> select e.ename,e.sal,d.dname from emp e,dept d where e.deptno = d.deptno order by e.deptno;ENAME SAL DNAME -------------------- ---------- ---------------------------- CLARK 2450 ACCOUNTING KING 5000 ACCOUNTING MILLER 1300 ACCOUNTING JONES 2975 RESEARCH FORD 3000 RESEARCH ADAMS 1100 RESEARCH SMITH 800 RESEARCH SCOTT 3000 RESEARCH WARD 1250 SALES TURNER 1500 SALES ALLEN 1600 SALESENAME SAL DNAME -------------------- ---------- ---------------------------- JAMES 950 SALES BLAKE 2850 SALES MARTIN 1250 SALES已選擇14行。如果用 group by ,一定要把 e.deptno 放到查詢列里面。
自連接
自連接是指在同一張表的連接查詢。
顯示某個員工的上級領導的姓名
SQL> select worker.ename,boss.ename from emp worker,emp boss where worker.mgr = boss.empno and worker.ename = 'FORD';ENAME ENAME -------------------- -------------------- FORD JONES根據 FORD 的名字找到 FORD 的 mgr 編號再根據這個編號找到 boss 的 empno,最后顯示出來。
子查詢
子查詢:指嵌入在其他 SQL 語句中的 select 語句,也叫做嵌套查詢。
單行子查詢
指只返回一行數據的子查詢語句。
顯示與 SMITH 同一部門的所有員工
分兩步:
數據庫在執行 SQL 是從左到右掃描的, 如果有括號的話,括號里面的先被優先執行。
多行子查詢
返回多行數據的子查詢
查詢和部門 10 的工作相同的雇員的名字,崗位,工資,部門號
1.首先查出部門 10 的工作種類
SQL> select job from emp where deptno = 10;JOB ------------------ MANAGER PRESIDENT CLERK發現有重復結果,所以在 job 前加上 distinct
SQL> select distinct job from emp where deptno = 10;JOB ------------------ CLERK PRESIDENT MANAGER2.根據工作的種類查詢
SQL> select ename,job,sal,deptno from emp where job in (select distinct job from emp where deptno = 10);ENAME JOB SAL DEPTNO -------------------- ------------------ ---------- ---------- CLARK MANAGER 2450 10 BLAKE MANAGER 2850 30 JONES MANAGER 2975 20 KING PRESIDENT 5000 10 MILLER CLERK 1300 10 JAMES CLERK 950 30 ADAMS CLERK 1100 20 SMITH CLERK 800 20已選擇8行。注意這里 job 之后用的是" in “而非” = ",因為等號 = 是一對一的。
all 操作符
顯示工資比部門 30 的所有員工的工資高的員工的姓名,工資和部門號
SQL> select ename,sal,deptno from emp where sal > all (select sal from emp where deptno = 30);ENAME SAL DEPTNO -------------------- ---------- ---------- JONES 2975 20 SCOTT 3000 20 FORD 3000 20 KING 5000 10也可以使用 max 方法
SQL> select ename,sal,deptno from emp where sal > (select max(sal) from emp where deptno = 30);ENAME SAL DEPTNO -------------------- ---------- ---------- JONES 2975 20 SCOTT 3000 20 KING 5000 10 FORD 3000 20max 方法的效率較高,原因是使用 all 操作符時,要和子查詢所得結果逐一比較而使用 max 只需和 sal 中的最大值比較,減少了比較的次數,縮短了時間。數據量較大是會比較明顯,數據量較小基本看不出來。
any 操作符
顯示工資比部門 30 的任意一個員工的工資高的員工的姓名,工資和部門號
SQL> select ename,sal,deptno from emp where sal > any (select sal from emp where deptno = 30);ENAME SAL DEPTNO -------------------- ---------- ---------- KING 5000 10 FORD 3000 20 SCOTT 3000 20 JONES 2975 20 BLAKE 2850 30 CLARK 2450 10 ALLEN 1600 30 TURNER 1500 30 MILLER 1300 10 WARD 1250 30 MARTIN 1250 30ENAME SAL DEPTNO -------------------- ---------- ---------- ADAMS 1100 20已選擇12行。也可以使用 min 方法
SQL> select ename,sal,deptno from emp where sal > (select min(sal) from emp where deptno = 30);ENAME SAL DEPTNO -------------------- ---------- ---------- ALLEN 1600 30 WARD 1250 30 JONES 2975 20 MARTIN 1250 30 BLAKE 2850 30 CLARK 2450 10 SCOTT 3000 20 KING 5000 10 TURNER 1500 30 ADAMS 1100 20 FORD 3000 20ENAME SAL DEPTNO -------------------- ---------- ---------- MILLER 1300 10已選擇12行。原理同上
多列子查詢
單行子查詢是指子查詢只返回單列、單行數據,多行子查詢是指返回單列多行數據, 都是針對單列而言的,而多列子查詢是指查詢返回多個列數據的子查詢語句。
查詢與 SMITH 的部門和崗位完全相同的所有雇員
1.查詢出 SMITH 的部門號,崗位
SQL> select deptno,job from emp where ename = 'SMITH';DEPTNO JOB ---------- ------------------20 CLERK2.顯示結果
SQL> select * from emp where (deptno,job) = (select deptno,job from emp where ename = 'SMITH');EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ----------7369 SMITH CLERK 7902 1980-12-17 800 207876 ADAMS CLERK 7788 1987-05-23 1100 20在 from 子句中使用子查詢
顯示高于自己部門的平均工資員工信息
1.查詢各個部門的平均工資和部門號
SQL> select avg(sal),deptno from emp group by deptno;AVG(SAL) DEPTNO ---------- ---------- 1566.66667 302175 20 2916.66667 102.把上面的查詢看作是一張子表
SQL> select e.ename,e.deptno,e.sal,ds.mysal from emp e,(select deptno, avg(sal) mysal from emp group by deptno) ds where e.deptno = ds.deptno and e.sal > ds.mysal;ENAME DEPTNO SAL MYSAL -------------------- ---------- ---------- ---------- ALLEN 30 1600 1566.66667 JONES 20 2975 2175 BLAKE 30 2850 1566.66667 SCOTT 20 3000 2175 KING 10 5000 2916.66667 FORD 20 3000 2175已選擇6行。將這兩個表做關聯查詢,當在 from 子句中使用子查詢時,該子查詢會被作為一個視圖來對待,因此叫做內嵌視圖,當在 from 子句中使用子查詢時,必須為子查詢指定別名。
注意:別名不能用 as ,如:
SQL> select e.ename,e.deptno,e.sal,ds.mysal from emp e,(select deptno, avg(sal) mysal from emp group by deptno) as ds where e.deptno = ds.deptno and e.sal > ds.mysal; select e.ename,e.deptno,e.sal,ds.mysal from emp e,(select deptno, avg(sal) mysal from emp group by deptno) as ds where e.deptno = ds.deptno and e.sal > ds.mysal* 第 1 行出現錯誤: ORA-00933: SQL 命令未正確結束在 ds 前不能加 as ,否則會報錯 (給表取別名的時候,不能加 as ;但是給列取別名,是可以加 as 的)。
Oracle 的分頁
Oracle 的分頁一共有三種方式:
根據 rowid 來分(效率最好)
按分析函數來分(效率次之)
按 rownum 來分(效率最差)
下面最主要介紹第三種:按 rownum 來分
SQL> select * from (select a.*,rownum rn from (select * from emp) a where rownum <= 15) where rn > 10;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO RN ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ---------- ----------7876 ADAMS CLERK 7788 1987-05-23 1100 20 117900 JAMES CLERK 7698 1981-12-03 950 30 127902 FORD ANALYST 7566 1981-12-03 3000 20 137934 MILLER CLERK 7782 1982-01-23 1300 10 14已用時間: 00: 00: 00.02這條語句是用來將 11-15 條記錄提取出來,拆分這條語句:
1.將所有想要的結果查詢出來
SQL> select * from emp;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ----------7369 SMITH CLERK 7902 1980-12-17 800 207499 ALLEN SALESMAN 7698 1981-02-20 1600 300 307521 WARD SALESMAN 7698 1981-02-22 1250 500 307566 JONES MANAGER 7839 1981-04-02 2975 207654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 307698 BLAKE MANAGER 7839 1981-05-01 2850 307782 CLARK MANAGER 7839 1981-06-09 2450 107788 SCOTT ANALYST 7566 1987-04-19 3000 207839 KING PRESIDENT 1981-11-17 5000 107844 TURNER SALESMAN 7698 1981-09-08 1500 0 307876 ADAMS CLERK 7788 1987-05-23 1100 20EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ----------7900 JAMES CLERK 7698 1981-12-03 950 307902 FORD ANALYST 7566 1981-12-03 3000 207934 MILLER CLERK 7782 1982-01-23 1300 10已選擇14行。已用時間: 00: 00: 00.082.將上一步的結果作為一個視圖,給每一條記錄加上一個 rn 編號并將前 15 條記錄查詢出來;其中 rownum 為 Oracle 的關鍵字,且在第一次在查詢字段中使用 rownum 時,如果有條件限制在 where 子句中也要用 rownum,不可以用 rn。
SQL> select a.*,rownum rn from (select * from emp) a where rownum <= 15;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO RN ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ---------- ----------7369 SMITH CLERK 7902 1980-12-17 800 20 17499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30 27521 WARD SALESMAN 7698 1981-02-22 1250 500 30 37566 JONES MANAGER 7839 1981-04-02 2975 20 47654 MARTIN SALESMAN 7698 1981-09-28 1250 1400 30 57698 BLAKE MANAGER 7839 1981-05-01 2850 30 67782 CLARK MANAGER 7839 1981-06-09 2450 10 77788 SCOTT ANALYST 7566 1987-04-19 3000 20 87839 KING PRESIDENT 1981-11-17 5000 10 97844 TURNER SALESMAN 7698 1981-09-08 1500 0 30 107876 ADAMS CLERK 7788 1987-05-23 1100 20 11EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO RN ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ---------- ----------7900 JAMES CLERK 7698 1981-12-03 950 30 127902 FORD ANALYST 7566 1981-12-03 3000 20 137934 MILLER CLERK 7782 1982-01-23 1300 10 14已選擇14行。已用時間: 00: 00: 00.033.將前 15 條數據作為一個視圖,提取出 11-15 條。
SQL> select * from (select a.*,rownum rn from (select * from emp) a where rownum <=15) where rn > 10;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO RN ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ---------- ----------7876 ADAMS CLERK 7788 1987-05-23 1100 20 117900 JAMES CLERK 7698 1981-12-03 950 30 127902 FORD ANALYST 7566 1981-12-03 3000 20 137934 MILLER CLERK 7782 1982-01-23 1300 10 14已用時間: 00: 00: 00.01在 Java 程序中只需要替換 15 和 10 這兩個數字就可以實現分頁了。
用查詢結果創建新表
這個命令是一種快捷的建表方法
SQL> select * from (select a.*,rownum rn from (select * from emp) a where rownum <=15) where rn > 10;EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO RN ---------- -------------------- ------------------ ---------- ---------- ---------- ---------- ---------- ----------7876 ADAMS CLERK 7788 1987-05-23 1100 20 117900 JAMES CLERK 7698 1981-12-03 950 30 127902 FORD ANALYST 7566 1981-12-03 3000 20 137934 MILLER CLERK 7782 1982-01-23 1300 10 14已用時間: 00: 00: 00.01 SQL> create table mytable(id,name,sal,job,deptno) as select empno,ename,sal,job,deptno from emp;表已創建。已用時間: 00: 00: 00.64創建好之后,我們可以查看一下表結構
SQL> desc mytable;名稱 是否為空? 類型----------------------------------------------------- -------- ------------------------------------ID NUMBER(4)NAME VARCHAR2(10)SAL NUMBER(7,2)JOB VARCHAR2(9)DEPTNO NUMBER(2)SQL> desc emp;名稱 是否為空? 類型----------------------------------------------------- -------- ------------------------------------EMPNO NOT NULL NUMBER(4)ENAME VARCHAR2(10)JOB VARCHAR2(9)MGR NUMBER(4)HIREDATE DATESAL NUMBER(7,2)COMM NUMBER(7,2)DEPTNO NUMBER(2)可以看出,新建表的字段類型和查詢表的一樣。
合并查詢
有時在實際應用中,為了合并多個 select 語句的結果,可以使用集合操作符號 union, union all, intersect (交集), minus (差集)
多用于數據量比較大的數據局庫,運行速度快。
union
該操作符用于取得兩個結果集的并集。當使用該操作符時,會自動去掉結果集中重復行。
SQL> select ename,sal,job from emp where sal > 2500 union select ename,sal,job from emp where job = 'MANAGER';ENAME SAL JOB -------------------- ---------- ------------------ BLAKE 2850 MANAGER CLARK 2450 MANAGER FORD 3000 ANALYST JONES 2975 MANAGER KING 5000 PRESIDENT SCOTT 3000 ANALYST已選擇6行。已用時間: 00: 00: 00.00union all
該操作符與 union 相似,但是它不會取消重復行,而且不會排序。
SQL> select ename,sal,job from emp where sal > 2500 union all select ename,sal,job from emp where job = 'MANAGER';ENAME SAL JOB -------------------- ---------- ------------------ JONES 2975 MANAGER BLAKE 2850 MANAGER SCOTT 3000 ANALYST KING 5000 PRESIDENT FORD 3000 ANALYST JONES 2975 MANAGER BLAKE 2850 MANAGER CLARK 2450 MANAGER已選擇8行。已用時間: 00: 00: 00.01intersect
使用該操作符用于取得兩個結果集的交集。
SQL> select ename,sal,job from emp where sal > 2500 intersect select ename,sal,job from emp where job = 'MANAGER';ENAME SAL JOB -------------------- ---------- ------------------ BLAKE 2850 MANAGER JONES 2975 MANAGER已用時間: 00: 00: 00.00minus
使用改操作符用于取得兩個結果集的差集, 他只會顯示存在第一個集合中, 而不存在第二個集合中的數據。
SQL> select ename,sal,job from emp where sal > 2500 minus select ename,sal,job from emp where job = 'MANAGER';ENAME SAL JOB -------------------- ---------- ------------------ FORD 3000 ANALYST KING 5000 PRESIDENT SCOTT 3000 ANALYST已用時間: 00: 00: 00.00集合操作要比 and, or 效率高很多。
操作數據
使用特定的格式插入日期值。
使用to_date函數
插入帶有日期的表,并按照年月日格式插入
SQL> insert into emp values(9999,'huang','PERSIDENT',null,to_date('1997-01-01','YYYY-MM-DD'),800,1000,10);已創建 1 行。已用時間: 00: 00: 00.06使用 to_date 函數可以插入任意形式的日期
使用子查詢插入數據
一條 insert 語句可以插入大量的數據,當處理行遷移或者裝載外部表的數據到數據庫時, 可以使用子查詢插入數據。
SQL> insert into mytable(id,name,deptno) select empno,ename,deptno from emp where deptno = 10;已創建4行。已用時間: 00: 00: 00.02 SQL> select * from mytable;ID NAME SAL JOB DEPTNO ---------- -------------------- ---------- ------------------ ----------7369 SMITH 800 CLERK 207499 ALLEN 1600 SALESMAN 307521 WARD 1250 SALESMAN 307566 JONES 2975 MANAGER 207654 MARTIN 1250 SALESMAN 307698 BLAKE 2850 MANAGER 307782 CLARK 2450 MANAGER 107788 SCOTT 3000 ANALYST 207839 KING 5000 PRESIDENT 107844 TURNER 1500 SALESMAN 307876 ADAMS 1100 CLERK 20ID NAME SAL JOB DEPTNO ---------- -------------------- ---------- ------------------ ----------7900 JAMES 950 CLERK 307902 FORD 3000 ANALYST 207934 MILLER 1300 CLERK 107782 CLARK 107839 KING 107934 MILLER 109999 huang 10已選擇18行。已用時間: 00: 00: 00.02后面 4 行為新插入的數據。
使用子查詢更新數據
希望員工 huang 的崗位、工資與 SCOOT 一樣
SQL> update mytable set(job,sal) = (select job,sal from mytable where name='SCOTT') where name = 'huang';已更新 1 行。已用時間: 00: 00: 00.00 SQL> select * from mytable;ID NAME SAL JOB DEPTNO ---------- -------------------- ---------- ------------------ ----------7369 SMITH 800 CLERK 207499 ALLEN 1600 SALESMAN 307521 WARD 1250 SALESMAN 307566 JONES 2975 MANAGER 207654 MARTIN 1250 SALESMAN 307698 BLAKE 2850 MANAGER 307782 CLARK 2450 MANAGER 107788 SCOTT 3000 ANALYST 207839 KING 5000 PRESIDENT 107844 TURNER 1500 SALESMAN 307876 ADAMS 1100 CLERK 20ID NAME SAL JOB DEPTNO ---------- -------------------- ---------- ------------------ ----------7900 JAMES 950 CLERK 307902 FORD 3000 ANALYST 207934 MILLER 1300 CLERK 107782 CLARK 107839 KING 107934 MILLER 109999 huang 3000 ANALYST 10已選擇18行。已用時間: 00: 00: 00.02name 的值要用大寫, Oracle 對值的大小寫是敏感的。
總結
以上是生活随笔為你收集整理的Oracle入门教程与实战的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mac中解决CSV乱码问题
- 下一篇: 如何根据负载选择开关电源规格?