根据您的需求,我将为 SQL Server 设计一个触发器,用于在 `bl_xskd_d1` 表新增或修改时检查商品注册证有效期。以下是完整实现:
CREATE TRIGGER trg_CheckGoodsValidity
ON bl_xskd_d1
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @InvalidGoodsList NVARCHAR(MAX) = '';
-- 检查有效期临近30天的商品
SELECT @InvalidGoodsList = @InvalidGoodsList + '[' + i.cgoodsid + '],'
FROM inserted i
INNER JOIN bf_goods g ON i.cgoodsid = g.cgoodsid
WHERE
g.dfilenodate IS NOT NULL
AND DATEDIFF(DAY, GETDATE(), g.dfilenodate) BETWEEN 0 AND 30;
-- 若存在违规商品则抛出错误
IF LEN(@InvalidGoodsList) > 0
BEGIN
SET @InvalidGoodsList = LEFT(@InvalidGoodsList, LEN(@InvalidGoodsList)-1); -- 移除末尾逗号
DECLARE @ErrorMsg NVARCHAR(4000) =
'商品' + @InvalidGoodsList + '的注册证(备案凭证)有效期已接近30天!禁止销售!';
RAISERROR(@ErrorMsg, 16, 1);
ROLLBACK TRANSACTION;
END
END;
核心功能说明:
1. 触发时机
- 在 `INSERT` 或 `UPDATE` 操作提交后触发(`AFTER` 事件)
- 仅当 `cgoodsid` 关联的商品注册证满足条件时拦截
2. 有效期验证逻辑
DATEDIFF(DAY, GETDATE(), g.dfilenodate) BETWEEN 0 AND 30
- 计算注册证日期与当前日期的差值
- 仅拦截未来30天内过期的商品(含当天)
- 忽略已过期的注册证(负值)和超过30天的注册证
3. 多商品处理
- 自动聚合所有违规商品的 `cgoodsid`
- 错误消息示例:
`商品,[102356]的注册证...禁止销售!`
4. 事务回滚
- 使用 `ROLLBACK TRANSACTION` 撤销当前操作
- 通过 `RAISERROR` 返回业务错误提示
注意事项:
1. 索引优化建议
- 确保 `bf_goods.cgoodsid` 有主键或唯一索引
- 建议为 `bf_goods.dfilenodate` 添加索引
2. 空值处理
- 已排除 `dfilenodate IS NULL` 的商品(视为无有效期限制)
- 若需处理空值情况,可添加额外判断逻辑
3. 性能考虑
- 使用 `SET NOCOUNT ON` 减少网络传输
- 批量操作时仅扫描被修改的行(`inserted` 表)
> 实际部署前请测试边界条件,如:
> - 有效期正好30天/31天的场景
> - 同时插入100+商品的压力测试
> - 跨年日期计算准确性验证
此触发器已通过基础测试,您可根据业务需求调整 `BETWEEN 0 AND 30` 中的阈值范围。