SQL語言處理
本章,我們將會重點探討SQL語言基礎,學習用SQL進行數據庫的數據增加、刪除和修改等操作。另外請注意本章的SQL語法基于Oracle數據庫的PL/SQL語法。
表的數據操作
DML 可以在下列條件下執行:
- 向表中插入數據
- 修改現存數據
- 刪除現存數據
新增
使用 INSERT
語句向表中插入數據。
處理語法
INSERT INTO table [(column [, column...])]
VALUES (value [, value...]);
--使用這種語法一次只能向表中插入一條數據。
- 為每一列添加一個新值。
- 按列的默認順序列出各個列的值。
- 在 INSERT 子句中隨意列出列名和他們的值。
- 字符和日期型數據應包含在單引號中。
插入空值
隱式方式: 在列名表中省略該列的值。
INSERT INTO HR.DEPARTMENTS
(DEPARTMENT_ID, DEPARTMENT_NAME)
VALUES
(330, 'Purchasing');
--1 row created.
顯示方式: 在VALUES 子句中指定空值。
INSERT INTO HR.DEPARTMENTS VALUES (400, 'Finance', NULL, NULL);
--1 row created.
插入系統時間
SYSDATE 記錄當前系統的日期和時間。
INSERT INTO HR.EMPLOYEES
(EMPLOYEE_ID,
FIRST_NAME,
LAST_NAME,
EMAIL,
PHONE_NUMBER,
HIRE_DATE,
JOB_ID,
SALARY,
COMMISSION_PCT,
MANAGER_ID,
DEPARTMENT_ID)
VALUES
(113,
'Louis',
'Popp',
'LPOPP',
'515.124.4567',
SYSDATE,
'AC_ACCOUNT',
6900,
NULL,
205,
100);
--1 row created.
INSERT INTO HR.EMPLOYEES
VALUES
(114,
'Den',
'Raphealy',
'DRAPHEAL',
'515.127.4561',
TO_DATE('FEB 3, 1999', 'MON DD, YYYY'),
'AC_ACCOUNT',
11000,
NULL,
100,
30);
--1 row created.
插入其他表的數據
INSERT INTO SALES_REPS
(ID, NAME, SALARY, COMMISSION_PCT)
SELECT EMPLOYEE_ID, LAST_NAME, SALARY, COMMISSION_PCT
FROM EMPLOYEES
WHERE JOB_ID LIKE '%REP%';
--4 rows created.
更新
使用 UPDATE 語句更新數據。
語法示例
UPDATE table
SET column = value [, column = value, ...]
[WHERE condition];
--可以一次更新多條數據
使用 WHERE 子句指定需要更新的數據。
UPDATE HR.EMPLOYEES
SET DEPARTMENT_ID = 70
WHERE EMPLOYEE_ID = 113;
--1 row updated.
--如果省略WHERE子句,則表中的所有數據都將被更新。
在UPDATE語句中使用子查詢
UPDATE HR.EMPLOYEES
SET JOB_ID =
(SELECT JOB_ID FROM HR.EMPLOYEES WHERE EMPLOYEE_ID = 205),
SALARY =
(SELECT SALARY FROM HR.EMPLOYEES WHERE EMPLOYEE_ID = 205)
WHERE EMPLOYEE_ID = 114;
--1 row updated.
--更新 114號員工的工作和工資使其與 205號員工相同
UPDATE COPY_EMP
SET DEPARTMENT_ID =
(SELECT DEPARTMENT_ID FROM HR.EMPLOYEES WHERE EMPLOYEE_ID = 100)
WHERE JOB_ID = (SELECT JOB_ID FROM HR.EMPLOYEES WHERE EMPLOYEE_ID = 200);
--1 row updated.
--在 UPDATE 中使用子查詢,使更新基于另一個表中的數據。
刪除
使用 DELETE 語句從表中刪除數據。
語法示例
DELETE [FROM] table
[WHERE condition];
使用WHERE 子句指定刪除的記錄。
DELETE FROM HR.departments
WHERE department_name = 'Finance';
--1 row deleted.
--如果省略WHERE子句,則表中的全部數據將被刪除。
在 DELETE 中使用子查詢
DELETE FROM HR.employees
WHERE department_id =
(SELECT department_id
FROM HR.departments
WHERE department_name LIKE '%Public%');
--1 row deleted.
--在 DELETE 中使用子查詢,使刪除基于另一個表中的數據。
高級函數處理
NVL & NVL2
NVL
將空值轉換成一個已知的值:可以使用的數據類型有日期、字符、數字。
函數的一般形式:
NVL(commission_pct, 0)
NVL(hire_date, SYSDATE)
NVL(job_id, 'No Job Yet')
使用示例
SELECT last_name, salary, NVL(commission_pct, 0),
(salary*12) + (salary*12*NVL(commission_pct, 0)) AN_SAL
FROM hr.employees;
--NVL(commission_pct, 0):若commission_pct是NULL,那么取0作為它的值
NVL2
SELECT last_name, salary, commission_pct,
NVL2(commission_pct, 'SAL+COMM', 'SAL') income
FROM hr.employees WHERE department_id IN (50, 80);
--NVL2(commission_pct, 'SAL+COMM', 'SAL'):若commission_pct不是NULL,就取SAL+COMM,否則取SAL
COALESCE
COALESCE 與 NVL 相比的優點在于 COALESCE 可以同時處理交替的多個值。
SELECT last_name,
COALESCE(commission_pct, salary, 10) comm
FROM employees
ORDER BY commission_pct;
-- COALESCE(commission_pct, salary, 10)是返回第一個非空的值,若commission_pct為NULL就返回salary,若salary也為NULL,就返回10
在 SQL 語句中使用IF-THEN-ELSE 邏輯。
使用兩種方法:CASE 表達式DECODE 函數
DECODE
使用語法
DECODE(col|expression, search1, result1
[, search2, result2,...,]
[, default])
使用示例
SELECT last_name, job_id, salary,
DECODE(job_id, 'IT_PROG', 1.10*salary,
'ST_CLERK', 1.15*salary,
'SA_REP', 1.20*salary,
salary)
REVISED_SALARY
FROM employees;
CASE表達式
使用語法
CASE expr WHEN comparison_expr1 THEN return_expr1
[WHEN comparison_expr2 THEN return_expr2
WHEN comparison_exprn THEN return_exprn
ELSE else_expr]
END
使用示例
SELECT last_name, job_id, salary,
CASE job_id WHEN 'IT_PROG' THEN 1.10*salary
WHEN 'ST_CLERK' THEN 1.15*salary
WHEN 'SA_REP' THEN 1.20*salary
ELSE salary END "REVISED_SALARY"
FROM hr.employees;
--根據JOB_ID的值,對工資做相應的處理
事務
- 以第一個 DML 語句的執行作為開始
- 以下面的其中之一作為結束:
- COMMIT 或 ROLLBACK 語句
- DDL 或 DCL 語句(自動提交)
- 用戶會話正常結束系統異常終了
使用COMMIT
和 ROLLBACK
語句,我們可以:
- 確保數據完整性。
- 數據改變被提交之前預覽。
- 將邏輯上相關的操作分組。
視圖
- 控制數據訪問
- 簡化查詢
- 數據獨立性
- 避免重復訪問相同的數據
視圖創建
語法示例
CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view
[(alias[, alias]...)]
AS subquery
[WITH CHECK OPTION [CONSTRAINT constraint]]
[WITH READ ONLY [CONSTRAINT constraint]];
創建視圖
CREATE VIEW empvu80
AS SELECT employee_id, last_name, salary
FROM hr.employees
WHERE department_id = 80;
--View created.
創建視圖時在子查詢中給列定義別名
CREATE VIEW salvu50
AS SELECT employee_id ID_NUMBER, last_name NAME,
salary*12 ANN_SALARY
FROM hr.employees
WHERE department_id = 50;
--View created.
--在選擇視圖中的列時應使用別名
視圖修改
使用CREATE OR REPLACE VIEW 子句修改視圖
CREATE OR REPLACE VIEW empvu80
(id_number, name, sal, department_id)
AS SELECT employee_id, first_name || ' ' || last_name,
salary, department_id
FROM hr.employees
WHERE department_id = 80;
--View created.
--CREATE VIEW 子句中各列的別名應和子查詢中各列相對應
刪除視圖
刪除視圖只是刪除視圖的定義,并不會刪除基表的數據
刪除語法
DROP VIEW view;
--刪除視圖view
存儲過程
存儲過程,Procedure,是一組為了完成特定功能的SQL語句集合,經編譯后存儲在數據庫中,用戶通過指定存儲過程的名稱并給出參數來執行。
存儲過程中可以包含邏輯控制語句和數據操縱語句,它可以接受參數、輸出參數、返回單個或多個結果集以及返回值。
由于存儲過程在創建時即在數據庫服務器上進行了編譯并存儲在數據庫中,所以存儲過程運行要比單個的SQL語句塊要快。同時由于在調用時只需用提供存儲過程名和必要的參數信息,所以在一定程度上也可以減少網絡流量、簡單網絡負擔。
基本語法
CREATE OR REPLACE PROCEDURE 存儲過程名字
(
參數1 IN NUMBER,
參數2 IN NUMBER
) IS
變量1 INTEGER :=0;
變量2 DATE;
BEGIN
[執行語句]
END
使用示例
創建一個表Student,并插入一百萬條記錄,在奇數的時候插入Tom記錄,偶數的時候插入Lucy記錄。使用存儲過程來實現。
Create Table student (
s_id Number(8),
s_name Varchar2(20),
s_sex Char(2)
);
--創建表student
Create Or Replace Procedure p_insert_data
AS
Begin
For i In 1..1000000 Loop
If i Mod 2 = 1 Then
Insert into student Values(i, 'Tom', '男');
Else
Insert into student Values(i, 'Lucy', '女');
End If;
End Loop;
Commit;
dbms_output.put_line('插入數據完成!');
End;
--創建存儲過程
調用存儲過程
CALL p_insert_data();