1. 程式人生 > >Oracle資料庫中的函式、檢視和索引

Oracle資料庫中的函式、檢視和索引

1. Oracle函式

Oracle SQL 提供了用於執行特定操作的專用函式。這些函式大大增強了 SQL 語言的功能。函式可以接受零個或者多個輸入引數,並返回一個輸出結果。 Oracle 資料庫中主要使用兩種型別的函式:
1. 單行函式:
對每一個函式應用在表的記錄中時,只能輸入一行結果,返回一個結果,比如: MOD(x,y)返回 x 除以 y 的餘數( x 和 y 可以是兩個整數,也可以是表中的整數列)。常用的單行函式有:對每一個函式應用在表的記錄中時,只能輸入一行結果,返回一個結果,比如: MOD(x,y)返回 x 除以 y 的餘數( x 和 y 可以是兩個整數,也可以是表中的整數列)。
常用的單行函式有:


 字元函式:對字串操作。
 數字函式:對數字進行計算,返回一個數字。
 轉換函式:可以將一種資料型別轉換為另外一種資料型別。
 日期函式:對日期和時間進行處理。

2. 聚合函式:
聚合函式同時可以對多行資料進行操作,並返回一個結果。比如 SUM(x)返回結果集中 x 列的總合。聚合函式同時可以對多行資料進行操作,並返回一個結果。比如 SUM(x)返回結果集中 x 列的總合。

字元函式

字元函式接受字元引數,這些引數可以是表中的列,也可以是一個字串表示式。下表
列出了常用的字元函式。
在這裡插入圖片描述

在這裡插入圖片描述

數字函式

數字函式接受數字引數,引數可以來自表中的一列,也可以是一個數字表達式。

在這裡插入圖片描述

說明:

  1. ROUND(X[,Y]),四捨五入。
    在預設 y 時,預設 y=0;比如: ROUND(3.56)=4。
    y 是正整數,就是四捨五入到小數點後 y 位。 ROUND(5.654,2)=5.65。
    y 是負整數,四捨五入到小數點左邊|y|位。 ROUND(351.654,-2)=400。

  2. TRUNC(x[,y]),直接擷取,不四捨五入。
    在預設 y 時,預設 y=0;比如: TRUNC (3.56)=3。
    y 是正整數,就是四捨五入到小數點後 y 位。 TRUNC (5.654,2)=5.65。
    y 是負整數,四捨五入到小數點左邊|y|位。 TRUNC (351.654,-2)=300。

日期函式

日期函式對日期進行運算。常用的日期函式有:
1.SYSDATE:顯示系統當前日期

例:select sysdate from dual
  1. ADD_MONTHS(date,n),在某一個日期 date 上,加上指定的月數 n,返回計算後的新日期。date 表示日期, n 表示要加的月數。
例:select add_months(sysdate, 6) six_month_later from dual;
  1. LAST_DAY(date),返回指定日期當月的最後一天。
    例:select last_day(sysdate) from dual;

4.NEXT_DAY(date,char):返回date日期的下一個周幾,周幾是由char決定的。

例:select NEXT_DAY(SYSDATE, ‘星期三’) from dual;

Char:中文環境中用中文,英文環境中用英文。
5.MONTHS_BETWEEN(DATE1,DATE2):計算date1和date2兩個日期間的間隔。注意是date1-date2

例:select months_between(sysdate, ’17-1月-17’) from dual;

例:計算emp表中職員入職多少個月。

  1. ROUND(d[,fmt]),返回一個以 fmt 為格式的四捨五入日期值, d 是日期, fmt 是格式
    模型。預設 fmt 為 DDD,即月中的某一天。
如果 fmt 為“YEAR”則舍入到某年的 1 月 1 日,即前半年捨去,後半年作為下一年。
如果 fmt 為“MONTH”則舍入到某月的 1 日,即前月捨去,後半月作為下一月。
例:select round(to_date(‘2009-09-25’, ‘yyyy-mm-dd’), ‘MONTH’) round_date from dual;
例:select round(to_date(‘2009-09-25’, ‘yyyy-mm-dd’), ‘YEAR’) round_date from dual;
例:select round(to_date(‘2009-09-25’, ‘yyyy-mm-dd’)) round_date from dual;

與 ROUND 對應的函式是TRUNC(d[,fmt])對日期的操作, TRUNC 與 ROUND 非常相似,只
是不對日期進行舍入,直接擷取到對應格式的第一天。

例:select TRUNC(to_date(‘2009-09-25’, ‘yyyy-mm-dd’), ‘MONTH’) trunc_date from dual;
例:select TRUNC (to_date(‘2009-09-25’, ‘yyyy-mm-dd’), ‘YEAR’) trunc_date from dual;
例:select TRUNC (to_date(‘2009-09-25’, ‘yyyy-mm-dd’)) trunc_date from dual;
  1. EXTRACT(fmt FROM d),提取日期中的特定部分。
    fmt 為: YEAR、MONTH、DAY、HOUR、MINUTE、SECOND。其中 YEAR、MONTH、DAY可以為 DATE 型別匹配,也可以與TIMESTAMP 型別匹配;但HOUR、MINUTE、SECOND 必須與 TIMESTAMP 型別匹配。
    例:EXTRACT 函式示例
    Select sysdate “date”,
    Extract(year from sysdate) “year”
    Extract(month from sysdate) “month”
    Extract(day from sysdate) “day”
    Extract(hour from systimestamp) “hour”
    Extract(minute from systimestamp) “minute”
    Extract(second from systimestamp) “second”
    From dual;

轉換函式

轉換函式將值從一種資料型別轉換為另外一種資料型別。常用的轉換函式有:

  1. TO_CHAR(d|n[,fmt])
    把日期和數字轉換為制定格式的字串。 fmt 是格式化字串,日期的格式化字串前
    面已經學習過。
    程式碼演示:TO_CHAR 對日期的處理
    SQL> SELECT TO_CHAR(SYSDATE,‘YYYY"年"MM"月"DD"日" HH24:MI:SS’) “date” FROM DUAL;

  2. TO_DATE(x [,fmt])
    將一個格式字串轉換成日期

  3. NVL(x,value)
    如果 x 為空,返回 value,否則返回 x。
    案例 7:對工資是 2000 元以下的員工,如果沒有發獎金,每人獎金 100 元。

    程式碼演示:NVL 函式
    SQL> SELECT ENAME,JOB,SAL,NVL(COMM,100) FROM EMP WHERE SAL<2000;
    ENAME JOB SAL NVL(COMM,100)
  1. NVL2(x,value1,value2)
    如果 x 非空,返回 value1,否則返回 value2。
    案例 8:對 EMP 表中工資為 2000 元以下的員工,如果沒有獎金,則獎金為 200 元,如
    果有獎金,則在原來的獎金基礎上加 100 元。
程式碼演示:NVL2 函式
SQL> SELECT ENAME,JOB,SAL,NVL2(COMM,comm+100,200) "comm"
2 FROM EMP WHERE SAL<2000;
  1. COALESCE(expr1[,expr2[,expr3]]…)
    返回引數列表中第一個非空的表示式的結果。
例:select ename,sal,comm,COALESCE(sal+comm,sal)salary FROM emp WHERE deptno=30;
  1. LNNVL(condition):通常用在where子句中,返回那些不滿足condition條件或者判斷條件為NULL的記錄。所有LNNVL也可以認為是is null 或is not true。
例:獲取獎金數小於500的員工的資訊
Select ename,comm from emp where lnnvl(comm>=500);

1.DECODE(expr, search1,result[, search2, result2…][, default])
DECODE用於比較引數expr的值,如果匹配到哪一個search條件,就返回對應的result結果。可以有多組search和result的對應關係,如果任何一個search條件都沒有匹配到,返回最後default的值。Default引數是可選的,如果沒有提供default引數值,當沒有匹配到時,返回NULL。

例:查詢職員表,根據職員的職位計算獎金,當職位分別是MANAGER,ANALYST,SALESMAN時,獎勵金額分別是薪水的1.2倍,1.1倍,1.05倍。如果不是這三個職位,則獎勵金額為領取薪水值
Select ename,job,sal, decode(job,’MANAGR’,sal*1.2, ‘ANALYST’,sal*1.1,’SALESMAN’,
sal*1.05,sal)bonus from emp;

總結:函式可以巢狀使用

–==字元函式:處理字串

第一組

–ascii chr

select ascii('a') from dual;
select char(97) from dual;

–lower upperinitcap
–求大寫A 的ascii

select ascii (upper('a')) from dual;

–求小寫a的ascii

select ascii (lower('A')) from dual;

–Initcap

select initcap(ename) from emp;

第二組

–ltrim rtrim trim
–注意事項 Ltrimrtrim 是字元級別的擷取,在擷取的時候,按照字元去匹配

select  Ltrim('ellen','e') from dual;
select rtrim('ellenellneen','ne') from dual;
select trim('ne',from 'ellenellneen') from dual;

–會報錯,,trim的擷取集只能是一個字元

select trim('   ellen') from dual;
--去空格--

第三組

–Lpad rpad 字串補位函式

左補齊

select lpad('hao',2,'ni') from dual;
select lpad('hao',5,'ni') from dual;
select lpad('hao',10,'ni') from dual;

右補齊

select rpad ('ni',1,'hao') from dual;
select rpad ('ni',5,'hao') from dual;
select rpad ('ni',10,'hao') from dual;

其他組

–concat
–字串連線:和連線運算子作用一致

select concat ('Dear',ename) from emp;

–legth:查詢emp員工表中員工姓名為5個字元的員工資訊

select *from emp where length(ename)=5;

–substr:求子串

select substr('Hello word',3) from dual;
select substr('Hello word',3,5) from dual;

–replace:字串替換

select replace('shelly','el','en') from dual;

可以分組去記

–=數學函式=====

–sign :求符號

select sign(-5) from dual;

–ceil: 求上整

select ceil(5.6) from dual;

–floor 求下整

select floor(5.6) from dual;

–round 四捨五入

select round(3.14) from dual
select round(3.14,1) from dual
select round(3.1415926,4) from dual
select round(356,-2) from dual   --一般是不用的

–trunc:截斷

select trunc(3.1415926,4) from dual;
select trunc(356,-2) from dual

–=日期函式==========

--sysdatesystimestamp(比sysdate)更精確
 
select sysdate from dual;
 
--add_months(date,1)1表示月份
 
select add_months(sysdate,1) from dual;
 
--month_between(date,date)
 
select months_between(sysdate,hiredate) from emp;
select month_between(sysdate,add_months(sysdate,1)) from dual;

 
--last_day(date)
select last_day(sysdate) from dual;
select last_day('08-2月-2018')from dual;
 
--next_day(date,char)
select next_day(sysdate,'星期二') from dual;

–round 四捨五入–trunc:截斷也可以對日期進行操作

select trunc(sysdate,'MONTH') from dual;
select round(sysdate,'MONTH') from dual;
 
select round(date'2018-01-16','MONTH') from dual;

—extract:

select extract(year from sysdate) as 年,
extract(month from sysdate) as 月,
extract (day from sysdate) as 日,
extract (hour from systimestamp) as 時,
extract (minute from systimestamp) as 分,
extract(second from systimestamp) as 秒
from dual;

–=轉換函式======

to_char to_date
–nvl nvl2
–問題:對emp表中的員工獎金為空,那麼給200元獎金,如果獎金不為空,那麼在原有獎金基礎上加100

update emp set comm=nvl2(comm,comm+100,200);

–問題:查詢emp表中所有員工的月收入

select ename,sal+nvl(comm,0) as 月收入 from emp;
select ename,coalesec(sal+comm,sal) as 月收入 from emp;

–decode
–案例:按照職位提升工資,如果是MANAGER,工資是原來的1.5倍,如果是ANALYST工資是原來的1.2倍
–如果是SALERSMAN工資是原來的1.1倍,預設情況下,工資是原來的1.05倍

update emp01 set sal=decode(job,'MANAGER',sal*1.5,'ANALYST',sal*1.2
,'SALERMAN',sal*1.1,sal*1.05)

2. 資料庫中的檢視

(1)什麼是檢視?

檢視是一張虛表,就是對select查詢的結果給取了一個名字。select查詢的表稱為基表
檢視不會儲存資料,資料儲存在基表中,檢視只是儲存一個對映關係

create view test as select ename,sal,job from emp;

(2)檢視的作用

		1.簡化複雜查詢
		2.限制資料訪問

–簡化複雜查詢
–舉例:查詢每個部門的員工人數和部門名稱

select d.dname,count(*)
from dept d,emp e
where d.deptno=e.deptno
group by d.dname;

可以建立檢視儲存上述結果

create view numEmp as
select d.dname,count(*) co
from dept d,emp e
where d.deptno=e.deptno
group by d.dname;


問題:查詢人數大於3的部門的名稱和員工資訊
select *from numEmp where co>3;

–建立檢視的時候,如果遇到select語句中有聚合函式,需要給聚合函式別名

   --限制資料訪問舉例
  create user hope identified by 123456;
  grant connect to hope;
  grant select on scott.emp to hope; --現在是可以看見整張表

create view empSimple as
select empno,ename,job,mgr,hiredate,deptno
from emp;

–注意事項:
(1)對於檢視的查詢和表的查詢是一樣的
(2)檢視中不包含資料,檢視只是一個對映關係
(3)當基表發生改變時,檢視也會隨之改變

(3)怎麼建立和刪除檢視

語法:

create view 檢視名(可以起別名) as
select...from ...【with read only】
--with  read only 表示檢視是一個只讀檢視,只能查詢,不能修改

–分類:簡單檢視(建立檢視的時候可以指定一個別名)

create view v_emp(“工號”,“姓名“) as
select empno,ename from emp;

create or replace view v_emp("編號","姓名‘) as
select empno,ename from emp with read only;

注意事項:別名,要麼沒有引號,要是有引號就必須是雙引號 " "**

question:能不能對檢視進行DML操作insert update delete?
能,但是不是所用的檢視都能進行DML操作
牽扯到檢視的分類
(1)非只讀的簡單檢視可以進行DML操作,事實上是對基表的操作

create or replace view test
   as select empno,ename from emp;
     
       insert into test values(1010,'sheely')可以看到基表裡面多了一條記錄          
       是不是所有的簡單檢視都可以進行DML操作呢?不是的          
        create or replace view test
       as select ename,sal from emp;        
       insert into test values('haloo',5000)執行不了,不允許插入
       原因是:違反了基表的主鍵約束
      
       結論:針對檢視的DML操作,不能違反基表的約束,所以並不是所有的簡單的都可以

(2)帶有with read only 和複雜檢視  連線檢視不能進行DML操作

-修改檢視 replace: 沒有就建立,有的話就修改

檢視的分類

簡單檢視:簡單查詢語句(不涉及到連線和聚合函式)

複雜檢視:牽扯到聚合函式,但是不涉及到表連線

連線檢視:涉及到表連線的檢視

–連線檢視舉例:

CREATE view  emp_dept as
select e.*,d.*
where e.deptno=d.deptno;

(4)什麼是索引?

類比圖書的目錄:索引是一種加快資料訪問速度的機制
索引需要佔用磁碟空間的,維護索引需要資源開銷,所以索引並不是越多越好

索引的分類:
(1)單列索引
(2)複合索引

–單列索引

create index idx_ename on emp(ename)
語法:create index 索引名on 表名(欄位名1,欄位名2)

–複合索引

create index idx_ename_deptno on emp(ename,deptno);

–唯一索引

create unique index idx_ename on emp(ename);
--注意;在某一欄位上建立一個唯一索引,自動會在該欄位建立一個唯一約束
--刪除:drop index 索引名
drop  index idx_ename;

--重建  alter index idx_ename rebuild;

注意事項:如果定義了主鍵約束和唯一約束,那麼Oracle會再自動的建立一個唯一索引

+++++++原創博文,轉載請註明出處。+++++++++