2009-05-28 3 views
1

"SELECT name, city, FROM People"쿼리를 호출한다고 가정합니다. 일단 내 SqlDataReader를 실행하면 열은 내 SQL 쿼리에서와 같은 순서로 나타 납니까? 즉SqlDataReader 열 서수

나는 다음과 같은 코드가 항상 제대로 작동합니다 의존하고 있습니다 : 나는 열 대신 서수의 이름을 사용하는 경우 또한

SqlConnection connection = new SqlConnection(MyConnectionString); 
SqlCommand command = new SqlCommand(); 
command.Connection = connection; 
command.CommandText = "SELECT [name], [city], [country] WHERE [id] = @id"; 

try 
{ 
    connection.Open(); 
    SqlDataReader reader = command.ExecuteReader(System.Data.CommandBehavior.SingleRow); 

    if (reader.Read()) 
    { 
     // Read values. 
     name = reader[0].ToString(); 
     city = reader[1].ToString(); 
     country = reader[2].ToString(); 
    } 
} 
catch (Exception) 
{ 
    throw; 
} 
finally 
{ 
    connection.Close(); 
} 

얼마나 성능 잃을 않는다 (독자 [ "이름"])?

SqlDataReader의 열 순서 동작을 설명하는 공식적인 Microsoft 문서가 있습니까?

답변

5

예 그렇지만 SqlDataReader.GetName (서수) 및 SqlDataReader.GetOrdinal (이름)을 사용할 수도 있습니다.

성능면에서 볼 때 다음 데이터 행을 검색하는 오버 헤드와 비교할 때 매우 중요하지 않다고 생각합니다.

+0

안녕하세요. Josh. 신속한 회신에 감사드립니다. 그래서이 동작을 보장하고 그것에 의존해야합니까, 아니면 열 이름을 사용하는 것이 더 좋을까요? PS - GetOrdinal의 경우 단일 행 만 검색하므로 내 경우에는 유용하지 않다고 생각합니다. – niaher

+0

예, SqlDataReader를 사용하여 단 몇 년 만에 백업 할 수있는 하드 코어 증거가 없지만 동작이 보장됩니다. 나는 보통 열 이름이 1 열 또는 2 열만있는 경우가 아니라면 열 이름을 사용합니다. – Josh

+1

하지만 실제로 나는 reader [0], reader [1] 등을 사용하지 않습니다. reader.GetString (0), reader.GetString (1) 등을 사용합니다. – Josh

5

전적으로 Josh와 동의합니다. 필드 위치는 실제로 SQL 쿼리 텍스트에서 지정하는 것과 같습니다.

하지만 더 강력하기 때문에 여전히 열 이름을 사용하는 편이 좋습니다. 예 : SQL 쿼리에 필드를 추가해야하는 경우 어떻게해야합니까?

command.CommandText = "SELECT [name], [jobtitle], [city], [country] WHERE [id] = @id"; 

지금 갑자기 당신은 내가 일반적으로 데이터 판독기에 의해 반환 된 모든 행을 열거 루프 밖에서 무엇을

는 위치를 결정하는 것입니다 .... 위치를 변경하는 모든 코드를 다시 작성해야 각 필드의 내가 관심 :

int namePosition = reader.GetOrdinal("name"); 
int cityPosition = reader.GetOrdinal("city"); 

후, 나는 개별 필드에 빠르게 액세스를 얻기 위해 데이터를 처리 내 루프 안쪽이 위치를 사용합니다. 그렇게하면 한 번만 위치를 결정할 수 있지만 데이터를 반복하면서 위치를 사용하고 있습니다. 두 가지 모두에서 가장 좋습니다! :-)

마크

4

이 예는 대부분의 유지 보수이며, 가장 쉬운 읽기 :

int? quantity = reader.Get<int?>("Quantity"); 
Guid token = reader.Get<Guid>("Token"); 

내가 만든 다음 확장 방법에 의존한다. DB 널 확인을 수행하고, 필드를 찾을 수 없을 때 유익한 오류 메시지를 제공하며, 열을 다시 정렬 할 때 중단되지 않습니다.

internal static T Get<T>(this SqlDataReader reader, string fieldName) 
{ 
    int ordinal; 
    try 
    { 
     ordinal = reader.GetOrdinal(fieldName); 
    } 
    catch (IndexOutOfRangeException) 
    { 
     throw new IndexOutOfRangeException(string.Format("Field name '{0}' not found.", fieldName)); 
    } 

    return !reader.IsDBNull(ordinal) ? (T)reader.GetValue(ordinal) : default(T); 
} 
관련 문제