1. 程式人生 > >ORACLE學習(下)

ORACLE學習(下)

ORACLE學習(下)
Select語句 Select語句功能
查詢語句語法
Select子句
From子句
Where子句

字串操作函式 CHAR和VARCHAR2型別
LONG和CLOB型別
LENGTH
CONCAT和“||”
UPPER、LOWER和INITCAP
TRIM、LTRIM、RTRIM
LPAD、RPAD
SUBSTR
INSTR

數值操作 NUMBER§表示整數
NUMBER(P,S)表示浮點數
ROUND
TRUNC
MOD
CEIL和FLOOR

日期常用操作 DATE
TIMESTAMP
SYSDATE
SYSTIMESTAMP
TO_DATE
日期格式
TO_CHAR
ADD_MONTHS
MONTHS_BETWEEN
LAST_DAY
NEXT_DAY
LEAST和GREATEST
EXTRACT
日期相減

一、Select語句
1.Select語句功能
SQL查詢語句是使用最頻繁的語句,Select語句的作用是通過from子句從某個或某些表中,通過select子句投影出某些列的資料,並通過where子句過濾選擇出某些記錄。
在這裡插入圖片描述
.
2.Select語句基本語法
查詢語句語法select [distinct] {*,列名 [列別名],…} from 表名

select子句用於指定要查詢的列,如果要查詢所有的列,可以在select後面使用*號,如果只查特定的列,
可以在select後面指定列名,列名之間用逗號隔開

–查詢employee_xxx表下的所有記錄
select * from employee_xxx;

如果只查詢表的部分列,需要在SELECT後指定列名,例如:
–查詢employee_xxx下的所有員工號和員工名字
select empno,ename from employee_xxx;

使用別名
在SQL語句中可以通過使用列的別名改變標題的顯示樣式,或者表示計算結果的含義,使用語法是列的別名跟在列名後,中間可以加或不加一個“as”關鍵字。
注意:Oracle不區分大小寫,如果要讓別名區分大小寫要使用"別名"的方式
例如:
SELECT empno AS ID , ename empname,deptno “Dept” FROM employee_xxx;

3.From子句
from用於指定從哪張表中查詢

如:
select * from dual;
dual 是用來幫助測試函式的,SYS 使用者的一個表,共享給當前資料庫中所有使用者,
其中 SYS 是資料庫中管理員使用者

4.Where子句
在SELECT語句中,可以在WHERE子句中使用比較操作符限制查詢結果,是可選的。

當查詢條件中和數字比較,可以使用單引號引起,也可以不用,當和字元及日期型別的資料比較,則必須用單引號引起。

例如查詢部門20下的員工資訊:
SELECT * FROM employee_xxx WHERE deptno = 10;

查詢職員表中職位是’MANAGER’的員工:
SELECT * FROM employee_xxx WHERE job = ‘MANAGER’;–如果資料是’Manager’查不出結果
注:oracle中sql語句大小寫不敏感,資料大小寫敏感

三、字串操作
1.CHAR和VARCHAR2型別

CHAR和VARCHAR2型別都是用來表示字串資料型別,用來在表中存放字串資訊
CHAR
char資料型別儲存固定長度的字元。一個CHAR資料型別可以包括1到2000個字元。如果對CHAR沒有明確地說明長度,它的預設長度則設定為1。如果對某個CHAR型別變數賦值,其長度小於規定的長度,那麼Oracle自動用空格填充。
VARCHAR2
VARCHAR2 儲存可變長度的字串。雖然也必須指定一個VARCHAR2資料的長度,但是這個長度是指賦值的最大長度而非實際賦值長度。不需用空格填充。VARCHAR2必須指定長度,最多可設定為4000個字元。因為VARCHAR2資料型別只儲存為該列所賦的字元(不加空格),所以VARCHAR2需要的儲存空間比CHAR資料型別要小。

在Oracle中,所有字串型別都以同樣的格式儲存。在資料庫儲存單元上,最前面都有一個1~3位元組的長度欄位,其後才是資料

如果一個包含"hello world"的varchar2(80), 儲存結構如圖所示:
在這裡插入圖片描述
如果在char(80)中儲存同樣的資訊,儲存結構如圖所示:
在這裡插入圖片描述
CHAR和VARCHAR2的儲存編碼
字串在資料庫中儲存的預設單位是位元組,也可顯式指定為字元。如:
CHAR(80),等價於 CHAR(80 BYTE)
如果指定單位為字元:CHAR(80 CHAR),160個位元組
VARCHAR2(80), 等價於VARCHAR2(80 BYTE)
指定單位為字元:VARCHAR2(80 CHAR),160個位元組

每個英文字元佔用一個位元組,每個中文字元按編碼不同,佔用2-4個位元組:
GBK: 2個位元組
UTF-8: 2-4個位元組

2.varchar
varchar是標準sql提供的資料型別
varchar2是oracle獨有的字串型別,建議使用varchar2

3.LONG和CLOB型別

LONG和CLOB型別可以儲存更大容量的字元資料
LONG
long資料型別可以存放2GB的字元資料,它是從早期版本中繼承下來的。但是LONG型別有諸多限制,所以不建議使用:
每個表只能有一個LONG型別列;
不能作為主鍵;
不能建立索引;
不能出現在查詢條件中等
現在如果儲存大容量的資料,Oracle推薦使用CLOB。

例如:
CREATE TABLE manager(
id NUMBER(4),
name VARCHAR2(20),
workExperience CLOB
);

LONG
CLOB用來儲存定長或變長字串,最多達4GB的字串資料

字串操作函式

4.SQL 函式

在這裡插入圖片描述

在這裡插入圖片描述
5.單行函式:
操作資料物件
接受引數返回一個結果
只對一行進行變換
每行返回一個結果
可以轉換資料型別
可以巢狀
引數可以是一列或一個值

在這裡插入圖片描述

在這裡插入圖片描述
在這裡插入圖片描述
6.LENGTH
LENGTH(char)用於返回引數字串的長度。如果字元型別是VARCHAR2,返回字元的實際長度(字元個數),如果字元型別是CHAR,長度還包括後補的空格。

例如:
select ename,length(ename) from employee_xxx;

列出ename和ename的字串長度

在這裡插入圖片描述

7.CONCAT和“||”
CONCAT是字串連線函式,語法是:
CONCAT(char1, char2)

用於返回兩個字串連線後的結果,兩個引數char1、char2是要連線的兩個字串。
–查詢所有的員工姓名,按’員工的姓名是xxx’格式顯示
select concat(‘員工的姓名是’,ename) name from employee_xxx;

concat只能有兩個引數,所以如果連線三個字串時,需要兩個concat函式。
–連線employee_xxx表中的ename列和job列,顯示格式為:xxx的工作xxx
SELECT CONCAT(CONCAT(ename, ’ 的工作是’), job) FROM employee_xxx;

在連線兩個以上操作符時並不是很方便。concat的等價操作是連線操作符”||”(類似於java的”+”)。當多個字串連線時,用||符號更直觀。下述SQL語句實現相同的效果:
SELECT ename||‘的工作是’||job from employee_xxx;

練習:
查詢出所有的員工工號,並連線ename和job,顯示格式為xxx work as xxx,並給該連線顯示結果取別名為detail
select empno,ename ||’ work as '||job detail from employee_xx;

8.UPPER、LOWER和INITCAP
這三個函式全部是英文的大小寫轉換函式,用來轉換字元的大小寫:
UPPER(char)用於將字元轉換為大寫形式
LOWER(char)用於將字元轉換為小寫形式
INITCAP(char)用於將字串中每個單詞的首字元大寫,其它字元小寫,單詞之間用空格和非字母字元分隔
如果這三個函式的輸入引數是NULL值,仍然返回NULL值。例如:
SELECT UPPER(‘i like oracle’), LOWER(‘I LIKE ORACLE’), INITCAP(‘i like oracle’) FROM DUAL;
將列出引數“i like oracle”的大寫、小寫和首字元大寫的形式。

在這裡插入圖片描述
一般用來查詢資料表中不確定大小寫的情況。
–查詢員工Jones的資訊
select * from employee_xxx where ename=‘Jones’;
Oracle中不區分大小寫,是指SQL語句不區分大小寫,但是資料是大小寫敏感的,資料庫中的資料是JONES,所以查不到資料
將字元資料轉換為小寫或大寫( 如果不知道職位的大小寫形式 , 可以使用 lower/upper 函式 , 忽略大小寫 )
select * from employee_lzh where lower(ename)=‘jones’;
select * from employee_lzh where upper(ename)=‘JONES’;

9.TRIM、LTRIM、RTRIM

這三個TRIM函式的作用都是截去子字串。語法形式及解釋:
TRIM(c2 FROM c1) 表示從c1的前後截去c2
LTRIM(c1[, c2]) 表示從c1的左邊(Left)截去c2
RTRIM(c1[, c2]) 表示從c1的右邊(Right)截去c2

在後兩個函式中,如果沒有引數c2,就去除空格。例如:
SELECT TRIM(‘甜’ from ‘甜蜜生活是那麼的甜’) AS TRIM1,
LTRIM(‘甜蜜生活是那麼的甜’, ‘甜’) AS LTRIM2,
RTRIM(‘甜蜜生活是那麼的甜’, ‘甜’) AS RTRIM3
FROM DUAL;
在這裡插入圖片描述

其中最常用的是TRIM,經常用來去掉字串前後的空格

10.LPAD、RPAD

PAD意即補丁,LPAD和RPAD兩個函式都叫做補位函式,LPAD表示LEFT PAD,在左邊打補丁,RPAD表示RIGHT PAD,在右邊打補丁。語法如下:
LPAD(char1, n, char2) 左補位函式
RPAD(char1, n, char2) 右補位函式
引數的含義: 在字串引數char1的左端或右端用char2補足到n位,其中引數char2可重複多次。
例如在employee_xxx表中使用左補位,將sal用 7 s e l e c t e n a m e , l p a d ( s a l , 7 , 補齊7位 select ename,lpad(sal,7,' ’) from employee_xxx;

11.SUBSTR

SUBSTR表示在一個字串中擷取子串:
SUBSTR(char, [m[, n]])
用於返回char中從m位開始取n個字元的子串,字串的首位計數從1開始。引數作用:
如果m = 0,則從首字元開始,如果m取負數,則從尾部開始
如果沒有設定n,或者n的長度超過了char的長度,則取到字串末尾為止
SELECT substr(‘i like oracle’,3,4) FROM dual;

在這裡插入圖片描述

SELECT substr(‘i like oracle’,-11,4) FROM dual;
在這裡插入圖片描述

12.INSTR

用來返回在一個字串中子串的位置:
INSTR(char1, char2[, m [, n]])
引數的作用:
返回子串char2在源字串char1中的位置
從m的位置開始搜尋,沒有指定m,從第1個字元開始搜尋
n用於指定子串的第n次出現次數,如果不指定取值1
如果在char1中沒有找到子串char2 ,返回0

例如:
SELECT instr(‘i like oracle’,‘like’) FROM dual;
在這裡插入圖片描述

四、數值常用操作
1.Number表示整數和浮點數
NUMBER(p)表示整數

資料表中的數值型別用NUMBER表示:
NUMBER(p,s)

可以用來表示整數和浮點數。如果沒有設定引數s,則預設取值0,即NUMBER§用來表示整數。P表示數字的總位數,取值為1-38。一般用來在表中存放整數記錄的資料。例如建表時指定書本編號是6位數字:
CREATE TABLE book_xxx(
ID NUMBER(6),
NAME VARCHAR2(20)
);

NUMBER(P,S)表示浮點數
如果NUMBER(p,s)的兩個引數全部顯式定義,則表示浮點數:
p:NUMBER可以儲存的最大數字長度(不包括左右兩邊的0)
s:在小數點右邊的最大數字長度(包括左側0)

NUMBER(p,s)經常用來做表中存放金額、成績等有小數位的資料
例如:
CREATE TABLE book2_xxx(
ID NUMBER(6),
NAME VARCHAR2(20),
price NUMBER(8,4)–書本價格,小數點後4位,總共8位有效數值
);

NUMBER的變種資料型別:內部實現是NUMBER,可以將其理解為NUMBER的別名,目的是與多種資料庫及程式語言相容
NUMERIC(p,s):等價於NUMBER(p,s)
DECIMAL(p,s)或DEC(p,s):等價於NUMBER(p,s)
INTEGER或INT:等價於NUMBER(38)型別
SMALLINT:等價於NUMBER(38)型別
FLOAT(b):等價於NUMBER型別

2.數值操作函式
數值函式指引數是數值型別的函式。常用的有ROUND、TRUNC、MOD、CEIL和FLOOR。

3.ROUND
ROUND(n[, m]) 用於將引數n按照m的數字要求四捨五入。
引數中的n可以是任何數字,指要被處理的數字
m必須是整數
m取正數則四捨五入到小數點後第m位
m取負數,則四捨五入到小數點前m位
m取0值則四捨五入到整數位
m預設,預設值是0
例:
SELECT ROUND(1234.5678, 2) FROM DUAL; --1234.57
SELECT ROUND(1234.5678, -1) FROM DUAL;–1230
SELECT ROUND(1234.5678, 0) FROM DUAL;–1235
SELECT ROUND(1234.5678) FROM DUAL;–1235

4.TRUNC
TRUNC(n[, m])的功能是擷取,其中n和m的定義和ROUND(n[, m])相同,不同的是功能上按照擷取的方式處理數字n
SELECT TRUNC(1234.5678, 2) FROM DUAL; --1234.56
SELECT TRUNC(1234.5678, -1) FROM DUAL;–1230
SELECT TRUNC(1234.5678, 0) FROM DUAL;–1234
SELECT TRUNC(1234.5678) FROM DUAL;–1234

5,MOD
MOD(m, n)是取模函式,返回m除以n後的餘數,如果n為0則直接返回m。
例如:
SELECT MOD(1234,1000) FROM dual;–234
SELECT MOD(999,1000) FROM dual;–999

6.CEIL和FLOOR
CEIL(n)、FLOOR(n)這兩個函式顧名思義,一個是天花板,就是取大於或等於n的最小整數值,一個是地板,就是取小於或等於n的最大整數值。比如數字n = 4.5,那麼它的CEIL是5.0,它的FLOOR是4.0
SELECT CEIL(1234.5678) FROM DUAL;–1235
SELECT FLOOR(1234.5678) FROM DUAL;-1234

五、日期處理
1.DATE
它可以儲存定長的日期或時間資料,包括世紀,年,月,日,時,分和秒。它典型地用來表示什麼時候事情已經發生或將要發生。DATE資料型別表示時間的最小單位是秒。
DATE型別在資料庫中的實際儲存固定為7個位元組,格式分別為:
第1位元組:世紀
第2位元組:年
第3位元組:月
第4位元組:天
第5位元組:小時
第6位元組:分
第7位元組:秒

Date型別的資料可以顯示到年月日,也可以顯示到年月日時分秒,主要看儲存資料的精確度
1)儲存年月日只顯示年月日
2)沒有存時分秒,或者時分秒位00:00:00,也都只顯示年月日
3)儲存年月日時分秒才會顯示年月日時分秒

2.TIMESTAMP
TIMESTAMP表示時間戳,與DATE的區別是不僅可以儲存日期和時間,還能儲存小數秒,可指定為0-9位,預設6位,最高精度可以到ns(納秒)級別。
資料庫內部用7或者11個位元組儲存,精度為0時,用7位元組儲存,與DATE功能相同,精度大於0則用11位元組儲存。格式為:
第1位元組-第7位元組:和DATE相同
第8-11位元組:納秒

例:
CREATE TABLE testTime(
d1 DATE,
d2 TIMESTAMP
);

3.SYSDATE

SYSDATE本質是一個Oracle的內部函式,用來返回當前的系統時間,精確到秒。但該函式預設顯示格式是DD-MON-RR,只有年月日並不顯示時分秒。
例如:
SELECT SYSDATE FROM DUAL;
顯示格式與資料庫所在作業系統有關 英文環境顯示 ‘01- Sep-89’ 中文環境顯示’01-9月-89’

如果想顯示時分秒,需要用日期處理函式將格式轉換一下:
SELECT TO_CHAR(SYSDATE,‘yyyy-mm-dd day hh24:mi:ss’) FROM DUAL;
在這裡插入圖片描述

在建表時,可以將系統時間SYSDATE作為某一列的預設值,當插入新的記錄,該列如果沒有指定值,將會取當時的系統時間該列資料儲存起來。
例如使用者表,使用者的註冊時間列預設取值為該資料記錄插入的時間:
CREATE TABLE user(
id NUMBER(6),
name CHAR(20),
registerTime DATE DEFAULT SYSDATE
);

  1. SYSTIMESTAMP
    SYSTIMESTAMP也是Oracle的內部日期函式,返回當前系統日期和時間,精確到毫秒。

例如:
SELECT SYSTIMESTAMP FROM DUAL;
----FF3顯示TIMESTAMP的3位小數秒資訊
SELECT TO_CHAR(SYSTIMESTAMP ,‘MM/DD/YYYY HH24:MI:SS:FF3’) FROM DUAL;

5.日期轉換函式
日期資料有時需要和字串資料相互轉換,需要用到日期轉換函式,包括TO_CHAR和TO_DATE。

TO_DATE
TO_DATE的功能是將字串按照定製格式轉換為日期型別:
TO_DATE(char[, fmt])
char是要轉換的字串,fmt是轉換格式。

–例:給testTime表插入一條資料,c1列時間值為 2012 年 10 月 1 日
INSERT INTO testTime(c1) VALUES(‘01-10月-12’);–這種時間格式不符合中國常用時間表示格式
–按指定時間格式插入資料
INSERT INTO testTime(c1) VALUES(to_date(‘2012-10-1’,‘yyyy-MM-dd’));

日期格式
常用的日期格式如下:
在這裡插入圖片描述

RR日期格式
two

TO_CHAR
轉換函式的作用是把日期資料轉換為字元資料,常用於格式化顯示日期資料:
to_char(日期資料 , 格式)

例如:按年-月-日 時:分:秒方式顯示employee_xxx表中的員工的入職時間
select ename,to_char(hiredate,‘yyyy-MM-dd HH24:MI:SS’) from employee_xxx;

6.日期常用函式
one
ADD_MONTHS
ADD_MONTHS(date, i):返回日期date加上i個月後的日期值.
其中:
引數i可以是任何數字,大部分時候取正值整數
如果i是小數,將會被擷取整數後再參與運算
如果i是負數,則獲得的是減去i個月後的日期值

例如計算職員入職10週年紀念日:
SELECT ename, ADD_MONTHS(hiredate, 10 * 12) “10週年” FROM employee_xxx;

計算出去年今天的時間值
SELECT add_months(SYSDATE,-12) FROM dual;

MONTHS_BETWEEN
MONTH_BETWEEN(date1, date2):
計算date1和date2兩個日期值之間間隔了多少個月,是date1-date2,如果date2時間比date1晚,會得到負值。
除非兩個日期間隔是整數月,否則會得到帶小數位的結果.
比如計算2015年7月7日到2014年7月8日之間間隔多少個月,會得到11.99個月。
例如計算職員入職多少個月:
SELECT ename, MONTHS_BETWEEN(SYSDATE, hiredate) hiredate FROM employee_lzh;

LAST_DAY
LAST_DAY(date)
返回日期date所在月的最後一天,一般是在按照自然月計算某些業務邏輯,或者安排月末週期性活動時很有用處。例子:
–查詢當月的最後一天
SELECT LAST_DAY(SYSDATE) FROM DUAL;
–查詢12年2月的最後一天
SELECT LAST_DAY(‘20-2月-12’) FROM DUAL;
NEXT_DAY

NEXT_DAY(date, char)
返回date日期資料的下一個周幾,周幾是由引數char來決定的。
在中文環境下,直接使用”星期三”這種形式,英文環境下,需要使用”WEDNESDAY”這種英文的周幾。
為避免麻煩,可以直接用數字1-7表示週日-週六。

需要注意的是NEXT_DAY不要按字面意思理解為明天。查詢下個週一是幾號,如果本週的週一還沒到則返回本週的週一,如果已經過了則返回下週的週一:
SELECT NEXT_DAY(SYSDATE, 2) FROM DUAL;
LEAST和GREATEST
比較函式LEAST和GREATEST語法如下:
GREATEST(expr1[, expr2[, expr3]]…)
LEAST(expr1[, expr2[, expr3]]…)
兩個函式都可以有多個引數值,但引數型別必須一致,返回結果是引數列表中最大或最小的值。
在比較之前,在引數列表中第二個以後的引數會被隱含的轉換為第一個引數的資料型別,所以如果可以轉換,則繼續比較,如果不能轉換將會報錯。

例:
SELECT LEAST(SYSDATE, ‘15-10月 -08’) FROM DUAL;
EXTRACT

EXTRACT(date FROM datetime)
從引數datetime中提取引數date指定的資料,比如提取年、月、日。
例如取出當前日期的年:
SELECT EXTRACT(YEAR FROM SYSDATE) current_year FROM DUAL;

取出指定時間的小時:
SELECT EXTRACT(HOUR FROM TIMESTAMP ‘2015-1-1 10:10:10’) FROM DUAL;
TIMESTAMP '2015-1-1 10:10:10’的作用是將char型別資料轉換成TIMESTAMP 型別
日期相減
日期資料相減 , 得到兩個日期之間的天數差 , 不足一天用小數表示。

如:計算員工入職多少天?
SELECT ename , hiredate , ( sysdate - hiredate ) days FROM employee_xxx;

可以用 round 函式處理
select ename , hiredate , round( sysdate - hiredate ) days from employee_xxx;