1、控制用户权限
数据库安全性:
- 系统安全性
- 数据安全性
系统权限–100+种有效的权限
对象权限
DBA 使用 CREATE USER 语句创建用户:
CREATE USER user
IDENTIFIED BY password;
用户创建之后, DBA 会赋予用户一些系统权限:
GRANT privilege [, privilege...]
TO user [, user| role, PUBLIC...];
以应用程序开发者为例, 一般具有下列系统权限:
- CREATE SESSION(创建会话)
- CREATE TABLE(创建表)
- CREATE SEQUENCE(创建序列)
- CREATE VIEW(创建视图)
- CREATE PROCEDURE(创建过程)
创建用户表空间: 用户拥有create table权限之外,还需要分配相应的表空间才可开辟存储空间用于创建的表。
ALTER USER atguigu01 QUOTA UNLIMITED
ON users
创建角色:create role name;
(通常由DBA完成)
为角色赋予权限:grant create table,create view to name;
将角色赋予用户:grant name TO anla, betty;
修改密码:ALTER USER scott IDENTIFIED BY lion;
对象权限:
不同的对象具有不同的对象权限
对象的拥有者拥有所有权限
对象的拥有者可以向外分配权限
分配表查询权限:
GRANT select
ON employees
TO sue, rich;
分配表各个列的更新权限:
GRANT update
ON scott.departments
TO atguigu
WITH GRANT OPTION 使用户同样具有分配权限的权利:
GRANT select, insert
ON departments
TO scott
WITH GRANT OPTION;
查询权限分配情况:
收回对象权限:
- 使用 REVOKE 语句收回权限
- 使用 WITH GRANT OPTION 子句所分配的权限同样被收回
REVOKE {privilege [, privilege...]|ALL}
ON object
FROM {
user[, user...]|role|PUBLIC}
[CASCADE CONSTRAINTS];
2、set运算符
UNION 操作符返回两个查询的结果集的并集。
UNION ALL 操作符返回两个查询的结果集的并集。对于两个结果集的重复部分,不去重。
INTERSECT 操作符返回两个结果集的交集。
MINUS操作符:返回两个结果集的差集。
注意:
- 系统将第一个查询的列名显示在输出中
- 除 UNION ALL之外,系统自动按照第一个查询中的第一个列的升序排列
使用相对位置排序举例
COLUMN a_dummy NOPRINT
SELECT 'sing' AS "My dream", 3 a_dummy
FROM dual
UNION
SELECT 'I`d like to teach', 1
FROM dual
UNION
SELECT 'the world to', 2
FROM dual
ORDER BY 2;
结果如图:
3、高级子查询
子查询是嵌套在 SQL 语句中的另一个SELECT 语句。
- 子查询 (内查询) 在主查询执行之前执行
- 主查询(外查询)使用子查询的结果
多列子查询:主查询与子查询返回的多个列进行比较。
WHERE (MANAGER_ID, DEPARTMENT_ID) IN ...
多列子查询中的比较分为两种:
- 成对比较
- 不成对比较
成对比较举例:
SELECT employee_id, manager_id, department_id
FROM employees
WHERE (manager_id, department_id) IN
(SELECT manager_id, department_id
FROM employees
WHERE employee_id IN (141,174))
AND employee_id NOT IN (141,174);
不成对比较举例:
SELECT employee_id, manager_id, department_id
FROM employees
WHERE manager_id IN (SELECT manager_id
FROM employees
WHERE employee_id IN (174,141))
AND department_id IN (SELECT department_id
FROM employees
WHERE employee_id IN (174,141))
AND employee_id NOT IN(174,141);
在 FROM 子句中使用子查询,作表可以,作判断元素也可以。
单列子查询:在一行中只返回一列的子查询。
- Oracle8i 只在下列情况下可以使用, 例如:
- SELECT 语句 (FROM 和 WHERE 子句)
- INSERT 语句中的VALUES列表中
- Oracle9i中单列子查询表达式可在下列情况下使用:
- DECODE 和 CASE
- SELECT 中除 GROUP BY 子句以外的所有子句中
举例:
- 在 CASE 表达式中使用单列子查询
SELECT employee_id, last_name,
(CASE
WHEN department_id =
(SELECT department_id FROM departments
WHERE location_id = 1800)
THEN 'Canada' ELSE 'USA' END) location
FROM employees;
- 在 ORDER BY 子句中使用单列子查询
SELECT employee_id, last_name
FROM employees e
ORDER BY (SELECT department_name
FROM departments d
WHERE e.department_id = d.department_id);
相关子查询:按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。子查询中使用主查询中的列
EXISTS 操作符检查在子查询中是否存在满足条件的行
- 如果在子查询中存在满足条件的行:
- 不在子查询中继续查找
- 条件返回 TRUE
- 如果在子查询中不存在满足条件的行:
- 条件返回 FALSE
- 继续在子查询中查找
相关更新
UPDATE table1 alias1
SET column = (SELECT expression
FROM table2 alias2
WHERE alias1.column =
alias2.column);
使用相关子查询依据一个表中的数据更新另一个表的数据。
相关删除
DELETE FROM table1 alias1
WHERE column operator
(SELECT expression
FROM table2 alias2
WHERE alias1.column = alias2.column);
WITH 子句
- 使用 WITH 子句, 可以避免在 SELECT 语句中重复书写相同的语句块
- WITH 子句将该子句中的语句块执行一次并存储到用户的临时表空间中
- 使用 WITH 子句可以提高查询效率
场景:查询公司中各部门的总工资大于公司中各部门的平均总工资的部门信息
WITH dept_costs AS (
SELECT d.department_name, SUM(e.salary) AS dept_total
FROM employees e, departments d
WHERE e.department_id = d.department_id
GROUP BY d.department_name),
avg_cost AS (
SELECT SUM(dept_total)/COUNT(*) AS dept_avg
FROM dept_costs)
SELECT *
FROM dept_costs
WHERE dept_total >
(SELECT dept_avg
FROM avg_cost)
ORDER BY department_name;