Oracle基础语法 #
一、SQL语句分类 #
1.1 SQL语句类型 #
text
SQL语句分类
├── DDL(数据定义语言)
│ ├── CREATE - 创建对象
│ ├── ALTER - 修改对象
│ ├── DROP - 删除对象
│ ├── TRUNCATE - 截断表
│ └── RENAME - 重命名
├── DML(数据操作语言)
│ ├── SELECT - 查询数据
│ ├── INSERT - 插入数据
│ ├── UPDATE - 更新数据
│ └── DELETE - 删除数据
├── DCL(数据控制语言)
│ ├── GRANT - 授予权限
│ └── REVOKE - 撤销权限
├── TCL(事务控制语言)
│ ├── COMMIT - 提交事务
│ ├── ROLLBACK - 回滚事务
│ └── SAVEPOINT - 设置保存点
└── DQL(数据查询语言)
└── SELECT - 查询语句
1.2 语句执行 #
sql
-- SQL语句以分号结尾
SELECT * FROM employees;
-- PL/SQL块以斜杠结尾
BEGIN
DBMS_OUTPUT.PUT_LINE('Hello Oracle');
END;
/
二、注释 #
2.1 单行注释 #
sql
-- 这是单行注释
SELECT employee_id, last_name FROM employees;
SELECT employee_id, -- 员工ID
last_name -- 姓氏
FROM employees;
2.2 多行注释 #
sql
/*
* 这是多行注释
* 可以跨越多行
* 用于详细说明
*/
SELECT * FROM employees;
/*
查询所有员工信息
包括员工ID、姓名、部门
*/
SELECT employee_id, first_name, last_name, department_id
FROM employees;
2.3 注释最佳实践 #
sql
-- 好的注释示例
-- 查询薪资大于10000的员工
-- 按部门分组统计人数和平均薪资
SELECT
department_id,
COUNT(*) AS employee_count,
AVG(salary) AS avg_salary
FROM employees
WHERE salary > 10000
GROUP BY department_id
ORDER BY avg_salary DESC;
-- 避免无意义的注释
SELECT * FROM employees; -- 查询所有员工(这种注释是多余的)
三、标识符 #
3.1 标识符规则 #
text
标识符命名规则:
├── 必须以字母开头
├── 可包含字母、数字、下划线(_)、美元符号($)
├── 长度不超过30个字符(12c R2后支持128字符)
├── 不能是Oracle保留字
├── 不区分大小写(默认)
└── 不能包含空格或特殊字符
3.2 命名示例 #
sql
-- 合法的标识符
employees
employee_id
first_name
salary$
dept_2024
-- 不合法的标识符
123employees -- 以数字开头
employee-id -- 包含连字符
employee name -- 包含空格
select -- 保留字
3.3 引用标识符 #
sql
-- 使用双引号可以突破命名规则
-- 包含特殊字符
CREATE TABLE "my table" (
id NUMBER
);
-- 区分大小写
CREATE TABLE "Employees" (
id NUMBER
);
-- 使用保留字
CREATE TABLE "table" (
id NUMBER
);
-- 查询时也需要使用双引号
SELECT * FROM "my table";
SELECT * FROM "Employees"; -- 必须完全匹配大小写
四、关键字与保留字 #
4.1 保留字列表 #
sql
-- 常见保留字(不能用作标识符)
SELECT, FROM, WHERE, AND, OR, NOT
INSERT, UPDATE, DELETE, CREATE, ALTER, DROP
TABLE, INDEX, VIEW, PROCEDURE, FUNCTION
NUMBER, VARCHAR2, DATE, TIMESTAMP
PRIMARY, FOREIGN, KEY, UNIQUE, CHECK
GRANT, REVOKE, COMMIT, ROLLBACK
4.2 查看保留字 #
sql
-- 查看所有保留字
SELECT * FROM V$RESERVED_WORDS ORDER BY KEYWORD;
-- 查看是否为保留字
SELECT KEYWORD, RESERVED
FROM V$RESERVED_WORDS
WHERE KEYWORD = 'SELECT';
4.3 关键字使用建议 #
sql
-- 不推荐:使用保留字作为列名
CREATE TABLE test (
select NUMBER, -- 不推荐
from VARCHAR2(50) -- 不推荐
);
-- 推荐:添加前缀或后缀
CREATE TABLE test (
select_type NUMBER,
from_location VARCHAR2(50)
);
-- 如果必须使用,需要双引号
CREATE TABLE test (
"SELECT" NUMBER,
"FROM" VARCHAR2(50)
);
五、命名规范 #
5.1 表命名规范 #
sql
-- 表名使用复数形式
employees -- 推荐
employee -- 不推荐
-- 使用下划线分隔单词
order_items -- 推荐
OrderItems -- 不推荐
order-items -- 错误
-- 添加业务前缀
hr_employees
fin_accounts
inv_products
-- 示例
CREATE TABLE hr_employees (
employee_id NUMBER PRIMARY KEY,
first_name VARCHAR2(50),
last_name VARCHAR2(50)
);
5.2 列命名规范 #
sql
-- 主键命名:表名_id 或 id
employee_id
id
-- 外键命名:关联表名_id
department_id
manager_id
-- 布尔类型:is_xxx 或 has_xxx
is_active
is_deleted
has_permission
-- 日期类型:xxx_date 或 xxx_time
create_date
update_time
hire_date
-- 示例
CREATE TABLE orders (
order_id NUMBER PRIMARY KEY,
customer_id NUMBER,
order_date DATE,
total_amount NUMBER(10,2),
is_paid NUMBER(1) DEFAULT 0,
create_time TIMESTAMP DEFAULT SYSTIMESTAMP
);
5.3 索引命名规范 #
sql
-- 索引命名:idx_表名_列名
CREATE INDEX idx_employees_last_name ON employees(last_name);
-- 唯一索引:uk_表名_列名
CREATE UNIQUE INDEX uk_employees_email ON employees(email);
-- 复合索引:idx_表名_列名1_列名2
CREATE INDEX idx_orders_customer_date ON orders(customer_id, order_date);
-- 主键索引:pk_表名
ALTER TABLE employees ADD CONSTRAINT pk_employees PRIMARY KEY (employee_id);
-- 外键索引:fk_表名_关联表名
ALTER TABLE employees ADD CONSTRAINT fk_employees_departments
FOREIGN KEY (department_id) REFERENCES departments(department_id);
5.4 其他对象命名规范 #
sql
-- 序列:seq_表名 或 seq_表名_id
CREATE SEQUENCE seq_employees START WITH 1 INCREMENT BY 1;
-- 视图:v_视图名
CREATE VIEW v_employee_details AS
SELECT * FROM employees;
-- 存储过程:sp_过程名 或 proc_过程名
CREATE PROCEDURE sp_update_salary(p_emp_id NUMBER) AS
BEGIN
NULL;
END;
/
-- 函数:fn_函数名 或 func_函数名
CREATE FUNCTION fn_get_salary(p_emp_id NUMBER) RETURN NUMBER AS
BEGIN
RETURN 0;
END;
/
-- 触发器:trg_表名_操作
CREATE TRIGGER trg_employees_insert
BEFORE INSERT ON employees
BEGIN
NULL;
END;
/
-- 包:pkg_包名
CREATE PACKAGE pkg_employee AS
PROCEDURE update_salary(p_emp_id NUMBER);
END;
/
六、数据类型简述 #
6.1 常用数据类型 #
sql
-- 数值类型
NUMBER -- 任意精度数值
NUMBER(p) -- 整数,p位精度
NUMBER(p,s) -- 定点数,p位精度,s位小数
INTEGER -- 整数
FLOAT -- 浮点数
-- 字符类型
CHAR(n) -- 定长字符串
VARCHAR2(n) -- 变长字符串
NCHAR(n) -- 定长Unicode字符串
NVARCHAR2(n) -- 变长Unicode字符串
CLOB -- 大文本
-- 日期时间类型
DATE -- 日期时间
TIMESTAMP -- 时间戳
TIMESTAMP WITH TIME ZONE -- 带时区时间戳
-- 其他类型
BLOB -- 二进制大对象
XMLTYPE -- XML数据
JSON -- JSON数据(21c+)
6.2 数据类型示例 #
sql
CREATE TABLE data_type_examples (
-- 数值类型
id NUMBER PRIMARY KEY,
age NUMBER(3),
salary NUMBER(10,2),
-- 字符类型
code CHAR(10),
name VARCHAR2(100),
description CLOB,
-- 日期类型
birth_date DATE,
create_time TIMESTAMP,
-- 其他类型
photo BLOB
);
七、运算符 #
7.1 算术运算符 #
sql
-- 加减乘除
SELECT 10 + 5 FROM DUAL; -- 15
SELECT 10 - 5 FROM DUAL; -- 5
SELECT 10 * 5 FROM DUAL; -- 50
SELECT 10 / 5 FROM DUAL; -- 2
-- 实际应用
SELECT
employee_id,
salary,
salary * 12 AS annual_salary,
salary + 1000 AS new_salary
FROM employees;
7.2 比较运算符 #
sql
-- 等于、不等于
SELECT * FROM employees WHERE salary = 10000;
SELECT * FROM employees WHERE salary != 10000;
SELECT * FROM employees WHERE salary <> 10000;
-- 大于、小于
SELECT * FROM employees WHERE salary > 10000;
SELECT * FROM employees WHERE salary < 10000;
SELECT * FROM employees WHERE salary >= 10000;
SELECT * FROM employees WHERE salary <= 10000;
-- BETWEEN...AND
SELECT * FROM employees WHERE salary BETWEEN 5000 AND 10000;
-- IN
SELECT * FROM employees WHERE department_id IN (10, 20, 30);
-- LIKE
SELECT * FROM employees WHERE last_name LIKE 'S%';
-- IS NULL
SELECT * FROM employees WHERE manager_id IS NULL;
7.3 逻辑运算符 #
sql
-- AND
SELECT * FROM employees
WHERE salary > 10000 AND department_id = 10;
-- OR
SELECT * FROM employees
WHERE salary > 10000 OR department_id = 10;
-- NOT
SELECT * FROM employees
WHERE NOT (salary > 10000);
-- 组合使用
SELECT * FROM employees
WHERE (salary > 10000 OR department_id = 10)
AND hire_date > TO_DATE('2020-01-01', 'YYYY-MM-DD');
7.4 字符串连接运算符 #
sql
-- 使用 || 连接字符串
SELECT first_name || ' ' || last_name AS full_name
FROM employees;
-- 使用 CONCAT 函数
SELECT CONCAT(first_name, last_name) AS full_name
FROM employees;
-- 多个字符串连接
SELECT first_name || ' ' || last_name || ' - ' || job_id AS employee_info
FROM employees;
八、NULL值处理 #
8.1 NULL值特点 #
sql
-- NULL表示未知或缺失的值
-- NULL不等于0或空字符串
-- NULL参与运算结果为NULL
SELECT NULL + 10 FROM DUAL; -- NULL
SELECT NULL * 10 FROM DUAL; -- NULL
SELECT NULL || 'text' FROM DUAL; -- text(字符串连接例外)
-- NULL比较
SELECT * FROM employees WHERE manager_id = NULL; -- 错误,不会返回结果
SELECT * FROM employees WHERE manager_id IS NULL; -- 正确
8.2 NULL函数 #
sql
-- NVL函数:如果为NULL则返回默认值
SELECT NVL(commission_pct, 0) FROM employees;
-- NVL2函数:根据是否为NULL返回不同值
SELECT NVL2(commission_pct, '有提成', '无提成') FROM employees;
-- COALESCE函数:返回第一个非NULL值
SELECT COALESCE(manager_id, department_id, 0) FROM employees;
-- NULLIF函数:如果相等则返回NULL
SELECT NULLIF(salary, 0) FROM employees;
-- LNNVL函数:条件取反(包含NULL)
SELECT * FROM employees WHERE LNNVL(salary > 10000);
九、DUAL表 #
9.1 DUAL表介绍 #
sql
-- DUAL是Oracle提供的单行单列表
-- 常用于计算、获取系统信息等
SELECT * FROM DUAL;
D
-
X
9.2 DUAL表使用 #
sql
-- 计算表达式
SELECT 1 + 1 FROM DUAL;
-- 获取系统日期
SELECT SYSDATE FROM DUAL;
-- 获取当前用户
SELECT USER FROM DUAL;
-- 获取序列值
SELECT seq_employees.NEXTVAL FROM DUAL;
-- 调用函数
SELECT TO_CHAR(SYSDATE, 'YYYY-MM-DD HH24:MI:SS') FROM DUAL;
-- 类型转换测试
SELECT TO_DATE('2024-01-15', 'YYYY-MM-DD') FROM DUAL;
十、SQL语句格式化 #
10.1 格式化建议 #
sql
-- 关键字大写
SELECT employee_id, last_name, salary
FROM employees
WHERE salary > 10000
ORDER BY salary DESC;
-- 缩进对齐
SELECT
employee_id,
first_name,
last_name,
salary,
department_id
FROM
employees
WHERE
salary > 10000
AND department_id IN (10, 20, 30)
ORDER BY
salary DESC,
employee_id ASC;
-- 每个子句独占一行
SELECT *
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE e.salary > 10000
ORDER BY e.salary DESC;
10.2 代码可读性 #
sql
-- 使用表别名
SELECT
e.employee_id,
e.first_name,
e.last_name,
d.department_name
FROM
employees e
JOIN
departments d ON e.department_id = d.department_id;
-- 使用列别名
SELECT
employee_id AS "员工ID",
first_name || ' ' || last_name AS "姓名",
salary AS "薪资"
FROM employees;
-- 复杂条件使用括号
SELECT *
FROM employees
WHERE (department_id = 10 OR department_id = 20)
AND salary > (SELECT AVG(salary) FROM employees);
十一、总结 #
语法要点总结:
| 类别 | 要点 |
|---|---|
| 注释 | 单行 – 多行 /* */ |
| 标识符 | 字母开头,30字符内 |
| 命名规范 | 表复数、列单数、加前缀 |
| 运算符 | 算术、比较、逻辑、连接 |
| NULL处理 | IS NULL、NVL、COALESCE |
| 格式化 | 关键字大写、合理缩进 |
下一步,让我们学习Oracle数据类型!
最后更新:2026-03-27