修改被CHECK约束引用的自定义函数无需删除约束的方案咨询
解决方案
禁用CHECK约束仅会停止约束对数据插入、更新操作的校验逻辑,不会移除SQL Server元数据中约束和函数的依赖关联,因此删除函数操作依然会被阻塞。
方法1:直接修改函数(最优,完全不需要操作CHECK约束)
不需要删除原有函数,直接使用ALTER FUNCTION语句更新函数逻辑即可,仅需保证修改前后函数的签名(参数数量、参数类型、返回值类型)完全一致,就不会触发依赖校验。
示例代码:
ALTER FUNCTION LibelleCodeMatch ( @TypeParam VARCHAR(50), -- 需和原有参数类型、顺序保持完全一致 @CodeParam VARCHAR(50) -- 需和原有参数类型、顺序保持完全一致 ) RETURNS INT -- 需和原有返回值类型保持完全一致 AS BEGIN -- 此处编写更新后的函数逻辑 IF @TypeParam = 'PAYS' AND @CodeParam IN ('CN','US','FR') RETURN 1 RETURN 0 END GO
修改完成后原有CHECK约束不需要做任何调整,后续会自动调用新版本的函数执行数据校验。
可选操作:函数更新完成后恢复约束校验
如果需要恢复CHECK约束的校验能力,可按需执行以下语句:
-- 仅启用约束,不验证存量数据(速度快,但约束会标记为非信任,优化器不会基于该约束优化执行计划) EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL' -- 启用约束同时验证存量数据(速度慢,约束会标记为受信任,优化器可基于该约束优化执行计划) EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL'
方法2:仅操作关联约束(适用于必须删除重建函数的场景)
如果特殊场景下必须删除重建函数,可以仅处理和该函数关联的CHECK约束,不需要修改其他不相关的约束:
- 首先查询所有依赖
LibelleCodeMatch的CHECK约束:
SELECT c.name AS ConstraintName, t.name AS TableName, c.definition AS ConstraintDefinition FROM sys.check_constraints c JOIN sys.tables t ON c.parent_object_id = t.object_id WHERE c.definition LIKE '%LibelleCodeMatch%'
- 备份查询出来的约束定义后,删除这部分约束,再执行函数的删除重建操作,最后用备份的定义重建CHECK约束即可。
内容的提问来源于stack exchange,提问作者Ludovic Aubert
相关产品推荐
相关产品推荐

