外观
SQLite视图、触发器与存储过程
本文档详细介绍 SQLite 视图、触发器和存储过程的创建与使用方法。
视图
什么是视图
视图是一个虚拟表,其内容由查询定义。视图本身不存储数据,而是根据定义查询底层表的数据。
视图的优点
- 简化查询:将复杂查询封装为视图,简化应用程序代码
- 数据安全:只暴露必要的数据,隐藏敏感信息
- 逻辑独立性:当底层表结构变化时,只需修改视图定义,不需要修改应用程序
创建视图
sql
CREATE [TEMPORARY] [VIEW] [IF NOT EXISTS] view_name AS SELECT_statement;示例
sql
-- 创建简单视图
CREATE VIEW view_active_users AS
SELECT id, name, email
FROM users
WHERE active = 1;
-- 创建复杂视图
CREATE VIEW view_user_orders AS
SELECT u.id AS user_id, u.name, o.id AS order_id, o.product, o.total, o.created_at
FROM users u
JOIN orders o ON u.id = o.user_id
ORDER BY o.created_at DESC;查看视图
sql
.tables -- 视图会显示在表列表中
.schema view_name更新视图
sql
-- SQLite 支持通过视图更新底层表,但有一定限制
-- 视图必须满足以下条件才能更新:
-- 1. 视图定义中只包含一个表
-- 2. 视图定义中不包含 DISTINCT、GROUP BY、HAVING、UNION 等
-- 更新视图示例
UPDATE view_active_users
SET name = 'New Name'
WHERE id = 1;删除视图
sql
DROP VIEW [IF EXISTS] view_name;触发器
什么是触发器
触发器是一种特殊的存储过程,当指定的事件发生时自动执行。
触发器类型
- BEFORE 触发器:在事件发生前执行
- AFTER 触发器:在事件发生后执行
触发事件
- INSERT:插入数据时触发
- UPDATE:更新数据时触发
- DELETE:删除数据时触发
创建触发器
sql
CREATE [TEMPORARY] TRIGGER [IF NOT EXISTS] trigger_name
{BEFORE | AFTER} {INSERT | UPDATE | DELETE} ON table_name
[FOR EACH ROW] [WHEN condition]
BEGIN
-- 触发器逻辑
END;示例
sql
-- 插入前触发器
CREATE TRIGGER before_user_insert
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
-- 设置默认值
IF NEW.created_at IS NULL THEN
SET NEW.created_at = CURRENT_TIMESTAMP;
END IF;
-- 验证数据
IF NEW.email IS NULL OR NEW.email = '' THEN
RAISE(ABORT, 'Email is required');
END IF;
END;
-- 更新后触发器
CREATE TRIGGER after_user_update
AFTER UPDATE ON users
FOR EACH ROW
BEGIN
-- 记录日志
INSERT INTO user_audit_logs (user_id, action, old_value, new_value, changed_at)
VALUES (OLD.id, 'UPDATE', JSON_OBJECT('email', OLD.email), JSON_OBJECT('email', NEW.email), CURRENT_TIMESTAMP);
END;
-- 删除前触发器
CREATE TRIGGER before_order_delete
BEFORE DELETE ON orders
FOR EACH ROW
BEGIN
-- 级联删除相关数据
DELETE FROM order_items WHERE order_id = OLD.id;
-- 记录日志
INSERT INTO order_audit_logs (order_id, action, deleted_at)
VALUES (OLD.id, 'DELETE', CURRENT_TIMESTAMP);
END;查看触发器
sql
.schema trigger_name删除触发器
sql
DROP TRIGGER [IF EXISTS] trigger_name;存储过程
什么是存储过程
存储过程是一组预编译的 SQL 语句,用于执行特定的操作。
SQLite 对存储过程的支持
SQLite 本身不直接支持存储过程,但可以通过以下方式实现类似功能:
- 使用触发器:通过触发器实现自动执行的逻辑
- 使用 SQLite 扩展:安装第三方扩展,如 SQLite3 Multiple Statement
- 在应用层实现:在应用程序中封装复杂逻辑
使用 SQLite 扩展实现存储过程
sql
-- 加载扩展
.load /path/to/libsqlite3-multiple-statement.so
-- 创建存储过程(模拟)
CREATE PROCEDURE sp_create_user(name TEXT, email TEXT)
BEGIN
INSERT INTO users (name, email) VALUES (name, email);
SELECT last_insert_rowid();
END;
-- 调用存储过程(模拟)
CALL sp_create_user('Test User', 'test@example.com');在应用层实现存储过程
python
import sqlite3
def sp_create_user(conn, name, email):
cursor = conn.cursor()
cursor.execute('INSERT INTO users (name, email) VALUES (?, ?)', (name, email))
user_id = cursor.lastrowid
conn.commit()
return user_id
# 使用示例
conn = sqlite3.connect('database.db')
user_id = sp_create_user(conn, 'Test User', 'test@example.com')
conn.close()常见问题(FAQ)
Q: SQLite 支持真正的存储过程吗?
A: 不,SQLite 本身不直接支持存储过程,但可以通过触发器、扩展或应用层实现类似功能。
Q: 视图可以更新吗?
A: 是的,但有一定限制,视图必须满足特定条件才能更新。
Q: 如何查看触发器定义?
A: 使用 .schema trigger_name 命令查看触发器定义。
Q: 触发器可以嵌套吗?
A: 是的,一个触发器的执行可以触发另一个触发器,但要注意避免无限循环。
