FluentMigrator中Try-Catch无法捕获SQL Server 2017不支持ADD SENSITIVITY CLASSIFICATION命令的异常问题求助
解决FluentMigrator中Execute.Sql异常无法捕获的问题
这个问题我之前也碰到过,核心原因是FluentMigrator的Execute.Sql()并不是立即执行SQL语句——它只是把这条SQL封装成一个执行表达式,添加到当前迁移的任务队列里。真正的SQL执行逻辑,要等到MigrationRunner统一处理所有迁移表达式的时候才会触发,这时候已经跳出了你写的AddSensitivityClassificationSql方法的try-catch范围,所以局部的catch根本捕获不到异常。
下面给你几个可行的解决方案,按推荐优先级排序:
方案一:提前检测SQL Server版本,跳过不支持的命令
既然知道ADD SENSITIVITY CLASSIFICATION是SQL Server 2019(主版本号15)才引入的,那我们可以先查询目标数据库的版本,只在版本符合要求时执行这条命令:
public void AddSensitivityClassificationSql(string schema, string table, string column, string label, string informationType, string rank) { // 查询SQL Server主版本号(2017是14,2019是15,2022是16) var versionQueryResult = Execute.Sql("SELECT CAST(SERVERPROPERTY('ProductMajorVersion') AS INT)").First(); var majorVersion = Convert.ToInt32(versionQueryResult); if (majorVersion >= 15) { // 仅在SQL Server 2019及以上版本执行敏感分类命令 Execute.Sql($@"ADD SENSITIVITY CLASSIFICATION TO [{schema}].[{table}].[{column}] WITH (LABEL = '{label}', INFORMATION_TYPE = '{informationType}', RANK = {rank})"); } else { Console.WriteLine("当前SQL Server版本低于2019,不支持敏感分类命令,已跳过执行"); } }
这个方案从根源上避免了异常的产生,是最稳妥的做法。
方案二:全局捕获迁移执行阶段的异常
如果你需要捕获所有迁移过程中可能出现的异常,可以在调用MigrateUp()的外层代码添加try-catch,而不是在迁移方法内部处理:
// 这里是你初始化MigrationRunner的代码 var runner = CreateYourMigrationRunner(); try { runner.MigrateUp(); } catch (Exception ex) { Console.WriteLine($"迁移执行失败:{ex.ToString()}"); // 这里可以添加异常处理逻辑,比如日志记录、回滚操作等 }
这种方式能捕获所有迁移执行阶段抛出的异常,包括你遇到的这个SQL语法错误。
方案三:自定义处理器捕获特定异常
如果需要针对特定SQL的异常做个性化处理(比如忽略敏感分类的错误,继续执行其他迁移),可以自定义SqlServerProcessor子类,重写执行方法来捕获异常:
public class CustomSqlServerProcessor : SqlServerProcessor { public CustomSqlServerProcessor(IDbConnection connection, IMigrationGenerator generator, IAnnouncer announcer, ProcessorOptions options, IDbFactory factory) : base(connection, generator, announcer, options, factory) { } public override int ExecuteNonQuery(string sql) { try { return base.ExecuteNonQuery(sql); } catch (SqlException ex) { // 判断是否是敏感分类的语法错误(错误号102,消息包含SENSITIVITY) if (ex.Number == 102 && ex.Message.Contains("SENSITIVITY")) { Announcer.Warn($"跳过不支持的敏感分类SQL:{sql}"); return 0; // 返回0表示"执行成功",避免中断后续迁移 } // 其他异常正常抛出,不影响原有逻辑 throw; } } }
之后在配置FluentMigrator的时候,替换默认的处理器为这个自定义类即可。
内容的提问来源于stack exchange,提问作者rplusg
相关产品推荐
相关产品推荐

