programing

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

newstyles 2023. 7. 3. 22:36

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

매개 변수를 SQL Command로 전달하는 가장 좋은 방법은 무엇입니까?할 수 있는 일:

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

또는

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

또는

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

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

저 안에서 무슨 일이 일어나고 있습니까?

여러 오버로드에 대한 매개 변수 목록을 인용합니다.Add다음은 생성자 오버로드에 직접 대응하는 편리한 방법입니다.SqlParameter호출한 하고, 그에 래스클라고 . 그들은 기본적으로 당신이 호출한 편리한 방법과 동일한 서명을 가진 어떤 생성자를 사용하여 매개변수 객체를 구성하고, 그 다음에 호출합니다.SqlParameterCollection.Add(SqlParameter)다음과 같이:

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

AddWithValue유사하지만 훨씬 더 편리하고 값도 설정할 수 있습니다.그러나 실제로는 프레임워크 결함을 해결하기 위해 도입되었습니다. MSDN을 하자면,

의 .Add문자열을 사용하고 객체는 가능한 모호성 때문에 더 이상 사용되지 않습니다.SqlParameterCollection.Add가 걸리는 String a 리고a.SqlDbType "" " " " " " " " " " " " " " " " " " 인 것으로 될 수 SqlDbType 치가를 합니다. 사용AddWithValue이름과 값을 지정하여 매개 변수를 추가할 때마다 선택합니다.

생성자가 다음을 위해 오버로드합니다.SqlParameter클래스는 인스턴스(instance) 속성을 설정하기 위한 단순한 편의입니다.그들은 성능에 거의 영향을 미치지 않으면서 코드를 단축합니다. 생성자는 세터 메서드를 우회하고 개인 멤버에서 직접 작동할 수 있습니다.차이가 있다면 얼마 되지 않을 것입니다.

어떻게 해야 하나?

(MSDN에서) 다음 사항에 유의합니다.

및 출력 은 반드시 " " " " " " " " " " " " " " " " 의 .Size입력 매개 변수에는 이 값이 필요하지 않으며, 명시적으로 설정되지 않은 경우 매개 변수화된 문이 실행될 때 지정된 매개 변수의 실제 크기에서 값이 유추됩니다.

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

루프에서 동일한 논리 매개 변수를 반복적으로 전달하는 경우 루프 외부에 SqlParameter 개체를 생성하고 크기를 적절하게 조정하는 것이 좋습니다.막대 크기를 너무 크게 하는 것은 해롭지 않으므로, 정확한 최대치를 얻는 것이 피타라면, 여러분이 예상했던 것보다 더 크게 설정하세요.반복할 때마다 개체를 새로 만드는 것이 아니라 개체를 재활용하기 때문에 크기 초과로 인해 약간 흥분하더라도 루프가 지속되는 동안 메모리 소비가 감소할 수 있습니다.

사실, 수천 건의 전화를 처리하지 않는 한, 이 중 어떤 것도 큰 차이를 만들지 못할 것입니다. AddWithValue크기 조정 문제를 피하여 새 개체를 만듭니다.그것은 짧고 달콤하고 이해하기 쉽습니다.수천 명을 넘기면 제 접근법을 사용하세요.그렇지 않은 경우 사용AddWithValue코드를 단순하고 쉽게 유지할 수 있습니다.


2008년은 아주 오래전이었습니다.

제가 이 글을 쓴 이후로 몇 년 동안 세상은 변했습니다.새로운 종류의 데이트가 있고, 최근 데이트에 대한 문제로 인해 확장의 의미에 대해 생각하게 될 때까지 제 머리를 스치지 않았던 문제도 있습니다.

용어에 익숙하지 않은 사람들에게 확장과 축소는 데이터 유형 변환의 특성입니다.더블에 int를 할당하면 더블이 "넓음"이기 때문에 정밀도가 손실되지 않습니다.이 작업은 항상 안전하므로 변환은 자동으로 이루어집니다.그렇기 때문에 인트를 더블에 할당할 수 있지만 명시적인 캐스트를 수행해야 하는 반대의 방법인 더블 투 인트는 잠재적인 정밀도 손실이 있는 좁은 변환입니다.

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

C# 문자열은 유니코드이므로 AddWithValue는 NVARCHAR 매개 변수를 생성합니다.다른 쪽 끝에서는 비교를 위해 VARCHAR 열 값이 NVARCHAR로 넓어집니다.이렇게 하면 쿼리 실행이 중지되지 않지만 인덱스가 사용되지 않습니다.이거 큰일났어요.

당신은 그것에 대해 무엇을 할 수 있습니까?두 가지 해결책이 있습니다.

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

VARCHAR를 버리는 것이 아마도 가장 좋은 생각일 것입니다.이는 예측 가능한 결과를 수반하는 간단한 변경이며 현지화 사례를 개선합니다.그러나 이 옵션은 선택사항으로 제공되지 않을 수 있습니다.

요즘 저는 다이렉트 ADO.NET을 많이 하지 않습니다.Linkq2Sql은 이제 제가 선택한 무기이며, 이 업데이트를 작성하는 행위는 이 문제를 어떻게 처리하는지 궁금하게 만들었습니다.갑자기 VARCHAR 열을 통해 데이터 액세스 코드를 조회하고 싶어졌습니다.


2019년 그리고 세계는 다시 으로 나아갔습니다.

linq2Sql은 dotnet Core에서 사용할 수 없기 때문에 Dapper를 사용하고 있습니다.[N]VARCHAR 문제는 여전히 중요하지만 더 이상 묻혀있지 않습니다.저는 ADO도 사용할 수 있다고 생각하기 때문에 그 점에서 일이 완전히 진행되었습니다.

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

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

나는 당신의 옵션 1을 사용했습니다:

cmd.Parameters.추가("@Name"), SqlDbType.VarChar, 20).값 = "밥";

잘 작동했지만, 그 후에 저는 사용하기 시작했습니다.AddWithValue는 매우 간단합니다.수천 번의 사용 후에도 문제가 발생하지 않았습니다.주의하세요, 저는 거의 항상 개인 변수 수업을 통과하기 때문에 암묵적인 유형 변환에 대해 크게 걱정할 필요가 없습니다.

확실히 1위입니다.그러나 Microsoft가 엔터프라이즈 라이브러리의 데이터 액세스 애플리케이션 블록에서 실행하는 것이 가장 좋습니다. 특히 SQL 서버의 경우:

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

그것은 당신의 신청에 따라 다릅니다.저장된 proc 매개 변수의 길이를 변경하면 DAO를 변경할 필요가 없기 때문에 저는 사실 2를 좋아합니다.하지만 그건 나야.저는 이행강제금 같은 것이 있는지 모르겠습니다.

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