悠悠楠杉
MySQL触发器实战:数据校验与格式转换的自动化处理
sql
CREATE TRIGGER beforearticlekeywords
BEFORE INSERT ON articles FOR EACH ROW
BEGIN
IF NEW.keywords IS NOT NULL THEN
-- 替换中文逗号为英文逗号
SET NEW.keywords = REPLACE(NEW.keywords, ',', ',');
-- 去除重复关键词
SET NEW.keywords = (
SELECT GROUP_CONCAT(DISTINCT TRIM(SUBSTRING_INDEX(
SUBSTRING_INDEX(
NEW.keywords,
',',
numbers.n
),
',',
-1
)) SEPARATOR ',')
FROM (
SELECT 1 n UNION SELECT 2 UNION SELECT 3 UNION
SELECT 4 UNION SELECT 5 UNION SELECT 6
) numbers
WHERE numbers.n <= 1 + LENGTH(NEW.keywords) - LENGTH(REPLACE(NEW.keywords, ',', ''))
);
END IF;
END;
四、格式转换高级技巧
处理HTML内容净化
sql
CREATE TRIGGER beforecontentupdate
BEFORE UPDATE ON articles FOR EACH ROW
BEGIN
-- 移除危险标签但保留基础排版
SET NEW.content = REGEXPREPLACE(
REGEXPREPLACE(
NEW.content,
'<script[^>]>.?|<iframe[^>]>.?',
''
),
'<(?!b|i|p|br|ul|ol|li|h[1-6])([a-z][a-z0-9])[^>]?>',
''
);
-- 正文长度控制
IF CHAR_LENGTH(NEW.content) < 500 THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '正文内容需大于500字';
END IF;
END;
多字段关联校验
sql
CREATE TRIGGER beforearticlepublish
BEFORE INSERT ON articles FOR EACH ROW
BEGIN
-- 描述自动生成逻辑
IF NEW.description IS NULL OR NEW.description = '' THEN
SET NEW.description = CONCAT(
SUBSTRING(
REPLACE(
REPLACE(NEW.content, '\n', ' '),
'\r', ''
), 1, 150
), '...'
);
END IF;
-- 关键词与标题一致性检查
IF NEW.keywords NOT LIKE CONCAT('%', SUBSTRING_INDEX(NEW.title, ' ', 1), '%') THEN
INSERT INTO trigger_warnings
VALUES (NEW.id, 'WARN', '关键词未包含标题核心词');
END IF;
END;
五、性能优化与避坑指南
- 索引策略:触发器内查询的字段必须建立索引
- 错误处理:使用SIGNAL SQLSTATE返回友好错误
- 执行顺序:多个触发器通过命名规范控制执行顺序(如01、02前缀)
- 调试技巧:
sql SHOW TRIGGERS FROM database_name; SELECT * FROM information_schema.TRIGGERS;
实际项目中,建议将复杂逻辑拆分为存储过程,触发器仅做调用。某电商平台统计显示,合理使用触发器后数据异常率下降63%,同时减少约40%的应用层校验代码。但需注意,过度使用可能导致级联触发问题,建议单个表的触发器不超过5个。