日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(五)Oracle函数 序列 约束 索引

發布時間:2024/8/26 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (五)Oracle函数 序列 约束 索引 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

DECODE函數

DECODE函數基本語法

DECODE函數的語法如下:DECODE (expr, search1, result1[, search2, result2…][, default])

它用于比較參數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, 'MANAGER', sal*1.2,'ANALYST', sal*1.1,'SALESMAN', sal*1.05, sal) AS bonus FROM emp;

DECODE函數功能相似的有CASE語句,實現類似于if-else的操作。

SELECT ename, job, sal,CASE job
WHEN 'MANAGER' THEN sal * 1.2 WHEN 'ANALYST' THEN sal * 1.1 WHEN 'SALESMAN' THEN sal * 1.05 ELSE sal END bonus FROM emp;

排序函數

ROW_NUMBER

ROW_NUMBER語法如下:ROW_NUMBER() OVER(?PARTITION BY col1 ORDER BY col2)

表示根據col1分組,在分組內部根據col2排序。此函數計算的值就表示每組內部排序后的順序編號,組內連續且唯一。

ROWNUM是偽列, ROW_NUMBER功能更強,可以直接從結果集中取出子集。

場景:按照部門編碼分組顯示,每組內按職員編碼排序,并賦予組內編碼

SELECT deptno, ename, empno,ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY empno) AS emp_id FROM emp;

RANK

RANK函數的語法如下:RANK() OVER(PARTITION BY col1 ORDER BY col2)

表示根據col1分組,在分組內部根據col2給予等級標識,即排名,相同的數據返回相同排名。特點是跳躍排序,如果有相同數據,則排名相同,比如并列第二,則兩行數據都標記為2,但下一位將是第四名。

和ROW_NUMBER的區別是有結果有重復值,而ROW_NUMBER沒有。

場景:按照部門編碼分組,同組內按薪水倒序排序,相同薪水則按獎金數正序排序,并給予組內等級,用Rank_ID表示

SELECT deptno, ename, sal, comm, RANK() OVER (PARTITION BY deptno ORDER BY sal DESC, comm) "Rank_ID" FROM emp;

※PARTITION 分區

DENSE_RANK

DENSE_RANK函數的語法如下:?DENSE_RANK() OVER(?PARTITION BY col1 ORDER BY col2)

表示根據col1分組,在分組內部根據col2給予等級標識,即排名,相同的數據返回相同排名。特點是連續排序,如果有并列第二,下一個排序將是三,這一點是和RANK的不同,RANK是跳躍排序。

場景:關聯emp和dept表,按照部門編碼分組,每組內按照員工薪水排序,列出員工的部門名字、姓名和薪水:

SELECT d.dname, e.ename, e.sal, DENSE_RANK() OVER (PARTITION BY e.deptno ORDER BY e.sal) AS drank FROM emp e join dept d ON e.deptno = d.deptno;

集合操作

UNION、UNION ALL

為了合并多個SELECT語句的結果,可以使用集合操作符,實現集合的并、交、差。

集合操作符包括UNION、UNION ALL、INTERSECT和MINUS。多條作集合操作的SELECT語句的列的個數和數據類型必須匹配。

ORDER BY子句只能放在最后的一個查詢語句中。

集合操作的語法如下:

SELECT statement1 [UNION | UNION ALL | INTERSECT | MINUS] SELECT statement2;

UNION和UNION ALL用來獲取兩個或兩個以上結果集的并集:

  • UNION操作符會自動去掉合并后的重復記錄。
  • UNION ALL返回兩個結果集中的所有行,包括重復的行。

例如,合并職位是’MANAGER’的員工和薪水大于2500的員工集合,查看兩種方式的結果差別:

--Union SELECT ename, job, sal FROM emp WHERE job = 'MANAGER' Union SELECT ename, job, sal FROM emp WHERE sal> 2500;--Union all SELECT ename, job, sal FROM emp WHERE job = 'MANAGER' Union all SELECT ename, job, sal FROM emp WHERE sal> 2500;

INTERSECT

INTERSECT函數獲得兩個結果集的交集,只有同時存在于兩個結果集中的數據,才被顯示輸出。使用INTERSECT操作符后的結果集會以第一列的數據作升序排列。

例如:顯示職位是’MANAGER’的員工和薪水大于2500的員工的交集:

SELECT ename, job, sal FROM emp WHERE job = 'MANAGER' INTERSECT SELECT ename, job, sal FROM emp WHERE sal> 2500;
同理:
SELECT
ename,job,sal FROM emp WHERE job = 'MANAGER' AND sal >2500;

MINUS

MINUS函數獲取兩個結果集的差集。只有在第一個結果集中存在,在第二個結果集中不存在的數據,才能夠被顯示出來。也就是結果集一減去結果集二的結果。

例如:列出職位是MANAGER但薪水低于2500的員工記錄:

SELECT ename, job, sal FROM emp WHERE job = 'MANAGER' MINUS SELECT ename, job, sal FROM emp WHERE sal > 2500;
同理:
SELECT
ename,job,sal FROM emp WHERE job = 'MANAGER' AND NOT sal > 2500;

主鍵約束

主鍵的意義

主鍵(Primary Key)約束條件從功能上看相當于非空(NOT NULL)且唯一(UNIQUE)的組合。主鍵字段可以是單字段或多字段組合,即:在主鍵約束下的單字段或者多字段組合上不允許有空值,也不允許有重復值。

主鍵可以用來在表中唯一的確定一行數據。一個表上只允許建立一個主鍵,而其它約束條件則沒有明確的個數限制。

主鍵選取的原則

  • 主鍵應是對系統無意義的數據
  • 永遠也不要更新主鍵,讓主鍵除了唯一標識一行之外,再無其他的用途
  • 主鍵不應包含動態變化的數據,如時間戳
  • 主鍵應自動生成,不要人為干預,以免使它帶有除了唯一標識一行以外的意義
  • 主鍵盡量建立在單列上

添加主鍵約束

在建表時添加主鍵約束條件:

CREATE TABLE employees2 ( name VARCHAR2(30) constraint pk_name primary key, email VARCHAR2(50), salary NUMBER(7, 2), hiredate DATE );

建表后創建主鍵約束條件,并自定義約束條件名稱:

CREATE TABLE employees3 ( eid NUMBER(6), name VARCHAR2(30), email VARCHAR2(50), salary NUMBER(7, 2), hiredate DATE );ALTER TABLE employees3 ADD CONSTRAINT employees3_eid_pk PRIMARY KEY (eid);

/*查看表TEST的約束條件*/
SELECT * FROM all_constraints WHERE table_name = 'employees3';

外鍵約束

外鍵約束的意義

外鍵約束條件定義在兩個表的字段或一個表的兩個字段上,用于保證相關兩個字段的關系。比如emp表的deptno列參照dept表的deptno列,則dept稱作主表或父表,emp表稱作從表或子表。

添加外鍵約束

先建表,在建表后建立外鍵約束條件:

CREATE TABLE employees4 ( eid NUMBER(6), name VARCHAR2(30), salary NUMBER(7, 2), deptno NUMBER(4) );ALTER TABLE employees4 ADD CONSTRAINT employees4_deptno_fk FOREIGN KEY (deptno) REFERENCES dept(deptno);

外鍵約束對一致性的維護

外鍵約束條件包括兩個方面的數據約束:

  • 從表上定義的外鍵的列值,必須從主表被參照的列值中選取,或者為NULL;
  • 當主表參照列的值被從表參照時,主表的該行記錄不允許被刪除。
--成功DML語句: INSERT INTO employees4(eid, name, deptno) VALUES(1234, ‘rose tyler’, 40);--成功 INSERT INTO employees4(eid, name, deptno) VALUES(1235, ‘martha jones’, NULL); --成功--失敗DML語句: INSERT INTO employees4(eid, name, deptno) VALUES(1236, 'donna noble', 50);--失敗,不存在部門50 DELETE FROM dept WHERE deptno = 40; --失敗,40被參照,不允許刪除

外鍵約束對性能的降低

如果在一個頻繁DML操作的表上建立外鍵,每次DML操作,都將導致數據庫自動對外鍵所關聯的對應表做檢查,產生開銷,如果已在程序中控制邏輯,這些判斷將增加額外負擔,可以省去。

另外外鍵確定了主從表的先后生成關系,有時會影響業務邏輯。

關聯不一定需要外鍵約束

如果業務邏輯要求保證數據完整性,可由程序控制,不一定需要外鍵約束。

另外為了簡化開發,維護數據時不用考慮外鍵約束,以及大量數據DML操作時不需考慮外鍵耗費時間。

唯一性約束

什么是唯一性約束

唯一性(Unique)約束條件用于保證字段或者字段的組合不出現重復值。當給表的某個列定義了唯一約束條件,該列的值不允許重復,但允許是NULL值。

唯一性約束條件可以在建表同時建立,也可以在建表以后再建立。

添加唯一性約束

在建表employees的同時,在eid、email列上創建唯一約束條件,并在建表后在name列上建立一個名為employees_name_uk的唯一約束條件:

DROP TABLE employees ; --將表刪掉重新創建 CREATE TABLE employees (eid NUMBER(6) constraint employees_eid_uk unique,name VARCHAR2(30),email VARCHAR2(50),salary NUMBER(7, 2),hiredate DATE, );

在建表之后增加唯一性約束條件:

ALTER TABLE employees ADD CONSTRAINT employees_name_uk UNIQUE(name);

檢查約束

什么是檢查約束

檢查(Check)約束條件用來強制在字段上的每個值都要滿足Check中定義的條件。當定義了Check約束的列新增或修改數據時,數據必須符合Check約束中定義的條件。

添加檢查約束

員工的薪水必須大于2000元,增加檢查約束:

ALTER TABLE employees4 ADD CONSTRAINT employees4_salary_check
CHECK (salary > 2000);

當插入大于2000的數據,操作成功:

INSERT INTO employees4(eid, name, salary, deptno) VALUES(1236, 'donna noble', 2500, 40);

試圖修改職員的薪水為1500元,更新失敗:

UPDATE employees4 SET salary = 1500 WHERE eid = 1236;?

序列

什么是序列

序列(SEQUENCE)是一種用來生成唯一數字值的數據庫對象。序列的值由Oracle程序按遞增或遞減順序自動生成,通常用來自動產生表的主鍵值,是一種高效率獲得唯一鍵值的途徑。

序列是獨立的數據庫對象,和表是獨立的對象,序列并不依附于表。

通常情況下,一個序列為一個表提供主鍵值,但一個序列也可以為多個表提供主鍵值。

舉例說明,創建一個序列,起始數據是100,步進是10:

CREATE SEQUENCE emp_seq START WITH 100 INCREMENT BY 10;

當序列被創建后,第一個序列值將是100,將要生成的序列號分別是110、120、130等。

序列中有兩個偽列:

  • NEXTVAL:獲取序列的下個值
  • CURRVAL:獲取序列的當前值

當序列創建以后,必須先執行一次NEXTVAL,之后才能使用CURRVAL。

獲取序列的第一個值,并且使用序列值為EMP表插入新的記錄:

SELECT emp_seq.NEXTVAL FROM DUAL; INSERT INTO emp(empno, ename) VALUES(emp_seq.NEXTVAL, 'donna');

查詢剛剛生成的記錄,主鍵值將是110:

SELECT empno, ename FROM emp WHERE ename = 'DONNA';

此時查詢序列的當前值,會得到110的數字。

SELECT emp_seq.CURRVAL FROM DUAL;

在序列的使用過程中,比如執行了一條語句:

SELECT emp_seq.NEXTVAL FROM DUAL;

則浪費了一個序列值,會導致表的主鍵值不連續。而CURRVAL的使用不會導致序列值的遞進。

刪除序列

刪除序列的語法如下:

DROP SEQUENCE sequence_name;

刪除序列emp_seq:

DROP SEQUENCE emp_seq;

索引

索引的原理

索引是一種允許直接訪問數據表中某一數據行的樹型結構,為了提高查詢效率而引入,是獨立于表的對象,可以存放在與表不同的表空間(TABLESPACE)中。索引記錄中存有索引關鍵字和指向表中數據的指針(地址)。對索引進行的I/O操作比對表進行操作要少很多。

索引一旦被建立就將被Oracle系統自動維護,查詢語句中不用指定使用哪個索引,是一種提高查詢效率的機制。

ROWID: 偽列,唯一標識一條數據記錄,可理解為行地址。

創建索引

創建索引的語法:

CREATE [UNIQUE] INDEX index_name ON table(column[, column…]);

其中:

  • index_name表示索引名稱
  • table表示表名
  • column表示列名,可以建立單列索引或復合索引
  • UNIQUE表示唯一索引

在EMP表的ENAME列上建立索引:

CREATE INDEX idx_emp_ename ON emp(ename);

復合索引也叫多列索引,是基于多個列的索引。如果經常在ORDER BY子句中使用job和salary作為排序依據,可以建立復合索引:

CREATE INDEX idx_emp_job_sal ON emp(job, sal);

當做下面的查詢時,會自動應用索引idx_emp_job_sal

SELECT empno, ename, sal, job FROM emp ORDER BY job, sal;

刪除索引

當一個表上有不合理的索引,會導致操作性能下降,刪除索引的語法:

DROP INDEX index_name;

刪除索引idx_emp_ename:

DROP INDEX idx_emp_ename;

合理使用索引提升查詢效率

為提升查詢效率,創建和使用索引的原則:

  • 為經常出現在WHERE子句中的列創建索引
  • 為經常出現在ORDER BY、DISTINCT后面的字段建立索引。如果建立的是復合索引,索引的字段順序要和這些關鍵字后面的字段順序一致
  • 為經常作為表的連接條件的列上創建索引
  • 不要在經常做DML操作的表上建立索引
  • 不要在小表上建立索引
  • 限制表上的索引數目,索引并不是越多越好
  • 刪除很少被使用的、不合理的索引

?

?

?

?

?

?

轉載于:https://www.cnblogs.com/Jonecmnn/p/6366327.html

總結

以上是生活随笔為你收集整理的(五)Oracle函数 序列 约束 索引的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。