oracle
流行的數據庫都屬於關係型數據庫:1、數據存在表中 2、表和表之間有關聯
流行數據庫:
- MySQL 小型數據庫 oracle 免費
- oracle 大型數據庫 oracle 學習、開發階段免費,上線收費
- SQLSever 中大型數據庫 微軟
- DB2 IBM
- 兩個服務:數據庫實例、數據庫監聽服務
SQL語言的分類:
- DB Database 數據庫
- DBMS DatabaseManagement System 數據庫管理系統
- DBA Database Administrator 數據庫管理員
- SQL Structured Query Language結構化查詢語言
- DDL Data Definition Language 數據定義語言
- DML Data manipulation language 數據操縱語言
- TCL Transaction Control Language事務控制語言
- CRUD Create、Retrieve、Update、Delete增刪改查
日期類型、字符串類型的值都需要用單引號”括起來。
每句語句用分號;結束
主鍵和外鍵:
- 主鍵(PRIMARY KEY):表中每一行記錄的唯一標識,一般以一個字段作爲組件,也可以兩個或兩個以上作爲聯合主鍵,主鍵值不能重複。
- 外鍵(FOREIGN KEY):引用另一張表主鍵信息。
主表和子表:被引用的表是主表,引用別人的是子表。
查詢
不會改變表中數據,執行查詢語句後會得到一個結果集。
全部數據: SELECT * FROM 表名;
某些字段: SELECT 字段1, 字段2… FROM 表名;
去重複: DISTINCT
起別名: SELECT 字段 [AS] 別名 FROM 表名; 別名中有空格要用”“括起來。
連接符: SELECT ename || “的” || (sal + NVL(comm, 0)) *12 年薪 FROM emp;
條件查詢:SELECT 字段1, 字段2… FROM emp WHERE 條件;
中文系統下日期默認格式: hiredate = “2-5**月**-1994”;
表名、字段名、關鍵字不區分大小寫,表格中數據內容區分大小寫。
運算符:>、 <、 >=、 <=、 =、 !=、 <>、 ^=、 AND、 OR、 NOT、IS NULL、 IS NOT NULL、 IN、 ANY、 ALL、 BETWEEN…AND…
模糊查詢: WHERE 字段 LIKE ‘_value%’;
通配符: _ 一個字符 % 零或多個字符
排序: ORDER BY 字段1, 字段2 [{DESC | ASC}]
默認不寫按升序排列,先按字段1排序,重複部分再按字段2排序,以此類推
DESC降序 ASC升序
SELECT ename, job, sal s FROM emp ORDER BY sal/3/s DESC, ename ASC;
空值排序問題:ASC NULL在最後, DESC NULL在最前, (NULL最大)
僞列
- rowid: 數據插入時Oracle自動分配的一個固定的唯一地址。
- rownum: 對採集結果進行編號,不是固定的,可以用來分頁。
函數:
- 字符函數
CONCAT(x, y)、 INITCAP(x)、 LOWER(x)、 UPPER(x)、 LPAD(x, width [,pad_string])、 RPAD(x, width [,pad_string])、 LENGTH(x)、 LTRIM(x [,trim_string])、 RTRIM(x [,trim_string])、 TRIM(x [,trim_string])、 INSTR(x, find_string [,start] [,occurrence])、 SUBSTR(x, start, [,length])、 NVL(x, value)、 - 數值函數
ABS(x)、 CEIL(x)、 FLOOR(x)、 ROUND(x)、 MOD(x, y)、 POWER(x, y)、 SQRT(x)、 TRUNC(x [,y])、 - 日期函數
SYSDATE、 ADD_MONTHS(x, y)、 MONTHS_BETWEEN(x, y)、 - 轉換函數
TO_CHAR(x [,format])、 TO_DATE(x [,format])、 TO_NUMBER(x [,format])、 - 聚合函數
AVG(x)、 COUNT(x)、 MAX(x)、 MIN(x)、 SUM(x)、 正則表達式函數
REGEXP_LIKE(x, pattern [,math_option])、
REGEXP_INSTR()、
REGEXP_REPLACE()、
REGEXP_SUBSTR()、
REGEXP_COUNT()、SELECT enamel, hiredate FROM emp WHERE hiredate REGEXP_LILE(TO_CHAR(hiredate, 'YYYY'), '^198[12]$')
聚合函數使用注意事項:
1. 如果不使用分組,SELECT後不能字段和聚合函數一起使用。
2. 聚合函數不能應用在WHERE字句中。
分組: GROUP BY 字段1, 字段2…
在GROUP BY後面多寫字段可以多查詢信息
分組時一般按哪些字段分組就把哪些字段一起查詢出來,一般分組和聚合函數搭配使用。
HAVING:對分組後的內容進行過濾。
WHERE和HAVING對比:
- 都能實現條件過濾。
WHERE條件作用於表對字段進行過濾,HAVING條件作用於分組後的結果,一般條件中使用聚合函數。
SELECT deptno, COUNT(ROWID) FROM emp WHERE job = ‘SALESMAN’ GROUP BY deptno HAVING COUNT(ROWID) > 2;
DECODE
DECODE(條件,值1,返回值1,值2,返回值2,…值n,返回值n,缺省值)
該函數的含義如下:
IF 條件=值1 THEN
RETURN(返回值1)
ELSIF 條件=值2 THEN
RETURN(返回值2)
……
ELSIF 條件=值n THEN
RETURN(返回值n)
ELSE
RETURN(缺省值)
END IFDECODE(字段或字段的運算,值1,值2,值3)
這個函數運行的結果是,當字段或字段的運算的值等於值1時,該函數返回值2,否則返回值3
當然值1,值2,值3也可以是表達式,這個函數使得某些sql語句簡單了許多
CASE WHEN
- 簡單Case函數
CASE 條件
WHEN 值1 THEN 返回值1
WHEN 值2 THEN 返回值2
…
ELSE 缺省返回值 END - Case搜索函數
CASE
WHEN 條件= 值1 THEN 返回值1
WHEN 條件= 值2 THEN 返回值2
ELSE 缺省返回值 END
--簡單CASE函數
CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE '其他' END
--CASE搜索函數
CASE
WHEN sex = '1' THEN '男'
WHEN sex = '2' THEN '女'
ELSE '其他' END
PIOVT
行轉列函數:
PIVOT(
聚合函數(value_column)
FOR pivot_column
IN(<column_list>)
)
例子:取自這篇文章
select * from tb
--------------------------------結果------------------------------------------------------------------------------------
姓名 課程 分數
---------- ---------- -----------
張三 語文 74
張三 數學 83
張三 物理 93
李四 語文 74
李四 數學 84
李四 物理 94
(6 行受影響)
現在的問題是:我想根據姓名統計這個人的三門成績,即:姓名 語文 數學 物理
首先看看使用case when end結構的時候:
select 姓名,
max(case 課程 when '語文' then 分數 else 0 end)語文,
max(case 課程 when '數學'then 分數 else 0 end)數學,
max(case 課程 when '物理'then 分數 else 0 end)物理
from tb
group by 姓名
--------------------------------結果------------------------------------------------------------------------------------
姓名 語文 數學 物理
---------- ----------- ----------- -----------
李四 74 84 94
張三 74 83 93
(2 行受影響)
這個結果就是我們想要的,然後再看看使用pivot:
select * from tb pivot(max(分數) for 課程 in (語文,數學,物理))a
--------------------------------結果------------------------------------------------------------------------------------
姓名 語文 數學 物理
---------- ----------- ----------- -----------
李四 74 84 94
張三 74 83 93
(2 行受影響)
哇,結果一模一樣!這個就是我想用的結果。
UNPIOVT
列轉行函數:
UNPIVOT(
value_column
FOR pivot_column
IN(<column_list>)
)
查詢過程中每一條記錄中的字段都可以拿來使用,比如當做查詢條件
select dwid,dwmc,dwdm,sjdw,dwlx,(select count(*) from kzjn_sys_dw where sjdw=m.dwid) cnt from kzjn_sys_dw m where 1=1 order by px asc
連表查詢
交叉連接
SELECT * FROM emp, dept;
結果集記錄數 = emp表記錄數 * dept表記錄數
笛卡爾積
等值連接
表連接時有關聯條件
SELECT e.ename, e.sal, d,dname FROM emp WHERE e.deptno = d.deptno;
內連接和外連接
內連接:連表時將相匹配的記錄查詢出來
SELECT 字段 FROM 表1, 表2... WHERE 連接條件1 AND 連接條件2...
SELECT 字段 FROM 表1 INNER JOIN 表2 ON 連接條件1 INNER JOIN 表3 ON 連接條件2...
外連接:匹不匹配的記錄都查詢出來
- 左外連接:LEFT JOIN 左表中匹不匹配的記錄都查詢出來
- 右外連接:RIGHT JOIN 右表中匹不匹配的記錄都查詢出來
- 全連接:FULL OUTER JOIN 兩邊表中匹不匹配的記錄都查詢出來
oracle中對左外連接和右外連接提供了簡化條件: (+),“釋放等號另一邊”。
右外連接:
SELECT e.ename, d.dname FROM emp e, dept d WHERE e.deptno (+)= d.deptno;
左外連接:
SELECT e.ename, d.dname FROM emp e, dept d WHERE e.deptno =(+) d.deptno;
自連接:
SELECT e.ename, m.ename FROM emp e, emp m WHERE e.mgr = m.empno;
子查詢
一個查詢作爲另一個查詢的條件。裏面的查詢–子查詢,外面的查詢–夫查詢。
SELECT * FROM emp WHERE job = (SELECT job FROM emp WHERE ename = 'SCOTT');
單行子查詢:>、 <、 =、 !=…
多行子查詢:IN、 NOT IN、 ANY、 ALL、
多列子查詢:
SELECT * FROM emp WHERE (deptno, job) = (SELECT deptno, job FROM emp WHERE ename = 'SCOTT');
子查詢結果集作爲臨時表,可用作表連接。
臨時表要起別名,若臨時表中字段有聚合函數,則那個字段必須起別名。
分頁查詢
對rownum進行條件過濾時,系統從第一條數據(rownum = 1)開始匹配,只要遇到不匹配的記錄就停止匹配。所以直接寫rownum > 2查詢不到任何記錄。
解決辦法:將rownum num,* 結果集作爲一張臨時表,此時num作爲臨時表的普通字段而不是系統自動添加的,所以可以使用任意條件過濾。
兩層過濾:
SELECT t.* FROM (SELECT rownum num, e.* FROM emp WHERE rownum <=5) t WHERE t.num >= 3;
三層過濾:
第一層: 條件過濾、連表、分組、排序等問題。
第二層: rownum <= 大值。
第三層: rownum(別名) >= 小值。
SELECT *
FROM
(SELECT rownum num, t.*
FROM (SELECT * FROM emp WHERE sal >= 2000 GROUP BY deptno HAVING COUNT(rowid) >= 2) t
WHERE rownum <= 5)
WHERE num >= 2;
合併查詢
縱向連接,兩張表字段數要匹配。
UNION: 合併結果後去重複。
UNION ALL: 合併結果後不去重複。
INTERSECT: 交集。
MINUS: 差集;
DDL語句
創建表:
CREATE TABLE
oracle中數據類型:
- 數值類型
NUMBER(precision, scale) 精度自動處理(四捨五入)
INTEGER - 字符類型
CHAR(length)、 VARCHAR(length)、 VARCHAR2(length)、 NCHAR(length)、 NVARCHAR(length)、 LONG - 其他類型
DATE、 TIMESTAMPE、 BLOB
添加數據
非空字段必須賦值
INSERT INTO 表名 VALUES (值1, 值2...)
--採用這種賦值方式,表中所有字段都要插入數據
INSERT INTO 表名 (字段1, 字段2...) VALUES (值1, 值2...)
INSERT INTO 表名 SELECT語句
INSERT INTO 表名(字段1, 字段...)SELECT 語句
注意: 先創建主表在創建子表,添加數據時先添加主表數據;刪除時先刪除子表數據或先刪除子表再刪除主表或主表。
字段特徵(約束):
PRIMARY KEY、 NOT NULL、 DEFAULT、 UNIQUE、 CHECK(自定義約束)、 外鍵、
NOT NULL和DEFAULE同時出現時,DEFAULT必須放在NOT NULL之前。
外鍵約束: 字段名 字段類型 REFERENCES 引用表名(字段)
表級約束: CONSTRAINT 約束名 PRIMARY KEY / CHECK()…
添加字段: ALTER TABLE 表名 ADD (字段名 字段類型 約束)
修改字段: ALTER TABLE 表名 MODIFY (字段名 字段類型 約束)
刪除字段: ALTER TABLE 表名 DROP COLUMN 字段名
ALTER TABLE 表名 DROP (字段1, 字段2…)
修改表名: RENAME 舊錶名 TO 新表名
複製表: CREATE TABLE 表名 AS SELECT查詢語句 字段約束不復制
CREATE TABLE 表名 (字段名1, 字段名2…) AS SELECT查詢語句
修改記錄: UPDATE 表名 SET 字段1 = 值1, 字段2 = 值2… [WHERE條件]
刪除記錄: DELETE FROM 表名 [WHERE條件]
截斷表: TRUNCATE TABLE 表名
刪除表和截斷表的異同:
相同點:都能達到清空表中數據的功能,表結構還在。
不同點:刪除表能定點刪除,刪除全部,截斷表只能刪除全部; 刪除表能通過ROLLBACK回滾事務,截斷表不能,但是截斷表的速度更快。
對錶中的操作:
增刪改: 會改變表中數據,返回結果是成功操作的行數
查詢:不會修改表中數據,返回結果是一個結果集。
事務
事務機制的特性通常被概括爲“ACID”原則:原子性、一致性、隔離性、持續性。
提交: COMMIT
回滾: ROLLBACK
什麼時候需要使用事務處理:執行多條SQL語句,希望要麼一次成功,要麼一次失敗(銀行轉賬問題)。
設置保存點: SAVEPOINT 保存點名
回滾到保存點: ROLLBACK TO [SAVEPOINT] 保存點名
DDL語句不能手動控制事務,DML語句可以。
視圖
視圖屬於一種數據對象,作用於表。
好處: 保護表中數據、 方便查詢
創建視圖:
CREATE [OR REPLACE] [{FORCE | NOFORCE}] VIEW view_name
[(alias_name[, alias_name…])] AS subquery
[{WITH CHECK OPTION | WITH READ ONLY} CONSTRANT constraint_name];
默認scott用戶不具備創建視圖的權限,需要登錄到管理員給scott賦予創建視圖的權利。
切換用戶:
CONN/CONNECT 用戶名/密碼[@數據庫實例 AS 身份];
查看當前登錄用戶: SHOW USER;
授予權限: GRANT 權限 TO 用戶
給scott用戶授予創建視圖的權限(由dba完成):
GRANT CREATE VIEW TO scott;
視圖和表的區別:
創建表時,結構數據佔用存儲空間。
視圖作用於表,創建視圖時將語句存儲在數據字典中,查詢視圖時現提取語句,執行查詢生成結果集。
可以對視圖進行增、刪、改操作,會影響原表(通過觸發器)。
WITH READ ONLY: 只讀視圖
WITH CHECK OPTION: 創建視圖後對數據進行DML操作時進行檢查,必須符合條件才能操作。
創建視圖時,聚合函數的字段必須起別名,不能有重名字段。
視圖不提供ALTER功能,修改視圖只能用CREATE OR REPLACE VIEW…來替換原視圖。
數據字典
數據字典是oracle數據庫的核心,用於描述數據庫及其對象。數據字典由一些列只讀表和視圖組成,這些表和視圖屬於sys用戶擁有,由oracle負責維護,用戶可以用SELECT語句進行訪問。
數據字典作用: 可以通過數據字典中的表及視圖獲取用戶的數據對象等信息(數據字典中的信息經過解密和其他處理後,以數據視圖的方式顯示給用戶)。
數據字典視圖:
- user_ : 當前用戶的對象信息
- all_ : 當前用戶可以訪問的對象信息
- dba_ : 所有對象包含的信息
序列
序列是一種數據庫項,可以生成整數序列。序列生成的整數通常用來填充數值主鍵。
創建序列
CREATE SEQUENCE sequence_name
[START WITH start_num]
[INCREAMENT BY incrent_num]
[MAXVALUE maximum_num | NOMAXVALUE]
[MINVALUE minimum_num | NOMINVALUE]
[CYCLE | NOCYCLE]
[CACHE | NOCACHE]
[ORDER | NOORDER]
序列生成一系列數字。序列中包含兩個“僞列”CURRVAL和NEXTVAL,分別用來獲取序列當前值和下一個值。
序列名.CURRVAL 序列名.NEXTVAL
在檢查序列當前值之前必須通過檢索序列下一個值對序列進行初始化。
在修改遞增序列的最大值是不能小於當前值,修改遞減的最小值不能大於當前值。
修改序列
ALTER SEQUENCE …;
序列的初始值不能改。
刪除序列
DROP SEQUENCE 序列名;
用戶
對象–> 表空間(TABLESPACE)–> 數據文件(DATAFILE)
創建用戶
CREATE USER user_name IDENTIFIED BY password
[DEFAULT TABLESPACE default_tablespace]
[TRMPORARY TABLESPACE temporary_tablespace]
權限:
系統權限:在系統級控制數據庫的存取和使用的機制。
系統權限:在用戶級控制數據庫的存取和使用的機制。
系統權限
常用的系統權限:CREATE SESSION、 CREATE SEQUENCE、 CREATE SYNONYM、 CREATE TABLE、 DROP TABLE、 CREATE PROCEDURE、 CREATE USER、 DROP USER、 CREATE VIEW、
授予系統權限:
GRANT 權限1, 權限2… TO 用戶 [WITH ADMIN OPTION];
收回系統權限(不聯動收回系統權限):
REVOKE 權限1, 權限2… FROM 用戶;
檢查授予用戶的系統特權:
SLECT * FROM user_sys_privs;
刪除用戶: DROP USER 用戶;
對象權限
常用對象特權: SELECT、 INSERT、 UPDATE、 DELETE、 EXECUTE、 INDEX、 REFERENCES、 ALTER、
授予對象權限:
GRANT 權限1, 權限2 ON 數據庫對象 TO 用戶;
回收對象權限:
REVOKE 權限1, 權限2 ON 數據庫 FROM 用戶;
檢查用戶已授予的對象權限:
user_tab_privs_made、 user_tab_privs_read
角色
角色就是相關權限的命令集合,使用命令的主要目的是爲了簡化權限的管理。
預定義角色: CONNECT、 RESOURCE、 DBA
自定義角色:一般由dba建立,如果用普通用戶建立,則需要具有CREATE ROLE的系統權限。
如果角色是公用的,可以採用不驗證的方式創建:
CREATE ROLE 角色名;
角色授權:
GRANT 系統權限 TO 角色;
GRANT 對象權限 ON 數據庫對象 TO 角色;
分配角色給某個用戶:
將角色從用戶收回(不會連帶收回角色):
REVOKE 角色名 FROM 用戶名;
GRANT 角色名 TO 用戶 [WITH ADMIN OPTION];
刪除角色:
DROP ROLE 角色名;
表空間
創建表空間:
CREATE TABLESPACE 表空間名
DATAFILE ‘文件路徑及文件名.dbf’ SIZE {K | M}
REUSE AUTOEXTEND ON NEXT 大小 MAXSIZE UNLIMITED;
路徑中包含爲創建的文件夾時,系統不會自定創建層級目錄,會報錯。
創建用戶時可以指定默認的表空間,當該用戶創建表時不指定表空間則使用默認表空間;若不指定用戶默認表空間則使用系統提供的users表空間。
修改表空間的大小:
ALTER DATABASE DATAFILE
’D:\DATA\mytablespace.bdf’
RESIZE 新大小;
刪除表空間:
DROP TABLESPACE 表空間;
索引
數據對象,提高搜索效率。
使用原則:
1、爲數據量大的表使用索引。
2、爲經常查詢操作的字段設置索引。
不要亂用索引,這只不當反而影響查詢效率。
創建B-樹索引:
CREATE [UNIQUE] INDEX index_name ON
table_name (column_name [, column_name…])
TABLESPACE table_sapce;
建表時有PRIMARY KEY、 UNIQUE的字段,系統自動爲這些字段加上唯一索引。
多列索引:
CREATE INDEX index_name ON myemp (ename, job);
--應用索引
... WHERE ename = '';
--應用索引
... WHERE ename = '' OR job = '';
--不應用索引
... WHERE job = '';
修改索引(只有重命名一種修改方法):
ALTER INDEX 索引名 RENAME TO 新名;
刪除索引:
DROP INDEX 索引名;
同義詞
同義詞(SYNONYM)是爲數據對象起的別名,可以是表、視圖、序列、過程、函數和包等。
同義詞有兩種:
- 公有同義詞:創建時必須有系統權限 CREATE PUBLIC SYNONYM。
- 私有同義詞:創建時必須有系統權限 CREATE PUBLIC SYNONYM。
訪問公有同義詞時只能使用同義詞,不能使用對象.同義詞;
訪問私有同義詞時同義詞所有者可以直接使用同義詞,也可以對象.同義詞,非所有者只能通過對象.同義詞訪問。
創建同義詞:
CREATE [PUBLIC] SYNONYM 同義詞名 FOR 數據對象;
可以爲一個數據對象設置多個同義詞,使用時可使用數據對象也可以使用同義詞,同義詞不能重名。
查看用戶擁有的同義詞:
SELECT object_name FROM user_objects WHERE object_type = 'SYNONYM';
用戶建立的私有同義詞自己有權限刪除,建立的公有同義詞只能由管理員刪除。
數據庫編程
PL/SQL(Procedual lanuage/SQL過程化語言)是oracle在標準SQL語言上的擴展。
塊(block)是pl/sql的基本編程單元,不會存儲在數據庫中,運行後就沒了。
塊結構:
[DECLARE
declare_statements
]
BEGIN
execute_statements
[EXCEPTION
exception_handing_statements
]
END;
/
打開服務器輸出:
SET SERVEROUTPUT ON;
變量賦值:
變量名 數據類型 {:= 初值 | DEFAULT 初值};
SELECT 字段 INTO 變量 FROM 表名 WHERE 條件;
v_ename emp.ename %TYPE;
定義常量:
常量名 CONSTANT 數據類型 {:= 初始值 | DEAUFT 初始值};
定義常量時必須賦值,並且不能重新賦值。
異常處理:
EXCEPTION
WHEN 異常名稱1 THEN
異常處理1
WHEN 異常名稱2 THEN
異常處理2
條件邏輯
IF condition1 THEN
statements1
ELSIF condition1 THEN
statements2
ELSE
statements3
END IF;
簡單循環:
LOOP
statements
END LOOP;
WHILE循環:
WHILE condition LOOP
statements
END LOOP;
FOR循環:
FOR loop_variable IN [REVERSE] lower_bound.. upper_bound LOOP
statemens
END LOOP
過程
過程包含一組SQL和PL/SQL語句。過程可將業務邏輯集中在數據庫中,任何能夠訪問數據庫的程序都可以使用過程。
創建過程:
CREATE [OR REPLACE] PROCEDURE procedure_name
[(parameter_name[IN | OUT | IN OUT] type [,…])] {IS | AS}
BEGIN
procedure_body
END[procedure_name];
/
調用過程:
EXECUTE / CALL procedure_name(parameter);
在塊裏調用過程時,不能使用EXEC / CALL ,直接寫名字即可。
特殊情況:既是IN又是OUT參數,必須有初始值。
函數
函數用於返回特定的數據,當建立函數時,在函數頭部必須包含return字句。而在函數體內必須包含return語句返回數據。
創建函數:
CREATE [OR REPLACE] FUNCTION function_name
[(paremeter_name[IN | OUT | IN OUT] type [,…])]
RETURN type
{IS | AS}
BEGIN
function_body
END [function_name];
/
調用函數:和使用系統函數一樣。
刪除函數:
DROP FUNCTION 函數名;
過程與函數:
相同點:都是oracle數據對象,作用都是事先某些功能。
不同點:過程 參數IN、OUT、IN OUT(可以傳入參數、傳出參數),參數可有多個。在程序中、PL/SQL塊中實現調用。
函數: 必須有且只有一個返回值。可以直接在SELECT字句中調用函數。
數據庫的設計
良好的數據:庫設計節省數據存儲空間,能夠保證數據的完整性、方便數據應用系統的開發。
糟糕的數據庫設計:數據冗餘,浪費存儲空間、內存空間浪費、數據更新和插入的異常。
標識對象(實體-Entity)、實體的屬性(Attribute)、標識對象之間的關係(Relationship)、E-R實體關係圖。
三大範式:
第一範式(確保每列的原子性):每列都是不可再分的最小數據單元。 1NF
第二範式(每個表只描述一件事情):滿足1NF,並且除主鍵以外的列,都依賴該主鍵(不能只依賴主鍵的一部分)。 2NF
第三範式(字段和主鍵直接相關):滿足2NF,並且除主鍵以外的其他列都不傳遞依賴該主鍵。
解決方法記錄:
查詢不到記錄希望返回0
直接使用NVL函數查詢時,有這條記錄但是某一字段爲null時才返回0,如果查詢不到記錄沒有返回數據。
SELECT NVL(field, 0) FROM TABLE WHERE condition...
解決辦法:
SELECT NVL(SUM(field), 0) FROM TABLE WHERE condition...