겉보기에 선호되는 접근법
나는 다른 사람들, 특히 일부 의견을 바탕으로 이미 다음과 같은 테스트를 받았다는 인상을 받았습니다. 그러나 내 테스트에 따르면이 두 가지 방법은 .NET을 통해 연결할 때도 실제로 DB 수준에서 작동합니다 SqlClient
. 이것들은 다른 사람들에 의해 테스트되고 검증되었습니다.
서버 전체
당신은 설정할 수있는 사용자 옵션 은 비트 단위 현재 무엇이든 할 서버 구성 설정을 OR
64 (값과 에드 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;
수동으로 실행 해야합니다. 고려해야 할 몇 가지 방법이 있습니다.
경우 당신이 엔티티 프레임 워크 6 (이상)을 사용하고, 당신도 시도 할 수 있습니다 :
Database.ExecuteSqlCommand 사용 : context.Database.ExecuteSqlCommand("SET ARITHABORT ON;");
이상적으로는 각 쿼리마다가 아닌 DB 연결을 연 후에 한 번 실행됩니다.
다음 중 하나를 통해 인터셉터 를 작성하십시오 .
이를 통해 SQL을 실행하기 전에 수정할 수 있습니다.이 경우 단순히 접두사로 다음을 지정할 수 있습니다 SET ARITHABORT ON;
. 여기서 단점은 로컬 변수를 저장하여 실행 여부를 캡처하고 매번 테스트합니다 (실제로 많은 추가 작업은 아니지만 사용하는 경우 ExecuteSqlCommand
) 아마도 더 쉬울 것입니다).
이 중 하나를 사용하면 기존 코드를 변경하지 않고 한 지점에서이를 처리 할 수 있습니다.
그렇지 않으면 다음과 유사한 래퍼 메소드를 작성할 수 있습니다.
public static SqlDataReader ExecuteReaderWithSetting(SqlCommand CommandToExec)
{
CommandToExec.CommandText = "SET ARITHABORT ON;\n" + CommandToExec.CommandText;
return CommandToExec.ExecuteReader();
}
그런 다음 현재 _Reader = _Command.ExecuteReader();
참조를로 변경하십시오 _Reader = ExecuteReaderWithSetting(_Command);
.
이렇게하면 단일 위치에서 설정을 처리 할 수 있으며 대부분 찾기 및 바꾸기를 통해 수행 할 수있는 최소한의 간단한 코드 변경 만 필요합니다.
더 좋은 방법은 ( 그렇지 이 연결 레벨 설정이기 때문에 파트 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을 확장하는 클래스를 만들어 더 많은 OO 스타일로 구현할 수 있습니다.
또는 더 나은 아직 ( 그 밖에 3 부), 당신은 연결 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
.
완벽을 기하기 위해 작동하지 않는 몇 가지 사항이 있습니다.
- 로그온 트리거 : 동일한 세션에서 실행 중이거나 명시 적으로 시작된 트랜잭션 내에서 실행되는 경우에도 트리거는 여전히 하위 프로세스이므로 해당 설정 (
SET
명령, 로컬 임시 테이블 등)은 로컬 이므로 해당 세션이 생존하지 않습니다. 하위 프로세스의 끝
SET ARITHABORT ON;
각 저장 프로 시저의 시작 부분에 추가 :
- 저장 프로 시저 수가 증가함에 따라 기존 프로젝트에 많은 작업이 필요합니다.
- 이것은 임시 쿼리에 도움이되지 않습니다