在Oracle数据库管理系统中,DDL(Data Definition Language,数据定义语言)和DML(Data Manipulation Language,数据操纵语言)是两类核心的SQL语句,它们分别承担着数据库结构管理和数据操作的不同职责。理解这两类语言的区别与联系,是掌握Oracle数据库开发与管理的基础。
一、DDL:数据库结构的定义者
DDL是用于定义和管理数据库对象结构的SQL语句集合,其主要作用包括创建、修改和删除数据库中的表、视图、索引、存储过程等对象。DDL语句的特点是执行后立即生效,且通常无法回滚(事务中的DDL会隐式提交)。
1.1 核心DDL语句
(1)CREATE:创建数据库对象
创建表是最基础的DDL操作,例如:
CREATE TABLE employees (
emp_id NUMBER PRIMARY KEY,
emp_name VARCHAR2(100) NOT NULL,
hire_date DATE DEFAULT SYSDATE,
salary NUMBER(10,2) CHECK (salary > 0)
);
此语句定义了一个包含主键、非空约束、默认值和检查约束的表结构。
(2)ALTER:修改对象结构
ALTER语句用于修改已有对象的结构,例如添加列:
ALTER TABLE employees
ADD COLUMN department_id NUMBER REFERENCES departments(dept_id);
或修改列数据类型:
ALTER TABLE employees
MODIFY COLUMN emp_name VARCHAR2(150);
(3)DROP:删除对象
删除表的操作需谨慎执行:
DROP TABLE employees CASCADE CONSTRAINTS;
其中CASCADE CONSTRAINTS选项会同时删除与该表相关的约束。
(4)TRUNCATE:清空表数据
与DELETE不同,TRUNCATE是DDL操作:
TRUNCATE TABLE temp_data;
它会快速删除表中所有数据,且不触发DELETE触发器。
1.2 DDL执行特性
1. 隐式提交:DDL语句执行后会自动提交当前事务
2. 不可回滚:执行后的DDL操作无法通过ROLLBACK撤销
3. 权限要求:执行DDL需要相应的对象创建权限(如CREATE TABLE)
4. 依赖管理:Oracle会自动维护对象间的依赖关系,如删除被外键引用的表会失败
二、DML:数据的操作者
DML是用于操作数据库表中数据的SQL语句,主要包括INSERT、UPDATE、DELETE和MERGE(Oracle特有)。与DDL不同,DML操作属于事务控制范围,可以回滚。
2.1 基础DML操作
(1)INSERT:插入数据
基本插入语法:
INSERT INTO employees (emp_id, emp_name, hire_date)
VALUES (101, '张三', TO_DATE('2023-01-15', 'YYYY-MM-DD'));
批量插入示例:
INSERT INTO sales_data
SELECT product_id, sale_date, quantity
FROM temp_sales
WHERE sale_date > SYSDATE-30;
(2)UPDATE:修改数据
条件更新示例:
UPDATE employees
SET salary = salary * 1.1,
last_updated = SYSDATE
WHERE department_id = 10;
使用子查询更新:
UPDATE products p
SET p.price = (SELECT AVG(price) FROM products WHERE category = p.category)
WHERE p.discontinued = 'N';
(3)DELETE:删除数据
条件删除:
DELETE FROM orders
WHERE order_date
TRUNCATE与DELETE的区别:TRUNCATE是DDL,不记录日志且速度更快;DELETE是DML,可带条件且可回滚。
2.2 Oracle特有DML
(1)MERGE:合并操作(UPSERT)
该语句可实现"存在则更新,不存在则插入":
MERGE INTO target_table t
USING source_table s
ON (t.key_column = s.key_column)
WHEN MATCHED THEN
UPDATE SET t.value = s.new_value
WHEN NOT MATCHED THEN
INSERT (key_column, value) VALUES (s.key_column, s.new_value);
(2)MULTI-TABLE INSERT:多表插入
Oracle支持将单条查询结果插入到多个表中:
INSERT ALL
INTO sales_2023 VALUES (col1, col2)
INTO sales_archive VALUES (col1, TO_CHAR(SYSDATE, 'YYYY'))
SELECT * FROM temp_sales;
2.3 DML事务控制
1. 显式事务控制:
BEGIN
SAVEPOINT start_update;
UPDATE accounts SET balance = balance - 100 WHERE acct_id = 1;
UPDATE accounts SET balance = balance + 100 WHERE acct_id = 2;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO start_update;
RAISE;
END;
2. 批量绑定技术:提高大批量DML性能
DECLARE
TYPE emp_id_array IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
v_ids emp_id_array;
BEGIN
-- 填充数组
FOR i IN 1..1000 LOOP
v_ids(i) := i;
END LOOP;
-- 批量更新
FORALL i IN 1..v_ids.COUNT
UPDATE employees SET bonus = 500 WHERE emp_id = v_ids(i);
END;
三、DDL与DML的协作实践
在实际数据库应用中,DDL和DML通常需要配合使用。例如在数据迁移场景中:
3.1 表结构调整与数据迁移
-- 1. 创建新表结构(DDL)
CREATE TABLE employees_new (
emp_id NUMBER PRIMARY KEY,
full_name VARCHAR2(200),
effective_date DATE DEFAULT SYSDATE,
salary NUMBER(12,2)
);
-- 2. 数据转换与迁移(DML)
INSERT INTO employees_new
SELECT
e.emp_id,
e.first_name || ' ' || e.last_name AS full_name,
TRUNC(SYSDATE) AS effective_date,
e.base_salary + NVL(e.bonus, 0) AS salary
FROM employees e;
-- 3. 验证数据后重命名表(DDL)
RENAME employees TO employees_old;
RENAME employees_new TO employees;
-- 4. 重建索引等对象(DDL)
CREATE INDEX idx_emp_name ON employees(full_name);
3.2 动态SQL应用
在PL/SQL中结合使用DDL和DML:
DECLARE
v_sql VARCHAR2(2000);
v_table_name VARCHAR2(30) := 'TEMP_DATA_' || TO_CHAR(SYSDATE, 'YYYYMMDD');
BEGIN
-- 动态创建表(DDL)
v_sql := 'CREATE TABLE ' || v_table_name || ' AS
SELECT * FROM source_data WHERE create_date > SYSDATE-7';
EXECUTE IMMEDIATE v_sql;
-- 动态处理数据(DML)
v_sql := 'UPDATE ' || v_table_name || ' SET status = ''PROCESSED''
WHERE rowid IN (SELECT rowid FROM ' || v_table_name || '
WHERE MOD(id, 10) = 0)';
EXECUTE IMMEDIATE v_sql;
-- 动态删除表(DDL)
v_sql := 'DROP TABLE ' || v_table_name;
-- EXECUTE IMMEDIATE v_sql; -- 实际使用时需谨慎
END;
四、性能优化策略
4.1 DDL优化
1. 在线DDL操作:Oracle 11g后支持部分DDL在线执行
ALTER TABLE large_table ADD COLUMN new_col NUMBER
ONLINE LOGGING;
2. 分区表维护:使用分区交换提高DDL效率
ALTER TABLE sales EXCHANGE PARTITION sales_q1
WITH TABLE sales_q1_temp INCLUDING INDEXES;
4.2 DML优化
1. 批量提交:控制事务大小平衡性能与恢复
BEGIN
FOR i IN 1..10000 LOOP
INSERT INTO log_table VALUES (...);
IF MOD(i, 1000) = 0 THEN
COMMIT;
END IF;
END LOOP;
COMMIT;
END;
2. 直接路径加载:使用/*+ APPEND */提示
INSERT /*+ APPEND */ INTO target_table
SELECT * FROM source_table;
五、安全与权限管理
1. DDL权限控制:
GRANT CREATE TABLE, ALTER ANY TABLE TO schema_owner;
REVOKE DROP ANY TABLE FROM junior_dba;
2. DML权限控制:
GRANT SELECT, INSERT ON employees TO app_user;
DENY UPDATE ON employees(salary) TO app_user;
3. 细粒度访问控制(VPD):
CREATE POLICY emp_policy ON employees
USING (
CASE WHEN SYS_CONTEXT('USERENV', 'SESSION_USER') = 'HR_ADMIN'
THEN '1=1'
ELSE 'dept_id = SYS_CONTEXT(''APP_CTX'', ''DEPT_ID'')'
END
);
六、常见问题与解决方案
1. DDL锁问题:
现象:执行ALTER TABLE时被其他会话阻塞
解决方案:
-- 查询阻塞会话
SELECT * FROM v$locked_object l, dba_objects o
WHERE l.object_id = o.object_id;
-- 终止阻塞会话(谨慎使用)
ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
2. DML性能下降:
现象:批量UPDATE变慢
解决方案:
-- 检查执行计划
EXPLAIN PLAN FOR
UPDATE large_table SET status = 'NEW' WHERE create_date > SYSDATE-30;
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
-- 添加适当索引
CREATE INDEX idx_create_date ON large_table(create_date);
3. 对象依赖问题:
现象:删除表时提示"存在依赖对象"
解决方案:
-- 查询依赖关系
SELECT * FROM all_dependencies
WHERE referenced_name = 'DEPENDENT_TABLE';
-- 使用级联删除
DROP TABLE master_table CASCADE CONSTRAINTS;
七、最佳实践建议
1. DDL操作前备份:
-- 使用数据泵导出
EXPDP schema_name DIRECTORY=dpump_dir DUMPFILE=pre_ddl.dmp
TABLES=employees,departments
2. DML批量处理:
-- 使用FORALL提高性能
DECLARE
TYPE id_array IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
v_ids id_array;
BEGIN
-- 填充数组...
FORALL i IN 1..v_ids.COUNT
UPDATE accounts SET balance = balance + 100 WHERE acct_id = v_ids(i);
END;
3. 版本控制:对DDL脚本进行版本管理
-- 示例版本控制注释
/*
* 版本: 1.2
* 作者: dba_team
* 日期: 2023-11-15
* 描述: 添加audit_trail列并设置默认值
*/
ALTER TABLE transactions ADD COLUMN audit_trail VARCHAR2(4000)
DEFAULT 'CREATED BY SYSTEM' NOT NULL;
4. 测试环境验证:所有DDL/DML变更应先在测试环境验证
-- 测试环境验证步骤示例
1. 创建测试表结构
2. 插入测试数据
3. 执行变更脚本
4. 验证数据完整性
5. 执行功能测试
结语
DDL和DML作为Oracle数据库的两大支柱语言,分别承担着结构定义和数据操作的核心职能。理解它们的特性、差异和协作方式,对于数据库设计、开发和运维至关重要。在实际应用中,应遵循"先设计后实现"、"小步变更"、"充分测试"等原则,确保数据库变更的安全性和可靠性。随着Oracle技术的不断发展,新的DDL和DML特性(如12c的多租户DDL、19c的JSON DML等)持续涌现,数据库专业人员需要保持持续学习,以充分利用这些先进功能提升工作效率。
关键词:Oracle数据库、DDL、DML、数据定义语言、数据操纵语言、SQL语句、数据库对象、事务控制、性能优化、权限管理
简介:本文详细阐述了Oracle数据库中DDL(数据定义语言)和DML(数据操纵语言)的核心概念、语法结构、执行特性及协作实践。通过2000余字的系统介绍,结合大量代码示例,全面解析了两类SQL语句在数据库设计、数据操作、事务管理、性能优化等方面的应用技巧和最佳实践,帮助读者深入理解并掌握Oracle数据库开发与管理中的关键技术。