本文档风哥主要介绍DM数据库开发与编程,包括数据库开发概述、数据库编程概述、开发工具、SQL开发、存储过程开发、函数开发、触发器开发、应用开发、性能优化、实际案例和最佳实践等内容,风哥教程参考DM官方文档DM8开发指南、DM8SQL编程指南、DM8存储过程编程指南,适合数据库开发人员在学习和生产环境中使用。
Part01-基础概念与理论知识
1.1 数据库开发概述
数据库开发是使用SQL语言和编程语言,对数据库进行操作和管理的过程。
# 数据库开发的定义
数据库开发是使用SQL语言和编程语言,对数据库进行操作和管理的过程。
# 数据库开发的内容
– SQL开发:使用SQL语句进行数据操作
– 存储过程开发:使用存储过程进行业务逻辑处理
– 函数开发:使用函数进行数据处理
– 触发器开发:使用触发器进行数据自动处理
– 应用开发:使用编程语言连接数据库进行应用开发
# 数据库开发的目标
– 数据操作:对数据进行增删改查操作
– 业务逻辑:实现业务逻辑处理
– 数据处理:对数据进行处理和转换
– 数据安全:保障数据安全和完整性
– 性能优化:提高数据库性能
# 数据库开发的步骤
1. 需求分析
– 分析业务需求
– 分析数据需求
– 分析功能需求
2. 数据库设计
– 设计数据结构
– 设计数据关系
– 设计数据约束
3. 数据库开发
– 开发SQL语句
– 开发存储过程
– 开发函数
– 开发触发器
4. 数据库测试
– 测试SQL语句
– 测试存储过程
– 测试函数
– 测试触发器
5. 数据库部署
– 部署SQL语句
– 部署存储过程
– 部署函数
– 部署触发器
数据库开发是使用SQL语言和编程语言,对数据库进行操作和管理的过程。
# 数据库开发的内容
– SQL开发:使用SQL语句进行数据操作
– 存储过程开发:使用存储过程进行业务逻辑处理
– 函数开发:使用函数进行数据处理
– 触发器开发:使用触发器进行数据自动处理
– 应用开发:使用编程语言连接数据库进行应用开发
# 数据库开发的目标
– 数据操作:对数据进行增删改查操作
– 业务逻辑:实现业务逻辑处理
– 数据处理:对数据进行处理和转换
– 数据安全:保障数据安全和完整性
– 性能优化:提高数据库性能
# 数据库开发的步骤
1. 需求分析
– 分析业务需求
– 分析数据需求
– 分析功能需求
2. 数据库设计
– 设计数据结构
– 设计数据关系
– 设计数据约束
3. 数据库开发
– 开发SQL语句
– 开发存储过程
– 开发函数
– 开发触发器
4. 数据库测试
– 测试SQL语句
– 测试存储过程
– 测试函数
– 测试触发器
5. 数据库部署
– 部署SQL语句
– 部署存储过程
– 部署函数
– 部署触发器
1.2 数据库编程概述
数据库编程是使用编程语言和数据库接口,对数据库进行操作和管理的过程。
# 数据库编程的定义
数据库编程是使用编程语言和数据库接口,对数据库进行操作和管理的过程。
# 数据库编程的方式
1. 嵌入式SQL
– 在C语言中嵌入SQL
– 在Java语言中嵌入SQL
– 在Python语言中嵌入SQL
2. 数据库接口
– JDBC:Java数据库连接 风哥提示:
– ODBC:开放数据库连接
– PDO:PHP数据对象
– DBI:Perl数据库接口
3. ORM框架
– Hibernate:Java ORM框架
– MyBatis:Java持久层框架
– SQLAlchemy:Python ORM框架
– Django ORM:Python Web框架
# 数据库编程的内容
– 数据库连接:建立数据库连接
– 数据库操作:对数据库进行增删改查操作
– 事务处理:处理数据库事务
– 异常处理:处理数据库异常
– 性能优化:优化数据库性能
# 数据库编程的步骤
1. 建立连接
– 加载数据库驱动
– 创建数据库连接
– 配置连接参数
2. 执行操作
– 执行SQL语句
– 执行存储过程
– 执行函数
3. 处理结果
– 处理查询结果
– 处理执行结果
– 处理异常情况
4. 关闭连接
– 关闭结果集
– 关闭语句 学习交流加群风哥微信: itpux-com
– 关闭连接
数据库编程是使用编程语言和数据库接口,对数据库进行操作和管理的过程。
# 数据库编程的方式
1. 嵌入式SQL
– 在C语言中嵌入SQL
– 在Java语言中嵌入SQL
– 在Python语言中嵌入SQL
2. 数据库接口
– JDBC:Java数据库连接 风哥提示:
– ODBC:开放数据库连接
– PDO:PHP数据对象
– DBI:Perl数据库接口
3. ORM框架
– Hibernate:Java ORM框架
– MyBatis:Java持久层框架
– SQLAlchemy:Python ORM框架
– Django ORM:Python Web框架
# 数据库编程的内容
– 数据库连接:建立数据库连接
– 数据库操作:对数据库进行增删改查操作
– 事务处理:处理数据库事务
– 异常处理:处理数据库异常
– 性能优化:优化数据库性能
# 数据库编程的步骤
1. 建立连接
– 加载数据库驱动
– 创建数据库连接
– 配置连接参数
2. 执行操作
– 执行SQL语句
– 执行存储过程
– 执行函数
3. 处理结果
– 处理查询结果
– 处理执行结果
– 处理异常情况
4. 关闭连接
– 关闭结果集
– 关闭语句 学习交流加群风哥微信: itpux-com
– 关闭连接
1.3 开发工具
DM数据库提供了多种开发工具,帮助开发人员进行数据库开发。
# 1. DM管理工具
– DM管理工具
– 数据库管理
– 数据库监控
– 数据库备份
– 数据库恢复
– DM SQL工具
– SQL编辑器
– SQL执行器
– SQL调试器
– SQL优化器
# 2. DM开发工具
– DM开发工具
– 存储过程编辑器
– 函数编辑器
– 触发器编辑器
– 包编辑器
– DM调试工具
– 存储过程调试器
– 函数调试器
– 触发器调试器
# 3. 第三方开发工具
– DBeaver
– 支持多种数据库
– 支持SQL编辑
– 支持数据库管理
– Navicat
– 支持多种数据库
– 支持SQL编辑
– 支持数据库管理
– PL/SQL Developer
– 支持Oracle数据库
– 支持SQL编辑
– 支持数据库管理
– DM管理工具
– 数据库管理
– 数据库监控
– 数据库备份
– 数据库恢复
– DM SQL工具
– SQL编辑器
– SQL执行器
– SQL调试器
– SQL优化器
# 2. DM开发工具
– DM开发工具
– 存储过程编辑器
– 函数编辑器
– 触发器编辑器
– 包编辑器
– DM调试工具
– 存储过程调试器
– 函数调试器
– 触发器调试器
# 3. 第三方开发工具
– DBeaver
– 支持多种数据库
– 支持SQL编辑
– 支持数据库管理
– Navicat
– 支持多种数据库
– 支持SQL编辑
– 支持数据库管理
– PL/SQL Developer
– 支持Oracle数据库
– 支持SQL编辑
– 支持数据库管理
学习交流加群风哥QQ113257174
风哥提示:数据库开发是数据库管理的重要工作,掌握数据库开发的方法和工具,是完成数据库开发的关键。根据业务需求和系统特点,选择合适的开发方式,是保证开发成功的重要手段。
Part02-生产环境规划与建议
2.1 SQL开发
2.1.1 SQL基础
# 1. DDL语句
– 创建表
SQL> CREATE TABLE fgedu_user (
user_id INT PRIMARY KEY,
user_name VARCHAR(50) NOT NULL,
user_email VARCHAR(100),
user_status INT,
create_time TIMESTAMP DEFAULT SYSDATE
);
– 创建索引
SQL> CREATE INDEX idx_fgedu_user_name ON fgedu_user(user_name);
– 创建视图
SQL> CREATE VIEW v_fgedu_user AS
SELECT user_id, user_name, user_email
FROM fgedu_user
WHERE user_status = 1;
# 2. DML语句
– 插入数据
SQL> INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (1, ‘fgedu_user1’, ‘fgedu_user1@fgedu.net.cn’, 1);
– 更新数据
SQL> UPDATE fgedu_user
SET user_status = 0
WHERE user_id = 1;
– 删除数据
SQL> DELETE FROM fgedu_user
WHERE user_id = 1;
# 3. DQL语句
– 查询数据
SQL> SELECT user_id, user_name, user_email
FROM fgedu_user
WHERE user_status = 1;
– 聚合查询 更多视频教程www.fgedu.net.cn
SQL> SELECT COUNT(*) AS user_count
FROM fgedu_user
WHERE user_status = 1;
– 分组查询
SQL> SELECT user_status, COUNT(*) AS user_count
FROM fgedu_user
GROUP BY user_status;
# 4. 实际示例
– 创建表
SQL> CREATE TABLE fgedu_user (
user_id INT PRIMARY KEY,
user_name VARCHAR(50) NOT NULL,
user_email VARCHAR(100),
user_status INT,
create_time TIMESTAMP DEFAULT SYSDATE
);
– 插入数据
SQL> INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (1, ‘fgedu_user1’, ‘fgedu_user1@fgedu.net.cn’, 1);
– 查询数据
SQL> SELECT * FROM fgedu_user;
# 输出结果
# USER_ID USER_NAME USER_EMAIL USER_STATUS CREATE_TIME
# ——– ———- ——————– ———— ——————-
# 1 fgedu_user1 fgedu_user1@fgedu.net.cn 1 2024-01-01 10:00:00
– 创建表
SQL> CREATE TABLE fgedu_user (
user_id INT PRIMARY KEY,
user_name VARCHAR(50) NOT NULL,
user_email VARCHAR(100),
user_status INT,
create_time TIMESTAMP DEFAULT SYSDATE
);
– 创建索引
SQL> CREATE INDEX idx_fgedu_user_name ON fgedu_user(user_name);
– 创建视图
SQL> CREATE VIEW v_fgedu_user AS
SELECT user_id, user_name, user_email
FROM fgedu_user
WHERE user_status = 1;
# 2. DML语句
– 插入数据
SQL> INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (1, ‘fgedu_user1’, ‘fgedu_user1@fgedu.net.cn’, 1);
– 更新数据
SQL> UPDATE fgedu_user
SET user_status = 0
WHERE user_id = 1;
– 删除数据
SQL> DELETE FROM fgedu_user
WHERE user_id = 1;
# 3. DQL语句
– 查询数据
SQL> SELECT user_id, user_name, user_email
FROM fgedu_user
WHERE user_status = 1;
– 聚合查询 更多视频教程www.fgedu.net.cn
SQL> SELECT COUNT(*) AS user_count
FROM fgedu_user
WHERE user_status = 1;
– 分组查询
SQL> SELECT user_status, COUNT(*) AS user_count
FROM fgedu_user
GROUP BY user_status;
# 4. 实际示例
– 创建表
SQL> CREATE TABLE fgedu_user (
user_id INT PRIMARY KEY,
user_name VARCHAR(50) NOT NULL,
user_email VARCHAR(100),
user_status INT,
create_time TIMESTAMP DEFAULT SYSDATE
);
– 插入数据
SQL> INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (1, ‘fgedu_user1’, ‘fgedu_user1@fgedu.net.cn’, 1);
– 查询数据
SQL> SELECT * FROM fgedu_user;
# 输出结果
# USER_ID USER_NAME USER_EMAIL USER_STATUS CREATE_TIME
# ——– ———- ——————– ———— ——————-
# 1 fgedu_user1 fgedu_user1@fgedu.net.cn 1 2024-01-01 10:00:00
2.1.2 SQL高级
# 1. 连接查询
– 内连接
SQL> SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u
INNER JOIN fgedu_order o ON u.user_id = o.user_id;
– 左连接
SQL> SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u
LEFT JOIN fgedu_order o ON u.user_id = o.user_id;
– 右连接
SQL> SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u 更多学习教程公众号风哥教程itpux_com
RIGHT JOIN fgedu_order o ON u.user_id = o.user_id;
# 2. 子查询
– 单行子查询
SQL> SELECT * FROM fgedu_user
WHERE user_id = (SELECT MAX(user_id) FROM fgedu_user);
– 多行子查询
SQL> SELECT * FROM fgedu_user
WHERE user_id IN (SELECT user_id FROM fgedu_order);
– 相关子查询
SQL> SELECT u.user_id, u.user_name,
(SELECT COUNT(*) FROM fgedu_order o WHERE o.user_id = u.user_id) AS order_count
FROM fgedu_user u;
# 3. 分页查询
– 使用LIMIT分页
SQL> SELECT * FROM fgedu_user
ORDER BY user_id
LIMIT 10 OFFSET 0;
– 使用ROWNUM分页
SQL> SELECT * FROM (
SELECT a.*, ROWNUM AS rn
FROM (SELECT * FROM fgedu_user ORDER BY user_id) a
WHERE ROWNUM <= 10 ) WHERE rn > 0;
# 4. 实际示例
– 连接查询
SQL> SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u
INNER JOIN fgedu_order o ON u.user_id = o.user_id;
# 输出结果
# USER_ID USER_NAME ORDER_ID ORDER_AMOUNT from DB视频:www.itpux.com
# ——– ———- ——— ————-
# 1 fgedu_user1 1001 100.00
# 1 fgedu_user1 1002 200.00
– 子查询
SQL> SELECT u.user_id, u.user_name,
(SELECT COUNT(*) FROM fgedu_order o WHERE o.user_id = u.user_id) AS order_count
FROM fgedu_user u;
# 输出结果
# USER_ID USER_NAME ORDER_COUNT
# ——– ———- ————
# 1 fgedu_user1 2
– 内连接
SQL> SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u
INNER JOIN fgedu_order o ON u.user_id = o.user_id;
– 左连接
SQL> SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u
LEFT JOIN fgedu_order o ON u.user_id = o.user_id;
– 右连接
SQL> SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u 更多学习教程公众号风哥教程itpux_com
RIGHT JOIN fgedu_order o ON u.user_id = o.user_id;
# 2. 子查询
– 单行子查询
SQL> SELECT * FROM fgedu_user
WHERE user_id = (SELECT MAX(user_id) FROM fgedu_user);
– 多行子查询
SQL> SELECT * FROM fgedu_user
WHERE user_id IN (SELECT user_id FROM fgedu_order);
– 相关子查询
SQL> SELECT u.user_id, u.user_name,
(SELECT COUNT(*) FROM fgedu_order o WHERE o.user_id = u.user_id) AS order_count
FROM fgedu_user u;
# 3. 分页查询
– 使用LIMIT分页
SQL> SELECT * FROM fgedu_user
ORDER BY user_id
LIMIT 10 OFFSET 0;
– 使用ROWNUM分页
SQL> SELECT * FROM (
SELECT a.*, ROWNUM AS rn
FROM (SELECT * FROM fgedu_user ORDER BY user_id) a
WHERE ROWNUM <= 10 ) WHERE rn > 0;
# 4. 实际示例
– 连接查询
SQL> SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u
INNER JOIN fgedu_order o ON u.user_id = o.user_id;
# 输出结果
# USER_ID USER_NAME ORDER_ID ORDER_AMOUNT from DB视频:www.itpux.com
# ——– ———- ——— ————-
# 1 fgedu_user1 1001 100.00
# 1 fgedu_user1 1002 200.00
– 子查询
SQL> SELECT u.user_id, u.user_name,
(SELECT COUNT(*) FROM fgedu_order o WHERE o.user_id = u.user_id) AS order_count
FROM fgedu_user u;
# 输出结果
# USER_ID USER_NAME ORDER_COUNT
# ——– ———- ————
# 1 fgedu_user1 2
2.2 存储过程开发
2.2.1 存储过程基础
# 1. 创建存储过程
– 创建简单存储过程
SQL> CREATE PROCEDURE sp_hello()
AS
BEGIN
PRINT ‘Hello, World!’;
END;
– 创建带参数的存储过程
SQL> CREATE PROCEDURE sp_get_user(p_user_id INT)
AS
BEGIN
SELECT * FROM fgedu_user WHERE user_id = p_user_id;
END;
– 创建带输出参数的存储过程
SQL> CREATE PROCEDURE sp_get_user_count(p_user_status INT, p_user_count OUT INT)
AS
BEGIN
SELECT COUNT(*) INTO p_user_count FROM fgedu_user WHERE user_status = p_user_status;
END;
# 2. 调用存储过程
– 调用简单存储过程
SQL> CALL sp_hello();
– 调用带参数的存储过程
SQL> CALL sp_get_user(1);
– 调用带输出参数的存储过程
SQL> DECLARE
v_user_count INT;
BEGIN
sp_get_user_count(1, v_user_count);
PRINT ‘User count: ‘ || v_user_count;
END;
# 3. 删除存储过程
SQL> DROP PROCEDURE sp_hello;
# 4. 实际示例
– 创建存储过程
SQL> CREATE PROCEDURE sp_get_user(p_user_id INT)
AS
BEGIN
SELECT * FROM fgedu_user WHERE user_id = p_user_id;
END;
– 调用存储过程
SQL> CALL sp_get_user(1);
# 输出结果
# USER_ID USER_NAME USER_EMAIL USER_STATUS CREATE_TIME
# ——– ———- ——————– ———— ——————-
# 1 fgedu_user1 fgedu_user1@fgedu.net.cn 1 2024-01-01 10:00:00
– 创建简单存储过程
SQL> CREATE PROCEDURE sp_hello()
AS
BEGIN
PRINT ‘Hello, World!’;
END;
– 创建带参数的存储过程
SQL> CREATE PROCEDURE sp_get_user(p_user_id INT)
AS
BEGIN
SELECT * FROM fgedu_user WHERE user_id = p_user_id;
END;
– 创建带输出参数的存储过程
SQL> CREATE PROCEDURE sp_get_user_count(p_user_status INT, p_user_count OUT INT)
AS
BEGIN
SELECT COUNT(*) INTO p_user_count FROM fgedu_user WHERE user_status = p_user_status;
END;
# 2. 调用存储过程
– 调用简单存储过程
SQL> CALL sp_hello();
– 调用带参数的存储过程
SQL> CALL sp_get_user(1);
– 调用带输出参数的存储过程
SQL> DECLARE
v_user_count INT;
BEGIN
sp_get_user_count(1, v_user_count);
PRINT ‘User count: ‘ || v_user_count;
END;
# 3. 删除存储过程
SQL> DROP PROCEDURE sp_hello;
# 4. 实际示例
– 创建存储过程
SQL> CREATE PROCEDURE sp_get_user(p_user_id INT)
AS
BEGIN
SELECT * FROM fgedu_user WHERE user_id = p_user_id;
END;
– 调用存储过程
SQL> CALL sp_get_user(1);
# 输出结果
# USER_ID USER_NAME USER_EMAIL USER_STATUS CREATE_TIME
# ——– ———- ——————– ———— ——————-
# 1 fgedu_user1 fgedu_user1@fgedu.net.cn 1 2024-01-01 10:00:00
2.2.2 存储过程高级
# 1. 条件语句
– IF语句
SQL> CREATE PROCEDURE sp_check_user(p_user_id INT)
AS
v_user_status INT;
BEGIN
SELECT user_status INTO v_user_status FROM fgedu_user WHERE user_id = p_user_id;
IF v_user_status = 1 THEN
PRINT ‘User is active’;
ELSIF v_user_status = 0 THEN
PRINT ‘User is inactive’;
ELSE
PRINT ‘User status is unknown’;
END IF;
END;
– CASE语句
SQL> CREATE PROCEDURE sp_get_user_status_name(p_user_id INT)
AS
v_user_status INT;
BEGIN
SELECT user_status INTO v_user_status FROM fgedu_user WHERE user_id = p_user_id;
CASE v_user_status
WHEN 1 THEN PRINT ‘Active’;
WHEN 0 THEN PRINT ‘Inactive’;
ELSE PRINT ‘Unknown’;
END CASE;
END;
# 2. 循环语句
– WHILE循环
SQL> CREATE PROCEDURE sp_print_numbers(p_count INT)
AS
v_i INT := 1;
BEGIN
WHILE v_i <= p_count LOOP PRINT 'Number: ' || v_i; v_i := v_i + 1; END LOOP; END; - FOR循环 SQL> CREATE PROCEDURE sp_print_users()
AS
v_user_id INT;
v_user_name VARCHAR(50);
BEGIN
FOR cur_user IN (SELECT user_id, user_name FROM fgedu_user) LOOP
PRINT ‘User ID: ‘ || cur_user.user_id || ‘, User Name: ‘ || cur_user.user_name;
END LOOP;
END;
# 3. 异常处理
– 异常处理
SQL> CREATE PROCEDURE sp_divide(p_a INT, p_b INT)
AS
v_result INT;
BEGIN
v_result := p_a / p_b;
PRINT ‘Result: ‘ || v_result;
EXCEPTION
WHEN ZERO_DIVIDE THEN
PRINT ‘Error: Division by zero’;
WHEN OTHERS THEN
PRINT ‘Error: ‘ || SQLERRM;
END;
# 4. 实际示例
– 创建存储过程
SQL> CREATE PROCEDURE sp_update_user_status(p_user_id INT, p_user_status INT)
AS
v_user_count INT;
BEGIN
SELECT COUNT(*) INTO v_user_count FROM fgedu_user WHERE user_id = p_user_id;
IF v_user_count = 0 THEN
PRINT ‘User not found’;
ELSE
UPDATE fgedu_user SET user_status = p_user_status WHERE user_id = p_user_id;
PRINT ‘User status updated’;
END IF;
END;
– 调用存储过程
SQL> CALL sp_update_user_status(1, 0);
# 输出结果
# User status updated
– IF语句
SQL> CREATE PROCEDURE sp_check_user(p_user_id INT)
AS
v_user_status INT;
BEGIN
SELECT user_status INTO v_user_status FROM fgedu_user WHERE user_id = p_user_id;
IF v_user_status = 1 THEN
PRINT ‘User is active’;
ELSIF v_user_status = 0 THEN
PRINT ‘User is inactive’;
ELSE
PRINT ‘User status is unknown’;
END IF;
END;
– CASE语句
SQL> CREATE PROCEDURE sp_get_user_status_name(p_user_id INT)
AS
v_user_status INT;
BEGIN
SELECT user_status INTO v_user_status FROM fgedu_user WHERE user_id = p_user_id;
CASE v_user_status
WHEN 1 THEN PRINT ‘Active’;
WHEN 0 THEN PRINT ‘Inactive’;
ELSE PRINT ‘Unknown’;
END CASE;
END;
# 2. 循环语句
– WHILE循环
SQL> CREATE PROCEDURE sp_print_numbers(p_count INT)
AS
v_i INT := 1;
BEGIN
WHILE v_i <= p_count LOOP PRINT 'Number: ' || v_i; v_i := v_i + 1; END LOOP; END; - FOR循环 SQL> CREATE PROCEDURE sp_print_users()
AS
v_user_id INT;
v_user_name VARCHAR(50);
BEGIN
FOR cur_user IN (SELECT user_id, user_name FROM fgedu_user) LOOP
PRINT ‘User ID: ‘ || cur_user.user_id || ‘, User Name: ‘ || cur_user.user_name;
END LOOP;
END;
# 3. 异常处理
– 异常处理
SQL> CREATE PROCEDURE sp_divide(p_a INT, p_b INT)
AS
v_result INT;
BEGIN
v_result := p_a / p_b;
PRINT ‘Result: ‘ || v_result;
EXCEPTION
WHEN ZERO_DIVIDE THEN
PRINT ‘Error: Division by zero’;
WHEN OTHERS THEN
PRINT ‘Error: ‘ || SQLERRM;
END;
# 4. 实际示例
– 创建存储过程
SQL> CREATE PROCEDURE sp_update_user_status(p_user_id INT, p_user_status INT)
AS
v_user_count INT;
BEGIN
SELECT COUNT(*) INTO v_user_count FROM fgedu_user WHERE user_id = p_user_id;
IF v_user_count = 0 THEN
PRINT ‘User not found’;
ELSE
UPDATE fgedu_user SET user_status = p_user_status WHERE user_id = p_user_id;
PRINT ‘User status updated’;
END IF;
END;
– 调用存储过程
SQL> CALL sp_update_user_status(1, 0);
# 输出结果
# User status updated
2.3 函数开发
2.3.1 函数基础
# 1. 创建函数
– 创建简单函数
SQL> CREATE FUNCTION fn_hello() RETURN VARCHAR
AS
BEGIN
RETURN ‘Hello, World!’;
END;
– 创建带参数的函数
SQL> CREATE FUNCTION fn_get_user_name(p_user_id INT) RETURN VARCHAR
AS
v_user_name VARCHAR(50);
BEGIN
SELECT user_name INTO v_user_name FROM fgedu_user WHERE user_id = p_user_id;
RETURN v_user_name;
END;
– 创建带多个参数的函数
SQL> CREATE FUNCTION fn_add(p_a INT, p_b INT) RETURN INT
AS
BEGIN
RETURN p_a + p_b;
END;
# 2. 调用函数
– 调用简单函数
SQL> SELECT fn_hello() FROM DUAL;
– 调用带参数的函数
SQL> SELECT fn_get_user_name(1) FROM DUAL;
– 调用带多个参数的函数
SQL> SELECT fn_add(1, 2) FROM DUAL;
# 3. 删除函数
SQL> DROP FUNCTION fn_hello;
# 4. 实际示例
– 创建函数
SQL> CREATE FUNCTION fn_get_user_name(p_user_id INT) RETURN VARCHAR
AS
v_user_name VARCHAR(50);
BEGIN
SELECT user_name INTO v_user_name FROM fgedu_user WHERE user_id = p_user_id;
RETURN v_user_name;
END;
– 调用函数
SQL> SELECT fn_get_user_name(1) FROM DUAL;
# 输出结果
# FN_GET_USER_NAME(1)
# ——————-
# fgedu_user1
– 创建简单函数
SQL> CREATE FUNCTION fn_hello() RETURN VARCHAR
AS
BEGIN
RETURN ‘Hello, World!’;
END;
– 创建带参数的函数
SQL> CREATE FUNCTION fn_get_user_name(p_user_id INT) RETURN VARCHAR
AS
v_user_name VARCHAR(50);
BEGIN
SELECT user_name INTO v_user_name FROM fgedu_user WHERE user_id = p_user_id;
RETURN v_user_name;
END;
– 创建带多个参数的函数
SQL> CREATE FUNCTION fn_add(p_a INT, p_b INT) RETURN INT
AS
BEGIN
RETURN p_a + p_b;
END;
# 2. 调用函数
– 调用简单函数
SQL> SELECT fn_hello() FROM DUAL;
– 调用带参数的函数
SQL> SELECT fn_get_user_name(1) FROM DUAL;
– 调用带多个参数的函数
SQL> SELECT fn_add(1, 2) FROM DUAL;
# 3. 删除函数
SQL> DROP FUNCTION fn_hello;
# 4. 实际示例
– 创建函数
SQL> CREATE FUNCTION fn_get_user_name(p_user_id INT) RETURN VARCHAR
AS
v_user_name VARCHAR(50);
BEGIN
SELECT user_name INTO v_user_name FROM fgedu_user WHERE user_id = p_user_id;
RETURN v_user_name;
END;
– 调用函数
SQL> SELECT fn_get_user_name(1) FROM DUAL;
# 输出结果
# FN_GET_USER_NAME(1)
# ——————-
# fgedu_user1
2.3.2 函数高级
# 1. 聚合函数
– 创建聚合函数
SQL> CREATE FUNCTION fn_get_user_count(p_user_status INT) RETURN INT
AS
v_user_count INT;
BEGIN
SELECT COUNT(*) INTO v_user_count FROM fgedu_user WHERE user_status = p_user_status;
RETURN v_user_count;
END;
– 调用聚合函数
SQL> SELECT fn_get_user_count(1) FROM DUAL;
# 2. 字符串函数
– 创建字符串函数
SQL> CREATE FUNCTION fn_format_email(p_user_name VARCHAR, p_domain VARCHAR) RETURN VARCHAR
AS
BEGIN
RETURN p_user_name || ‘@’ || p_domain;
END;
– 调用字符串函数
SQL> SELECT fn_format_email(‘fgedu_user1’, ‘fgedu.net.cn’) FROM DUAL;
# 3. 日期函数
– 创建日期函数
SQL> CREATE FUNCTION fn_get_age(p_birthday DATE) RETURN INT
AS
v_age INT;
BEGIN
v_age := FLOOR(MONTHS_BETWEEN(SYSDATE, p_birthday) / 12);
RETURN v_age;
END;
– 调用日期函数
SQL> SELECT fn_get_age(TO_DATE(‘1990-01-01’, ‘YYYY-MM-DD’)) FROM DUAL;
# 4. 实际示例
– 创建函数
SQL> CREATE FUNCTION fn_get_user_email(p_user_id INT) RETURN VARCHAR
AS
v_user_email VARCHAR(100);
BEGIN
SELECT user_email INTO v_user_email FROM fgedu_user WHERE user_id = p_user_id;
RETURN v_user_email;
END;
– 调用函数
SQL> SELECT fn_get_user_email(1) FROM DUAL;
# 输出结果
# FN_GET_USER_EMAIL(1)
# ——————–
# fgedu_user1@fgedu.net.cn
– 创建聚合函数
SQL> CREATE FUNCTION fn_get_user_count(p_user_status INT) RETURN INT
AS
v_user_count INT;
BEGIN
SELECT COUNT(*) INTO v_user_count FROM fgedu_user WHERE user_status = p_user_status;
RETURN v_user_count;
END;
– 调用聚合函数
SQL> SELECT fn_get_user_count(1) FROM DUAL;
# 2. 字符串函数
– 创建字符串函数
SQL> CREATE FUNCTION fn_format_email(p_user_name VARCHAR, p_domain VARCHAR) RETURN VARCHAR
AS
BEGIN
RETURN p_user_name || ‘@’ || p_domain;
END;
– 调用字符串函数
SQL> SELECT fn_format_email(‘fgedu_user1’, ‘fgedu.net.cn’) FROM DUAL;
# 3. 日期函数
– 创建日期函数
SQL> CREATE FUNCTION fn_get_age(p_birthday DATE) RETURN INT
AS
v_age INT;
BEGIN
v_age := FLOOR(MONTHS_BETWEEN(SYSDATE, p_birthday) / 12);
RETURN v_age;
END;
– 调用日期函数
SQL> SELECT fn_get_age(TO_DATE(‘1990-01-01’, ‘YYYY-MM-DD’)) FROM DUAL;
# 4. 实际示例
– 创建函数
SQL> CREATE FUNCTION fn_get_user_email(p_user_id INT) RETURN VARCHAR
AS
v_user_email VARCHAR(100);
BEGIN
SELECT user_email INTO v_user_email FROM fgedu_user WHERE user_id = p_user_id;
RETURN v_user_email;
END;
– 调用函数
SQL> SELECT fn_get_user_email(1) FROM DUAL;
# 输出结果
# FN_GET_USER_EMAIL(1)
# ——————–
# fgedu_user1@fgedu.net.cn
生产环境建议:根据业务需求和系统特点,选择合适的开发方式。在开发前进行充分的需求分析,确保开发的功能满足业务需求。建立完善的测试体系,确保开发的质量。
Part03-生产环境项目实施方案
3.1 触发器开发
3.1.1 触发器基础
# 1. 创建触发器
– 创建BEFORE INSERT触发器
SQL> CREATE TRIGGER trg_fgedu_user_before_insert
BEFORE INSERT ON fgedu_user
FOR EACH ROW
BEGIN
:NEW.create_time := SYSDATE;
END;
– 创建AFTER INSERT触发器
SQL> CREATE TRIGGER trg_fgedu_user_after_insert
AFTER INSERT ON fgedu_user
FOR EACH ROW
BEGIN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘INSERT’, SYSDATE);
END;
– 创建BEFORE UPDATE触发器
SQL> CREATE TRIGGER trg_fgedu_user_before_update
BEFORE UPDATE ON fgedu_user
FOR EACH ROW
BEGIN
IF :OLD.user_status != :NEW.user_status THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘UPDATE’, SYSDATE);
END IF;
END;
# 2. 删除触发器
SQL> DROP TRIGGER trg_fgedu_user_before_insert;
# 3. 查看触发器
SQL> SELECT trigger_name, trigger_type, triggering_event, table_name
FROM user_triggers
WHERE table_name = ‘FGEDU_USER’;
# 4. 实际示例
– 创建触发器
SQL> CREATE TRIGGER trg_fgedu_user_before_insert
BEFORE INSERT ON fgedu_user
FOR EACH ROW
BEGIN
:NEW.create_time := SYSDATE;
END;
– 插入数据
SQL> INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (2, ‘fgedu_user2’, ‘fgedu_user2@fgedu.net.cn’, 1);
– 查询数据
SQL> SELECT * FROM fgedu_user WHERE user_id = 2;
# 输出结果
# USER_ID USER_NAME USER_EMAIL USER_STATUS CREATE_TIME
# ——– ———- ——————– ———— ——————-
# 2 fgedu_user2 fgedu_user2@fgedu.net.cn 1 2024-01-01 10:00:00
– 创建BEFORE INSERT触发器
SQL> CREATE TRIGGER trg_fgedu_user_before_insert
BEFORE INSERT ON fgedu_user
FOR EACH ROW
BEGIN
:NEW.create_time := SYSDATE;
END;
– 创建AFTER INSERT触发器
SQL> CREATE TRIGGER trg_fgedu_user_after_insert
AFTER INSERT ON fgedu_user
FOR EACH ROW
BEGIN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘INSERT’, SYSDATE);
END;
– 创建BEFORE UPDATE触发器
SQL> CREATE TRIGGER trg_fgedu_user_before_update
BEFORE UPDATE ON fgedu_user
FOR EACH ROW
BEGIN
IF :OLD.user_status != :NEW.user_status THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘UPDATE’, SYSDATE);
END IF;
END;
# 2. 删除触发器
SQL> DROP TRIGGER trg_fgedu_user_before_insert;
# 3. 查看触发器
SQL> SELECT trigger_name, trigger_type, triggering_event, table_name
FROM user_triggers
WHERE table_name = ‘FGEDU_USER’;
# 4. 实际示例
– 创建触发器
SQL> CREATE TRIGGER trg_fgedu_user_before_insert
BEFORE INSERT ON fgedu_user
FOR EACH ROW
BEGIN
:NEW.create_time := SYSDATE;
END;
– 插入数据
SQL> INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (2, ‘fgedu_user2’, ‘fgedu_user2@fgedu.net.cn’, 1);
– 查询数据
SQL> SELECT * FROM fgedu_user WHERE user_id = 2;
# 输出结果
# USER_ID USER_NAME USER_EMAIL USER_STATUS CREATE_TIME
# ——– ———- ——————– ———— ——————-
# 2 fgedu_user2 fgedu_user2@fgedu.net.cn 1 2024-01-01 10:00:00
3.1.2 触发器高级
# 1. 条件触发器
– 创建条件触发器
SQL> CREATE TRIGGER trg_fgedu_user_conditional
BEFORE UPDATE ON fgedu_user
FOR EACH ROW
WHEN (OLD.user_status != NEW.user_status)
BEGIN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘STATUS_CHANGE’, SYSDATE);
END;
# 2. 行级触发器
– 创建行级触发器
SQL> CREATE TRIGGER trg_fgedu_user_row_level
AFTER INSERT OR UPDATE OR DELETE ON fgedu_user
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘INSERT’, SYSDATE);
ELSIF UPDATING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘UPDATE’, SYSDATE);
ELSIF DELETING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:OLD.user_id, ‘DELETE’, SYSDATE);
END IF;
END;
# 3. 语句级触发器
– 创建语句级触发器
SQL> CREATE TRIGGER trg_fgedu_user_statement_level
AFTER INSERT OR UPDATE OR DELETE ON fgedu_user
BEGIN
INSERT INTO fgedu_operation_log (operation, operation_time)
VALUES (SQL_OP, SYSDATE);
END;
# 4. 实际示例
– 创建触发器
SQL> CREATE TRIGGER trg_fgedu_user_row_level
AFTER INSERT OR UPDATE OR DELETE ON fgedu_user
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘INSERT’, SYSDATE);
ELSIF UPDATING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘UPDATE’, SYSDATE);
ELSIF DELETING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:OLD.user_id, ‘DELETE’, SYSDATE);
END IF;
END;
– 插入数据
SQL> INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (3, ‘user3’, ‘user3@fgedu.net.cn’, 1);
– 查询日志
SQL> SELECT * FROM fgedu_user_log;
# 输出结果
# LOG_ID USER_ID ACTION ACTION_TIME
# ——- ——– ——- ——————-
# 1 3 INSERT 2024-01-01 10:00:00
– 创建条件触发器
SQL> CREATE TRIGGER trg_fgedu_user_conditional
BEFORE UPDATE ON fgedu_user
FOR EACH ROW
WHEN (OLD.user_status != NEW.user_status)
BEGIN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘STATUS_CHANGE’, SYSDATE);
END;
# 2. 行级触发器
– 创建行级触发器
SQL> CREATE TRIGGER trg_fgedu_user_row_level
AFTER INSERT OR UPDATE OR DELETE ON fgedu_user
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘INSERT’, SYSDATE);
ELSIF UPDATING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘UPDATE’, SYSDATE);
ELSIF DELETING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:OLD.user_id, ‘DELETE’, SYSDATE);
END IF;
END;
# 3. 语句级触发器
– 创建语句级触发器
SQL> CREATE TRIGGER trg_fgedu_user_statement_level
AFTER INSERT OR UPDATE OR DELETE ON fgedu_user
BEGIN
INSERT INTO fgedu_operation_log (operation, operation_time)
VALUES (SQL_OP, SYSDATE);
END;
# 4. 实际示例
– 创建触发器
SQL> CREATE TRIGGER trg_fgedu_user_row_level
AFTER INSERT OR UPDATE OR DELETE ON fgedu_user
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘INSERT’, SYSDATE);
ELSIF UPDATING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:NEW.user_id, ‘UPDATE’, SYSDATE);
ELSIF DELETING THEN
INSERT INTO fgedu_user_log (user_id, action, action_time)
VALUES (:OLD.user_id, ‘DELETE’, SYSDATE);
END IF;
END;
– 插入数据
SQL> INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (3, ‘user3’, ‘user3@fgedu.net.cn’, 1);
– 查询日志
SQL> SELECT * FROM fgedu_user_log;
# 输出结果
# LOG_ID USER_ID ACTION ACTION_TIME
# ——- ——– ——- ——————-
# 1 3 INSERT 2024-01-01 10:00:00
3.2 应用开发
3.2.1 JDBC开发
# 1. JDBC连接
– 加载驱动
Class.forName(“dm.jdbc.driver.DmDriver”);
– 创建连接
Connection conn = DriverManager.getConnection(
“jdbc:dm://fgedu.localhost:5236/fgedudb”,
“SYSDBA”,
“SYSDBA”
);
# 2. JDBC操作
– 执行查询
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(“SELECT * FROM fgedu_user”);
while (rs.next()) {
int userId = rs.getInt(“user_id”);
String userName = rs.getString(“user_name”);
System.out.println(“User ID: ” + userId + “, User Name: ” + userName);
}
– 执行更新
Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate(“UPDATE fgedu_user SET user_status = 0 WHERE user_id = 1”);
System.out.println(“Rows updated: ” + rows);
# 3. JDBC事务
– 开启事务
conn.setAutoCommit(false);
– 提交事务
conn.commit();
– 回滚事务
conn.rollback();
# 4. 实际示例
– JDBC连接和查询
import java.sql.*;
public class DMJDBCExample {
public static void main(String[] args) {
try {
Class.forName(“dm.jdbc.driver.DmDriver”);
Connection conn = DriverManager.getConnection(
“jdbc:dm://fgedu.localhost:5236/fgedudb”,
“SYSDBA”,
“SYSDBA”
);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(“SELECT * FROM fgedu_user”);
while (rs.next()) {
int userId = rs.getInt(“user_id”);
String userName = rs.getString(“user_name”);
System.out.println(“User ID: ” + userId + “, User Name: ” + userName);
}
rs.close();
stmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
# 输出结果
# User ID: 1, User Name: fgedu_user1
# User ID: 2, User Name: fgedu_user2
# User ID: 3, User Name: user3
– 加载驱动
Class.forName(“dm.jdbc.driver.DmDriver”);
– 创建连接
Connection conn = DriverManager.getConnection(
“jdbc:dm://fgedu.localhost:5236/fgedudb”,
“SYSDBA”,
“SYSDBA”
);
# 2. JDBC操作
– 执行查询
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(“SELECT * FROM fgedu_user”);
while (rs.next()) {
int userId = rs.getInt(“user_id”);
String userName = rs.getString(“user_name”);
System.out.println(“User ID: ” + userId + “, User Name: ” + userName);
}
– 执行更新
Statement stmt = conn.createStatement();
int rows = stmt.executeUpdate(“UPDATE fgedu_user SET user_status = 0 WHERE user_id = 1”);
System.out.println(“Rows updated: ” + rows);
# 3. JDBC事务
– 开启事务
conn.setAutoCommit(false);
– 提交事务
conn.commit();
– 回滚事务
conn.rollback();
# 4. 实际示例
– JDBC连接和查询
import java.sql.*;
public class DMJDBCExample {
public static void main(String[] args) {
try {
Class.forName(“dm.jdbc.driver.DmDriver”);
Connection conn = DriverManager.getConnection(
“jdbc:dm://fgedu.localhost:5236/fgedudb”,
“SYSDBA”,
“SYSDBA”
);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(“SELECT * FROM fgedu_user”);
while (rs.next()) {
int userId = rs.getInt(“user_id”);
String userName = rs.getString(“user_name”);
System.out.println(“User ID: ” + userId + “, User Name: ” + userName);
}
rs.close();
stmt.close();
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
# 输出结果
# User ID: 1, User Name: fgedu_user1
# User ID: 2, User Name: fgedu_user2
# User ID: 3, User Name: user3
3.2.2 Python开发
# 1. Python连接
– 安装驱动
pip install dmPython
– 创建连接
import dmPython
conn = dmPython.connect(
user=’SYSDBA’,
password=’SYSDBA’,
server=’fgedu.localhost’,
port=5236
)
# 2. Python操作
– 执行查询
cursor = conn.cursor()
cursor.execute(“SELECT * FROM fgedu_user”)
for row in cursor:
print(“User ID:”, row[0], “, User Name:”, row[1])
– 执行更新
cursor = conn.cursor()
rows = cursor.execute(“UPDATE fgedu_user SET user_status = 0 WHERE user_id = 1”)
print(“Rows updated:”, rows)
# 3. Python事务
– 开启事务
conn.begin()
– 提交事务
conn.commit()
– 回滚事务
conn.rollback()
# 4. 实际示例
– Python连接和查询
import dmPython
conn = dmPython.connect(
user=’SYSDBA’,
password=’SYSDBA’,
server=’fgedu.localhost’,
port=5236
)
cursor = conn.cursor()
cursor.execute(“SELECT * FROM fgedu_user”)
for row in cursor:
print(“User ID:”, row[0], “, User Name:”, row[1])
cursor.close()
conn.close()
# 输出结果
# User ID: 1, User Name: fgedu_user1
# User ID: 2, User Name: fgedu_user2
# User ID: 3, User Name: user3
– 安装驱动
pip install dmPython
– 创建连接
import dmPython
conn = dmPython.connect(
user=’SYSDBA’,
password=’SYSDBA’,
server=’fgedu.localhost’,
port=5236
)
# 2. Python操作
– 执行查询
cursor = conn.cursor()
cursor.execute(“SELECT * FROM fgedu_user”)
for row in cursor:
print(“User ID:”, row[0], “, User Name:”, row[1])
– 执行更新
cursor = conn.cursor()
rows = cursor.execute(“UPDATE fgedu_user SET user_status = 0 WHERE user_id = 1”)
print(“Rows updated:”, rows)
# 3. Python事务
– 开启事务
conn.begin()
– 提交事务
conn.commit()
– 回滚事务
conn.rollback()
# 4. 实际示例
– Python连接和查询
import dmPython
conn = dmPython.connect(
user=’SYSDBA’,
password=’SYSDBA’,
server=’fgedu.localhost’,
port=5236
)
cursor = conn.cursor()
cursor.execute(“SELECT * FROM fgedu_user”)
for row in cursor:
print(“User ID:”, row[0], “, User Name:”, row[1])
cursor.close()
conn.close()
# 输出结果
# User ID: 1, User Name: fgedu_user1
# User ID: 2, User Name: fgedu_user2
# User ID: 3, User Name: user3
3.3 性能优化
3.3.1 SQL优化
# 1. 索引优化
– 创建索引
SQL> CREATE INDEX idx_fgedu_user_name ON fgedu_user(user_name);
– 使用索引
SQL> SELECT * FROM fgedu_user WHERE user_name = ‘fgedu_user1’;
# 2. 查询优化
– 避免全表扫描
SQL> SELECT * FROM fgedu_user WHERE user_id = 1;
– 避免使用SELECT *
SQL> SELECT user_id, user_name FROM fgedu_user;
– 使用LIMIT限制结果集
SQL> SELECT * FROM fgedu_user LIMIT 10;
# 3. 连接优化
– 使用INNER JOIN代替子查询
SQL> SELECT u.user_id, u.user_name, o.order_id
FROM fgedu_user u
INNER JOIN fgedu_order o ON u.user_id = o.user_id;
– 使用小表驱动大表
SQL> SELECT u.user_id, u.user_name, o.order_id
FROM fgedu_order o
INNER JOIN fgedu_user u ON o.user_id = u.user_id;
# 4. 实际示例
– 优化前
SQL> SELECT * FROM fgedu_user WHERE user_name LIKE ‘%user%’;
– 优化后
SQL> SELECT * FROM fgedu_user WHERE user_name LIKE ‘user%’;
– 查看执行计划
SQL> EXPLAIN PLAN FOR SELECT * FROM fgedu_user WHERE user_name LIKE ‘user%’;
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
# 输出结果
# PLAN_TABLE_OUTPUT
# ——————
# Plan hash value: 1234567890
#
# ————————————————
# | Id | Operation | Name | Rows |
# ————————————————
# | 0 | SELECT STATEMENT | | 100 |
# | 1 | TABLE ACCESS BY INDEX ROWID| FGEDU_USER| 100 |
# |* 2 | INDEX RANGE SCAN| IDX_FGEDU_USER_NAME| 100 |
# ————————————————
– 创建索引
SQL> CREATE INDEX idx_fgedu_user_name ON fgedu_user(user_name);
– 使用索引
SQL> SELECT * FROM fgedu_user WHERE user_name = ‘fgedu_user1’;
# 2. 查询优化
– 避免全表扫描
SQL> SELECT * FROM fgedu_user WHERE user_id = 1;
– 避免使用SELECT *
SQL> SELECT user_id, user_name FROM fgedu_user;
– 使用LIMIT限制结果集
SQL> SELECT * FROM fgedu_user LIMIT 10;
# 3. 连接优化
– 使用INNER JOIN代替子查询
SQL> SELECT u.user_id, u.user_name, o.order_id
FROM fgedu_user u
INNER JOIN fgedu_order o ON u.user_id = o.user_id;
– 使用小表驱动大表
SQL> SELECT u.user_id, u.user_name, o.order_id
FROM fgedu_order o
INNER JOIN fgedu_user u ON o.user_id = u.user_id;
# 4. 实际示例
– 优化前
SQL> SELECT * FROM fgedu_user WHERE user_name LIKE ‘%user%’;
– 优化后
SQL> SELECT * FROM fgedu_user WHERE user_name LIKE ‘user%’;
– 查看执行计划
SQL> EXPLAIN PLAN FOR SELECT * FROM fgedu_user WHERE user_name LIKE ‘user%’;
SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());
# 输出结果
# PLAN_TABLE_OUTPUT
# ——————
# Plan hash value: 1234567890
#
# ————————————————
# | Id | Operation | Name | Rows |
# ————————————————
# | 0 | SELECT STATEMENT | | 100 |
# | 1 | TABLE ACCESS BY INDEX ROWID| FGEDU_USER| 100 |
# |* 2 | INDEX RANGE SCAN| IDX_FGEDU_USER_NAME| 100 |
# ————————————————
3.3.2 存储过程优化
# 1. 减少SQL执行次数
– 优化前
SQL> CREATE PROCEDURE sp_update_users()
AS
BEGIN
FOR cur_user IN (SELECT user_id FROM fgedu_user) LOOP
UPDATE fgedu_user SET user_status = 0 WHERE user_id = cur_user.user_id;
END LOOP;
END;
– 优化后
SQL> CREATE PROCEDURE sp_update_users()
AS
BEGIN
UPDATE fgedu_user SET user_status = 0;
END;
# 2. 使用批量操作
– 优化前
SQL> CREATE PROCEDURE sp_insert_users()
AS
BEGIN
INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (1, ‘fgedu_user1’, ‘fgedu_user1@fgedu.net.cn’, 1);
INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (2, ‘fgedu_user2’, ‘fgedu_user2@fgedu.net.cn’, 1);
INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (3, ‘user3’, ‘user3@fgedu.net.cn’, 1);
END;
– 优化后
SQL> CREATE PROCEDURE sp_insert_users()
AS
BEGIN
INSERT ALL
INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (1, ‘fgedu_user1’, ‘fgedu_user1@fgedu.net.cn’, 1)
INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (2, ‘fgedu_user2’, ‘fgedu_user2@fgedu.net.cn’, 1)
INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (3, ‘user3’, ‘user3@fgedu.net.cn’, 1)
SELECT * FROM DUAL;
END;
# 3. 使用临时表
– 优化前
SQL> CREATE PROCEDURE sp_get_user_orders()
AS
BEGIN
SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u
INNER JOIN fgedu_order o ON u.user_id = o.user_id
WHERE u.user_status = 1;
END;
– 优化后
SQL> CREATE PROCEDURE sp_get_user_orders()
AS
BEGIN
CREATE GLOBAL TEMPORARY TABLE temp_user_orders AS
SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u
INNER JOIN fgedu_order o ON u.user_id = o.user_id
WHERE u.user_status = 1;
SELECT * FROM temp_user_orders;
END;
# 4. 实际示例
– 优化前
SQL> CREATE PROCEDURE sp_update_users()
AS
BEGIN
FOR cur_user IN (SELECT user_id FROM fgedu_user) LOOP
UPDATE fgedu_user SET user_status = 0 WHERE user_id = cur_user.user_id;
END LOOP;
END;
– 优化后
SQL> CREATE PROCEDURE sp_update_users()
AS
BEGIN
UPDATE fgedu_user SET user_status = 0;
END;
– 测试性能
SQL> CALL sp_update_users();
# 输出结果
# 优化前:执行时间10秒
# 优化后:执行时间0.1秒
– 优化前
SQL> CREATE PROCEDURE sp_update_users()
AS
BEGIN
FOR cur_user IN (SELECT user_id FROM fgedu_user) LOOP
UPDATE fgedu_user SET user_status = 0 WHERE user_id = cur_user.user_id;
END LOOP;
END;
– 优化后
SQL> CREATE PROCEDURE sp_update_users()
AS
BEGIN
UPDATE fgedu_user SET user_status = 0;
END;
# 2. 使用批量操作
– 优化前
SQL> CREATE PROCEDURE sp_insert_users()
AS
BEGIN
INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (1, ‘fgedu_user1’, ‘fgedu_user1@fgedu.net.cn’, 1);
INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (2, ‘fgedu_user2’, ‘fgedu_user2@fgedu.net.cn’, 1);
INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (3, ‘user3’, ‘user3@fgedu.net.cn’, 1);
END;
– 优化后
SQL> CREATE PROCEDURE sp_insert_users()
AS
BEGIN
INSERT ALL
INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (1, ‘fgedu_user1’, ‘fgedu_user1@fgedu.net.cn’, 1)
INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (2, ‘fgedu_user2’, ‘fgedu_user2@fgedu.net.cn’, 1)
INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (3, ‘user3’, ‘user3@fgedu.net.cn’, 1)
SELECT * FROM DUAL;
END;
# 3. 使用临时表
– 优化前
SQL> CREATE PROCEDURE sp_get_user_orders()
AS
BEGIN
SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u
INNER JOIN fgedu_order o ON u.user_id = o.user_id
WHERE u.user_status = 1;
END;
– 优化后
SQL> CREATE PROCEDURE sp_get_user_orders()
AS
BEGIN
CREATE GLOBAL TEMPORARY TABLE temp_user_orders AS
SELECT u.user_id, u.user_name, o.order_id, o.order_amount
FROM fgedu_user u
INNER JOIN fgedu_order o ON u.user_id = o.user_id
WHERE u.user_status = 1;
SELECT * FROM temp_user_orders;
END;
# 4. 实际示例
– 优化前
SQL> CREATE PROCEDURE sp_update_users()
AS
BEGIN
FOR cur_user IN (SELECT user_id FROM fgedu_user) LOOP
UPDATE fgedu_user SET user_status = 0 WHERE user_id = cur_user.user_id;
END LOOP;
END;
– 优化后
SQL> CREATE PROCEDURE sp_update_users()
AS
BEGIN
UPDATE fgedu_user SET user_status = 0;
END;
– 测试性能
SQL> CALL sp_update_users();
# 输出结果
# 优化前:执行时间10秒
# 优化后:执行时间0.1秒
风哥提示:数据库开发是一个持续的过程,需要根据业务需求和系统运行情况,不断调整和优化。建立完善的测试体系,是保障开发质量的关键。
Part04-生产案例与实战讲解
4.1 存储过程开发案例
4.1.1 案例描述
某企业需要开发一个存储过程,实现用户批量导入功能。
4.1.2 开发步骤
# 1. 需求分析
– 功能需求
– 批量导入用户数据
– 支持事务处理
– 支持错误处理
– 数据需求
– 用户ID
– 用户名
– 用户邮箱
– 用户状态
# 2. 存储过程开发
– 创建存储过程
SQL> CREATE PROCEDURE sp_batch_import_users()
AS
v_user_id INT;
v_user_name VARCHAR(50);
v_user_email VARCHAR(100);
v_user_status INT;
v_error_count INT := 0;
v_success_count INT := 0;
BEGIN
FOR cur_user IN (SELECT user_id, user_name, user_email, user_status FROM temp_users) LOOP
BEGIN
INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (cur_user.user_id, cur_user.user_name, cur_user.user_email, cur_user.user_status);
v_success_count := v_success_count + 1;
EXCEPTION
WHEN OTHERS THEN
v_error_count := v_error_count + 1;
PRINT ‘Error importing user: ‘ || cur_user.user_id || ‘, Error: ‘ || SQLERRM;
END;
END LOOP;
PRINT ‘Import completed. Success: ‘ || v_success_count || ‘, Error: ‘ || v_error_count;
END;
# 3. 测试存储过程
– 准备测试数据
SQL> CREATE TABLE temp_users (
user_id INT,
user_name VARCHAR(50),
user_email VARCHAR(100),
user_status INT
);
SQL> INSERT INTO temp_users VALUES (4, ‘user4’, ‘user4@fgedu.net.cn’, 1);
SQL> INSERT INTO temp_users VALUES (5, ‘user5’, ‘user5@fgedu.net.cn’, 1);
SQL> INSERT INTO temp_users VALUES (6, ‘user6’, ‘user6@fgedu.net.cn’, 1);
– 执行存储过程
SQL> CALL sp_batch_import_users();
# 输出结果
# Import completed. Success: 3, Error: 0
# 4. 验证结果
– 查询导入的用户
SQL> SELECT * FROM fgedu_user WHERE user_id IN (4, 5, 6);
# 输出结果
# USER_ID USER_NAME USER_EMAIL USER_STATUS CREATE_TIME
# ——– ———- ——————– ———— ——————-
# 4 user4 user4@fgedu.net.cn 1 2024-01-01 10:00:00
# 5 user5 user5@fgedu.net.cn 1 2024-01-01 10:00:00
# 6 user6 user6@fgedu.net.cn 1 2024-01-01 10:00:00
# 5. 实施结果
– 存储过程开发成功
– 批量导入功能正常
– 事务处理正常
– 错误处理正常
– 功能需求
– 批量导入用户数据
– 支持事务处理
– 支持错误处理
– 数据需求
– 用户ID
– 用户名
– 用户邮箱
– 用户状态
# 2. 存储过程开发
– 创建存储过程
SQL> CREATE PROCEDURE sp_batch_import_users()
AS
v_user_id INT;
v_user_name VARCHAR(50);
v_user_email VARCHAR(100);
v_user_status INT;
v_error_count INT := 0;
v_success_count INT := 0;
BEGIN
FOR cur_user IN (SELECT user_id, user_name, user_email, user_status FROM temp_users) LOOP
BEGIN
INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (cur_user.user_id, cur_user.user_name, cur_user.user_email, cur_user.user_status);
v_success_count := v_success_count + 1;
EXCEPTION
WHEN OTHERS THEN
v_error_count := v_error_count + 1;
PRINT ‘Error importing user: ‘ || cur_user.user_id || ‘, Error: ‘ || SQLERRM;
END;
END LOOP;
PRINT ‘Import completed. Success: ‘ || v_success_count || ‘, Error: ‘ || v_error_count;
END;
# 3. 测试存储过程
– 准备测试数据
SQL> CREATE TABLE temp_users (
user_id INT,
user_name VARCHAR(50),
user_email VARCHAR(100),
user_status INT
);
SQL> INSERT INTO temp_users VALUES (4, ‘user4’, ‘user4@fgedu.net.cn’, 1);
SQL> INSERT INTO temp_users VALUES (5, ‘user5’, ‘user5@fgedu.net.cn’, 1);
SQL> INSERT INTO temp_users VALUES (6, ‘user6’, ‘user6@fgedu.net.cn’, 1);
– 执行存储过程
SQL> CALL sp_batch_import_users();
# 输出结果
# Import completed. Success: 3, Error: 0
# 4. 验证结果
– 查询导入的用户
SQL> SELECT * FROM fgedu_user WHERE user_id IN (4, 5, 6);
# 输出结果
# USER_ID USER_NAME USER_EMAIL USER_STATUS CREATE_TIME
# ——– ———- ——————– ———— ——————-
# 4 user4 user4@fgedu.net.cn 1 2024-01-01 10:00:00
# 5 user5 user5@fgedu.net.cn 1 2024-01-01 10:00:00
# 6 user6 user6@fgedu.net.cn 1 2024-01-01 10:00:00
# 5. 实施结果
– 存储过程开发成功
– 批量导入功能正常
– 事务处理正常
– 错误处理正常
4.2 触发器开发案例
4.2.1 案例描述
某企业需要开发一个触发器,实现用户操作日志记录功能。
4.2.2 开发步骤
# 1. 需求分析
– 功能需求
– 记录用户操作日志
– 记录操作类型
– 记录操作时间
– 数据需求
– 用户ID
– 操作类型
– 操作时间
# 2. 创建日志表
– 创建用户日志表
SQL> CREATE TABLE fgedu_user_log (
log_id INT PRIMARY KEY,
user_id INT,
action VARCHAR(50),
action_time TIMESTAMP DEFAULT SYSDATE
);
– 创建序列
SQL> CREATE SEQUENCE seq_fgedu_user_log;
# 3. 创建触发器
– 创建触发器
SQL> CREATE TRIGGER trg_fgedu_user_log
AFTER INSERT OR UPDATE OR DELETE ON fgedu_user
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO fgedu_user_log (log_id, user_id, action, action_time)
VALUES (seq_fgedu_user_log.NEXTVAL, :NEW.user_id, ‘INSERT’, SYSDATE);
ELSIF UPDATING THEN
INSERT INTO fgedu_user_log (log_id, user_id, action, action_time)
VALUES (seq_fgedu_user_log.NEXTVAL, :NEW.user_id, ‘UPDATE’, SYSDATE);
ELSIF DELETING THEN
INSERT INTO fgedu_user_log (log_id, user_id, action, action_time)
VALUES (seq_fgedu_user_log.NEXTVAL, :OLD.user_id, ‘DELETE’, SYSDATE);
END IF;
END;
# 4. 测试触发器
– 插入数据
SQL> INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (7, ‘user7’, ‘user7@fgedu.net.cn’, 1);
– 更新数据
SQL> UPDATE fgedu_user SET user_status = 0 WHERE user_id = 7;
– 删除数据
SQL> DELETE FROM fgedu_user WHERE user_id = 7;
# 5. 验证结果
– 查询日志
SQL> SELECT * FROM fgedu_user_log WHERE user_id = 7;
# 输出结果
# LOG_ID USER_ID ACTION ACTION_TIME
# ——- ——– ——- ——————-
# 1 7 INSERT 2024-01-01 10:00:00
# 2 7 UPDATE 2024-01-01 10:00:01
# 3 7 DELETE 2024-01-01 10:00:02
# 6. 实施结果
– 触发器开发成功
– 日志记录功能正常
– 操作类型记录正常
– 操作时间记录正常
– 功能需求
– 记录用户操作日志
– 记录操作类型
– 记录操作时间
– 数据需求
– 用户ID
– 操作类型
– 操作时间
# 2. 创建日志表
– 创建用户日志表
SQL> CREATE TABLE fgedu_user_log (
log_id INT PRIMARY KEY,
user_id INT,
action VARCHAR(50),
action_time TIMESTAMP DEFAULT SYSDATE
);
– 创建序列
SQL> CREATE SEQUENCE seq_fgedu_user_log;
# 3. 创建触发器
– 创建触发器
SQL> CREATE TRIGGER trg_fgedu_user_log
AFTER INSERT OR UPDATE OR DELETE ON fgedu_user
FOR EACH ROW
BEGIN
IF INSERTING THEN
INSERT INTO fgedu_user_log (log_id, user_id, action, action_time)
VALUES (seq_fgedu_user_log.NEXTVAL, :NEW.user_id, ‘INSERT’, SYSDATE);
ELSIF UPDATING THEN
INSERT INTO fgedu_user_log (log_id, user_id, action, action_time)
VALUES (seq_fgedu_user_log.NEXTVAL, :NEW.user_id, ‘UPDATE’, SYSDATE);
ELSIF DELETING THEN
INSERT INTO fgedu_user_log (log_id, user_id, action, action_time)
VALUES (seq_fgedu_user_log.NEXTVAL, :OLD.user_id, ‘DELETE’, SYSDATE);
END IF;
END;
# 4. 测试触发器
– 插入数据
SQL> INSERT INTO fgedu_user (user_id, user_name, user_email, user_status)
VALUES (7, ‘user7’, ‘user7@fgedu.net.cn’, 1);
– 更新数据
SQL> UPDATE fgedu_user SET user_status = 0 WHERE user_id = 7;
– 删除数据
SQL> DELETE FROM fgedu_user WHERE user_id = 7;
# 5. 验证结果
– 查询日志
SQL> SELECT * FROM fgedu_user_log WHERE user_id = 7;
# 输出结果
# LOG_ID USER_ID ACTION ACTION_TIME
# ——- ——– ——- ——————-
# 1 7 INSERT 2024-01-01 10:00:00
# 2 7 UPDATE 2024-01-01 10:00:01
# 3 7 DELETE 2024-01-01 10:00:02
# 6. 实施结果
– 触发器开发成功
– 日志记录功能正常
– 操作类型记录正常
– 操作时间记录正常
4.3 应用开发案例
4.3.1 案例描述
某企业需要开发一个Java应用,实现用户管理功能。
4.3.2 开发步骤
# 1. 需求分析
– 功能需求
– 用户查询
– 用户添加
– 用户更新
– 用户删除
– 技术需求
– Java语言
– JDBC连接
– 事务处理
# 2. 数据库连接
– 创建数据库连接类
import java.sql.*;
public class DMConnection {
private static final String URL = “jdbc:dm://fgedu.localhost:5236/fgedudb”;
private static final String USER = “SYSDBA”;
private static final String PASSWORD = “SYSDBA”;
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USER, PASSWORD);
}
}
# 3. 用户查询功能
– 创建用户查询类
import java.sql.*;
public class UserQuery {
public static void queryUser(int userId) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DMConnection.getConnection();
String sql = “SELECT * FROM fgedu_user WHERE user_id = ?”;
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, userId);
rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(“User ID: ” + rs.getInt(“user_id”));
System.out.println(“User Name: ” + rs.getString(“user_name”));
System.out.println(“User Email: ” + rs.getString(“user_email”));
System.out.println(“User Status: ” + rs.getInt(“user_status”));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (rs != null) rs.close();
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
# 4. 用户添加功能
– 创建用户添加类
import java.sql.*;
public class UserAdd {
public static void addUser(int userId, String userName, String userEmail, int userStatus) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DMConnection.getConnection();
String sql = “INSERT INTO fgedu_user (user_id, user_name, user_email, user_status) VALUES (?, ?, ?, ?)”;
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, userId);
pstmt.setString(2, userName);
pstmt.setString(3, userEmail);
pstmt.setInt(4, userStatus);
int rows = pstmt.executeUpdate();
System.out.println(“Rows inserted: ” + rows);
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
# 5. 测试应用
– 创建测试类
public class UserManagementTest {
public static void main(String[] args) {
// 查询用户
UserQuery.queryUser(1);
// 添加用户
UserAdd.addUser(8, ‘user8’, ‘user8@fgedu.net.cn’, 1);
// 查询用户
UserQuery.queryUser(8);
}
}
# 输出结果
# User ID: 1
# User Name: fgedu_user1
# User Email: fgedu_user1@fgedu.net.cn
# User Status: 1
# Rows inserted: 1
# User ID: 8
# User Name: user8
# User Email: user8@fgedu.net.cn
# User Status: 1
# 6. 实施结果
– 应用开发成功
– 用户查询功能正常
– 用户添加功能正常
– 事务处理正常
– 功能需求
– 用户查询
– 用户添加
– 用户更新
– 用户删除
– 技术需求
– Java语言
– JDBC连接
– 事务处理
# 2. 数据库连接
– 创建数据库连接类
import java.sql.*;
public class DMConnection {
private static final String URL = “jdbc:dm://fgedu.localhost:5236/fgedudb”;
private static final String USER = “SYSDBA”;
private static final String PASSWORD = “SYSDBA”;
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USER, PASSWORD);
}
}
# 3. 用户查询功能
– 创建用户查询类
import java.sql.*;
public class UserQuery {
public static void queryUser(int userId) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = DMConnection.getConnection();
String sql = “SELECT * FROM fgedu_user WHERE user_id = ?”;
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, userId);
rs = pstmt.executeQuery();
while (rs.next()) {
System.out.println(“User ID: ” + rs.getInt(“user_id”));
System.out.println(“User Name: ” + rs.getString(“user_name”));
System.out.println(“User Email: ” + rs.getString(“user_email”));
System.out.println(“User Status: ” + rs.getInt(“user_status”));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (rs != null) rs.close();
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
# 4. 用户添加功能
– 创建用户添加类
import java.sql.*;
public class UserAdd {
public static void addUser(int userId, String userName, String userEmail, int userStatus) {
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DMConnection.getConnection();
String sql = “INSERT INTO fgedu_user (user_id, user_name, user_email, user_status) VALUES (?, ?, ?, ?)”;
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, userId);
pstmt.setString(2, userName);
pstmt.setString(3, userEmail);
pstmt.setInt(4, userStatus);
int rows = pstmt.executeUpdate();
System.out.println(“Rows inserted: ” + rows);
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
# 5. 测试应用
– 创建测试类
public class UserManagementTest {
public static void main(String[] args) {
// 查询用户
UserQuery.queryUser(1);
// 添加用户
UserAdd.addUser(8, ‘user8’, ‘user8@fgedu.net.cn’, 1);
// 查询用户
UserQuery.queryUser(8);
}
}
# 输出结果
# User ID: 1
# User Name: fgedu_user1
# User Email: fgedu_user1@fgedu.net.cn
# User Status: 1
# Rows inserted: 1
# User ID: 8
# User Name: user8
# User Email: user8@fgedu.net.cn
# User Status: 1
# 6. 实施结果
– 应用开发成功
– 用户查询功能正常
– 用户添加功能正常
– 事务处理正常
生产环境建议:在数据库开发完成后,要进行充分的测试,确保开发的功能满足业务需求。建立完善的测试体系,确保开发的质量。定期进行代码审查,提高代码质量。
Part05-风哥经验总结与分享
5.1 数据库开发最佳实践
DM数据库开发最佳实践:
- 充分分析:在开发前进行充分的需求分析,确保开发的功能满足业务需求
- 规范编码:遵循编码规范,提高代码可读性和可维护性
- 充分测试:在开发后进行充分的测试,确保开发的质量
- 性能优化:优化SQL语句和存储过程,提高数据库性能
- 异常处理:完善异常处理机制,提高系统稳定性
- 文档记录:记录开发过程和结果,便于后续维护
- 团队协作:与团队协作,共同完成开发工作
- 经验积累:积累开发经验,提高开发效率
- 工具使用:使用合适的开发工具,提高开发效率
- 最佳实践:遵循最佳实践,避免常见错误
5.2 常见问题与解决方案
# 1. SQL语句错误
– 症状:SQL语句执行失败
– 原因:SQL语法错误、表名错误、字段名错误
– 解决方案:检查SQL语法、检查表名、检查字段名
# 2. 存储过程错误
– 症状:存储过程执行失败
– 原因:语法错误、逻辑错误、权限不足
– 解决方案:检查语法、检查逻辑、检查权限
# 3. 触发器错误
– 症状:触发器执行失败
– 原因:语法错误、逻辑错误、权限不足
– 解决方案:检查语法、检查逻辑、检查权限
# 4. 连接错误
– 症状:数据库连接失败
– 原因:连接参数错误、网络问题、权限不足
– 解决方案:检查连接参数、检查网络、检查权限
# 5. 性能问题
– 症状:数据库性能下降
– 原因:SQL语句不优化、索引不合理、资源不足
– 解决方案:优化SQL语句、优化索引、增加资源
– 症状:SQL语句执行失败
– 原因:SQL语法错误、表名错误、字段名错误
– 解决方案:检查SQL语法、检查表名、检查字段名
# 2. 存储过程错误
– 症状:存储过程执行失败
– 原因:语法错误、逻辑错误、权限不足
– 解决方案:检查语法、检查逻辑、检查权限
# 3. 触发器错误
– 症状:触发器执行失败
– 原因:语法错误、逻辑错误、权限不足
– 解决方案:检查语法、检查逻辑、检查权限
# 4. 连接错误
– 症状:数据库连接失败
– 原因:连接参数错误、网络问题、权限不足
– 解决方案:检查连接参数、检查网络、检查权限
# 5. 性能问题
– 症状:数据库性能下降
– 原因:SQL语句不优化、索引不合理、资源不足
– 解决方案:优化SQL语句、优化索引、增加资源
5.3 数据库开发检查清单
DM数据库开发检查清单:
- 需求分析检查:需求分析是否充分,功能需求是否明确
- 数据库设计检查:数据库设计是否合理,数据结构是否规范
- SQL开发检查:SQL语句是否正确,性能是否满足要求
- 存储过程检查:存储过程是否正确,逻辑是否合理
- 函数检查:函数是否正确,返回值是否正确
- 触发器检查:触发器是否正确,触发条件是否合理
- 应用开发检查:应用开发是否完成,功能是否正常
- 测试验证检查:测试是否充分,测试结果是否正常
- 性能优化检查:性能是否满足要求,优化是否完成
- 文档记录检查:开发过程是否记录,开发文档是否完善
持续改进:数据库开发是一个持续的过程,需要根据业务需求和系统运行情况,不断调整和优化。建立完善的测试体系,是保障开发质量的关键。定期进行代码审查,提高代码质量。
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
