sql-server – 使SqlClient默认为ARITHABORT ON
起主要做的工作是:我正在行使MS SQL Server 2008和兼容级别为80的数据库,并行使.Net的System.Data.SqlClient.SqlConnection毗连到它. 出于机能缘故起因,我建设了一个索引视图.因此,必要行使ARITHABORT ON对视图中引用的表举办更新.可是,说明器表现SqlClient与ARITHABORT OFF毗连,因此对这些表的更新失败. 是否有中央设置配置使SqlClient行使ARITHABORT ON?我能找到的最好的要领是每次打开毗连时手动执行,但更新现有的代码库来执行此操纵将是一项相等大的使命,以是我盼愿找到更好的要领. 办理要领看似首选的要领我的印象是,其他人已经测试了以下内容,出格是基于一些评述.但我的测试表白,这两种要领确实可以在数据库级别事变,纵然通过.NET SqlClient毗连也是云云.这些已颠末其他人的测试和验证. 处事器范畴 您可以将user options处事器设置配置配置为当前按位与64举办ORING(ARITHABORT的值).假如您不行使按位OR(|)而是直接分派(=),那么您将破除已启用的任何其他现有选项. DECLARE @Value INT; SELECT @Value = CONVERT(INT,[value_in_use]) --[config_value] | 64 FROM sys.configurations sc WHERE sc.[name] = N'user options'; IF ((@Value & 64) <> 64) BEGIN PRINT 'Enabling ARITHABORT...'; SET @Value = (@Value | 64); EXEC sp_configure N'user options',@Value; RECONFIGURE; END; EXEC sp_configure N'user options'; -- verify current state 数据库级 这可以通过ALTER DATABASE SET按数据库配置: USE [master]; IF (EXISTS( SELECT * FROM sys.databases db WHERE db.[name] = N'{database_name}' AND db.[is_arithabort_on] = 0 )) BEGIN PRINT 'Enabling ARITHABORT...'; ALTER DATABASE [{database_name}] SET ARITHABORT ON WITH NO_WAIT; END; 更换要领 不太好的动静是我已经对这个主题举办了大量的搜刮,功效发明多年来许多其他人已经对这个主题举办了大量的搜刮,而且没有步伐设置这个举动SqlClient.一些MSDN文档体现它可以通过ConnectionString完成,可是没有应承变动这些配置的要害字.另一个文档体现可以通过客户端收集设置/设置打点器举办变动,但这好像也不行能.因此,相等不幸的是,您必要执行SET ARITHABORT ON;手动.以下是一些必要思量的要领: 假如您行使的是Entity Framework 6(或更新版本),您可以实行: >行使Database.ExecuteSqlCommand:context.Database.ExecuteSqlCommand(“SET ARITHABORT ON;”); > DbConfiguration.AddInterceptor 这将应承您在执行之前修改SQL,在这种环境下,您只需在其前面加上:SET ARITHABORT ON;.这里的弱点是它将是每个查询,除非你存储一个局部变量来捕捉它是否已被执行的状态而且每次都举办测试(这现实上不是那么多特另外事变,而是行使ExecuteSqlCommand也许更轻易). 个中任何一个都应承您在一个位置处理赏罚此题目,而无需变动任何现有代码. ELSE,您可以建设一个执行此操纵的包装器要领,相同于: public static SqlDataReader ExecuteReaderWithSetting(SqlCommand CommandToExec) { CommandToExec.CommandText = "SET ARITHABORT ON;n" + CommandToExec.CommandText; return CommandToExec.ExecuteReader(); } 然后只需变动当前的_Reader = _Command.ExecuteReader();引用是_Reader = ExecuteReaderWithSetting(_Command);. 这样做还应承在单个位置处理赏罚配置,同时仅必要少少且简朴的代码变动,这些变动凡是可通过Find& amp;改换. 更好的是(其他第2部门),由于这是一个毗连级别配置,以是不必要为每个SqlCommand.Execute __()挪用执行它.因此,不是为ExecuteReader()建设包装器,而是为Connection.Open()建设一个包装器: public static void OpenAndSetArithAbort(SqlConnection MyConnection) { using (SqlCommand _Command = MyConnection.CreateCommand()) { _Command.CommandType = CommandType.Text; _Command.CommandText = "SET ARITHABORT ON;"; MyConnection.Open(); _Command.ExecuteNonQuery(); } return; } 然后只需替代现有的_Connection.Open();引用为OpenAndSetArithAbort(_Connection);. 通过建设扩展SqlCommand或SqlConnection的Class,可以以更多OO样式实现上述两个设法. 可能更好(其它第3部门),您可觉得Connection StateChange建设一个变乱处理赏罚措施,并在毗连从Closed变动为Open时配置属性,如下所示: protected static void OnStateChange(object sender,StateChangeEventArgs args) { if (args.OriginalState == ConnectionState.Closed && args.CurrentState == ConnectionState.Open) { using (SqlCommand _Command = ((SqlConnection)sender).CreateCommand()) { _Command.CommandType = CommandType.Text; _Command.CommandText = "SET ARITHABORT ON;"; _Command.ExecuteNonQuery(); } } } 有了这个,您只必要在建设SqlConnection实例的每个位置添加以下内容: _Connection.StateChange += new StateChangeEventHandler(OnStateChange); 不必要变动现有代码.我方才在一个小型节制台应用措施中实行了这种要领,通过打印SELECT SESSIONPROPERTY(‘ARITHABORT’);的功效举办测试.它返回1,可是假如我禁用变乱处理赏罚措施,它将返回0. 为了完备起见,以下是一些不起浸染的工作(基础不是可能没有结果): > Logon Triggers:触发器,纵然在统一会话中运行,纵然在显式启动的事宜中运行,如故是一个子历程,因此其配置(SET呼吁,当地姑且表等)是当地的,不是在该子流程竣事时幸存下来. >这必要对现有项目举办大量事变,尤其是跟着存储进程数目的增进>这无助于即席查询 (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |