IT TIP

SQLCommand에 매개 변수를 전달하는 가장 좋은 방법은 무엇입니까?

itqueen 2021. 1. 10. 19:42
반응형

SQLCommand에 매개 변수를 전달하는 가장 좋은 방법은 무엇입니까?


SQLCommand에 매개 변수를 전달하는 가장 좋은 방법은 무엇입니까? 넌 할 수있어:

cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob";

또는

cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob";

또는

cmd.Parameters.Add("@Name").Value = "Bob";

첫 번째는 성능면에서나 오류 검사면에서 "더 나은"것 같습니다. 하지만 좀 더 확실히 알고 싶습니다.


를 사용할 수도 AddWithValue()있지만 잘못된 암시 적 형식 변환의 가능성을 알고 있어야합니다.

cmd.Parameters.AddWithValue("@Name", "Bob");

거기에서 무슨 일이 일어나고 있습니까?

의 여러 오버로드에 대한 매개 변수 목록을 인용합니다 Add. SqlParameter클래스의 생성자 오버로드에 직접 해당하는 편리한 메서드입니다 . 기본적으로 호출 한 편의 메서드와 동일한 서명이있는 생성자를 사용하여 매개 변수 개체를 생성 한 다음 다음과 같이 호출 SqlParameterCollection.Add(SqlParameter)합니다.

SqlParameter foo = new SqlParameter(parameterName, dbType, size);
this.Add(foo);

AddWithValue비슷하지만 훨씬 더 편리하고 값을 설정합니다. 그러나 실제로 프레임 워크 결함을 해결하기 위해 도입되었습니다. MSDN을 인용하려면

그 오버로드는 Add문자열을 사용하고 객체는 a를 사용하는 SqlParameterCollection.Add오버로드 StringSqlDbType문자열과 함께 정수를 전달하는 것이 매개 변수 값 또는 해당 SqlDbType으로 해석 될 수 있는 열거 형 값 과의 모호성 때문에 더 이상 사용되지 않습니다 . AddWithValue이름과 값을 지정하여 매개 변수를 추가 할 때마다 사용하십시오 .

SqlParameter클래스 의 생성자 오버로드는 인스턴스 속성을 설정하기위한 단순한 편의입니다. 성능에 약간의 영향을 미치면서 코드를 단축합니다. 생성자는 setter 메서드를 우회하고 private 멤버에서 직접 작동 할 수 있습니다. 차이가 있다면 그다지 많지 않을 것입니다.

어떻게해야합니까?

다음 사항에 유의하십시오 (MSDN에서).

양방향 및 출력 매개 변수와 반환 값의 경우 값을 설정해야합니다 Size. 입력 매개 변수에는 필요하지 않으며, 명시 적으로 설정하지 않은 경우 매개 변수화 된 명령문이 실행될 때 지정된 매개 변수의 실제 크기에서 값이 유추됩니다.

기본 유형은 입력입니다. 그러나 크기를 이와 같이 추론 할 수 있도록 허용하고 루프에서 매개 변수 객체를 재활용하면 (성능에 관심이 있다고 말했듯이) 크기는 첫 번째 값으로 설정되고 더 긴 후속 값은 잘립니다. 분명히 이것은 문자열과 같은 가변 길이 값에만 중요합니다.

루프에서 동일한 논리적 매개 변수를 반복적으로 전달하는 경우 루프 외부에 SqlParameter 개체를 만들고 적절하게 크기를 조정하는 것이 좋습니다. varchar의 크기를 초과하는 것은 무해하므로 정확한 최대 값을 얻기위한 PITA의 경우 열이 예상했던 것보다 크게 설정하면됩니다. 반복 할 때마다 새 개체를 만드는 대신 개체를 재활용하기 때문에 오버 사이징에 약간 흥분하더라도 루프 기간 동안 메모리 소비가 감소 할 수 있습니다.

수천 건의 통화를 처리하지 않는 한,이 중 어느 것도 큰 차이를 만들지 않습니다. AddWithValue크기 문제를 피하면서 새 개체를 만듭니다. 짧고 달콤하고 이해하기 쉽습니다. 수천을 반복한다면 내 접근 방식을 사용하십시오. 그렇지 않은 AddWithValue경우을 사용 하여 코드를 간단하고 유지 관리하기 쉽게 유지하십시오.


2008 년은 오래전

이 글을 쓴 후 몇 년 동안 세상이 바뀌 었습니다. 새로운 종류의 날짜가 있고, 최근 날짜 문제로 인해 확대의 의미를 생각하게 될 때까지 마음에 들지 않았던 문제도 있습니다.

용어에 익숙하지 않은 사용자를위한 확대 및 축소는 데이터 유형 변환의 특성입니다. int를 double에 할당하면 double이 "더 넓기"때문에 정밀도가 손실되지 않습니다. 이 작업은 항상 안전하므로 변환은 자동입니다. 이것이 int를 double에 할당 할 수 있지만 명시 적 캐스트를 수행해야하는 다른 방식으로 진행하는 이유입니다. double을 int로 변환하면 정밀도가 손실 될 가능성이있는 축소 변환입니다.

이것은 문자열에 적용될 수 있습니다. NVARCHAR은 VARCHAR보다 넓으므로 VARCHAR를 NVARCHAR에 할당 할 수 있지만 반대 방향으로 이동하려면 캐스트가 필요합니다. 비교는 VARCHAR가 암시 적으로 NVARCHAR로 확장되기 때문에 작동 하지만 인덱스 사용을 방해합니다!

C # 문자열은 유니 코드이므로 AddWithValue는 NVARCHAR 매개 변수를 생성합니다. 다른 쪽 끝에서는 비교를 위해 VARCHAR 열 값이 NVARCHAR로 확장됩니다. 이것은 쿼리 실행을 중지하지 않지만 인덱스 사용을 방지합니다. 이것은 나쁘다.

그것에 대해 무엇을 할 수 있습니까? 두 가지 가능한 솔루션이 있습니다.

  • 매개 변수를 명시 적으로 입력하십시오. 이것은 더 이상 AddWithValue가 없음을 의미합니다.
  • 모든 문자열 열 유형을 NVARCHAR로 변경하십시오.

VARCHAR을 버리는 것이 아마도 가장 좋은 생각 일 것입니다. 결과를 예측할 수있는 간단한 변경이며 현지화 스토리를 개선합니다. 그러나이 옵션이 없을 수도 있습니다.

요즘에는 직접 ADO.NET을 많이 사용하지 않습니다. Linq2Sql은 이제 제가 선택한 무기이며,이 업데이트를 작성하는 과정에서이 문제를 어떻게 처리하는지 궁금해졌습니다. VARCHAR 열을 통한 조회를 위해 데이터 액세스 코드를 확인하려는 갑작스럽고 불타는 열망이 있습니다.


2019 and the world has moved on again

Linq2Sql is not available in dotnet Core, so I find myself using Dapper. The [N]VARCHAR problem is still a thing but it's no longer so far buried. I believe one can also use ADO so things have come full circle in that regard.


I'd say #1 for sure. But, however Microsoft does it in the data access application block in the enterprise library is the best, esp for SQL server:

http://msdn.microsoft.com/en-us/library/dd203144.aspx


I used to use your option 1:

cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob";

which worked fine, but then I started using .AddWithValue and it is as simple as it gets. It hasn't caused me a problem after many many thousands of uses. Mind you, I almost always pass my classes private variables, so I don't have to worry about the implicit type conversion as much.


It depends on your application. I actually like 2, because I don't lke to have to change my DAO if I change the length of a stored proc parameter. That's just me though. I don't know if there are any performance penalties or anything.

ReferenceURL : https://stackoverflow.com/questions/293311/whats-the-best-method-to-pass-parameters-to-sqlcommand

반응형