2013-09-27 19 views
10

Witam Mam ten kod, który odczytuje dane z SQL DB.Używanie nazwy kolumny podczas korzystania z SqlDataReader.IsDBNull

Nie wiem, w jaki sposób należy go edytować, aby móc używać oryginalnej nazwy kolumny, a nie indeksu kolumny.

string query = "SELECT * FROM zajezd WHERE event='" + thisrow+ "' AND year='" + klientClass.Year() + "'"; 
SqlCommand cmd= new SqlCommand(query, spojeni); 
spojeni.Open(); 
SqlDataReader read= cmd.ExecuteReader(); 


if (read.Read()) 
{ 
    maskedTextBox2.Text = read.IsDBNull(24) ? 
     string.Empty : 
     read.GetDateTime(24).ToString("MM/dd/yyyy"); 

Z góry dziękuję.

+3

Więc używasz SELECT *, a kolumna, której szukasz, jest 24. kolumną? To jest straszny sposób kodowania - co się dzieje, gdy ktoś zmienia tabelę (np. Dodaje kolumnę między 1-23)? Może pojawić się błąd lub może się zdarzyć, że uzyskasz inną kolumnę daty i nie zostanie ona zauważona. Czy podoba Ci się również wstrzyknięcie SQL? Użyj sparametryzowanych zapytań. Tak dynamiczny SQL sprawia, że ​​każdego dnia jest tak wiele exploitów do wstrzyknięć SQL w Internecie. –

+0

@NathanKoop w edycji dodano klamrę zamykającą. Prawdopodobnie masz rację, ale jak widać z poniższych komentarzy, daje to bardzo konkretne znaczenie zapytaniu stosowanemu przez PO. Jeśli PO potrzebuje tylko jednej kolumny, wówczas możliwe byłoby lepsze podejście. – Steve

+0

@Steve przepraszam za opóźnioną odpowiedź. Nie widzę komentarzy, do których się odwołujesz, ale usunąłem kręcone. Dla mnie nie ma to wielkiego znaczenia, jeśli tak jest, czy nie :-) –

Odpowiedz

14

Szukasz SqlDataReader.GetOrdinal

Zgodnie z MSDN

Pobiera porządkowa kolumny, biorąc pod uwagę nazwę kolumny.

if (read.Read()) 
{ 
    int colIndex = read.GetOrdinal("MyColumnName"); 
    maskedTextBox2.Text = read.IsDBNull(colIndex) ? 
        string.Empty : 
        read.GetDateTime(colIndex).ToString("MM/dd/yyyy"); 

} 

Na marginesie, zapytanie jest otwarty na SQL injection. Nie używaj konkatenacji ciągów zbudować polecenia SQL, ale użyć zapytania parametrycznego

string query = "SELECT * FROM zajezd WHERE [email protected] AND [email protected]"; 
    using(SqlCommand cmd= new SqlCommand(query, spojeni)) 
    { 
    spojeni.Open(); 
    cmd.Parameters.AddWithValue("@p1",thisrow); 
    cmd.Parameters.AddWithValue("@p2",klientClass.Year().ToString()); 
    using(SqlDataReader read= cmd.ExecuteReader()) 
    { 
     ...... 
    } 
    } 
+0

Downvoter, czy mógłbyś wyjaśnić, czego mi brakuje? – Steve

+0

Nie spadłem, ale gdybym to robił, robiłbym odczyt poza pętlą. EDIT: Po prostu zobaczyłem, że jest to instrukcja 'if' nie pętla. Myślę, że powinien zamiast tego użyć ExecuteScaler. –

+0

Zakładamy, że OP potrzebuje tylko jednej kolumny, ale nie można tego zweryfikować na podstawie niekompletnego zaksięgowanego kodu, jednak jeśli OP naprawdę potrzebuje tylko jednej kolumny z jednego rekordu, zgadzam się, że całe zapytanie powinno zostać przepisane – Steve

7

chciałbym spróbować (string)(reader["ColumnName"] == DBNull.Value ? "" : reader["ColumnName"]); to zrobić przez nazwę kolumny.

+0

OP musi używać IsDBNull i nie można tego zrobić z nazwą kolumny .... – Steve

+0

To jest co robimy i działa dobrze (ciąg) (czytnik ["ColumnName"] == DBNull.Value? "": reader ["ColumnName"]); –

+0

Cóż, to prawda, ale dlaczego nie dodasz do swojej odpowiedzi? – Steve

Powiązane problemy