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();