2013-07-27 10 views
14

w moim programie muszę sprawdzić, czy rekord w bazie danych już istnieje w tabeli przy użyciu instrukcji if. przy użyciu C# próbuję to zrobić poprzez połączenie sql. jak przypuszczam, że polecenie ExecuteNonQuery(); zwraca wartość całkowitą, jeśli moje przypuszczenie jest prawdziwe, chcę wiedzieć, jaka wartość jest prawdziwa, aby wiedzieć, że dany rekord istnieje w tabeli, czy nie. Oto przykład z mojego kodu:Sprawdź, czy rekord w tabeli istnieje w bazie danych poprzez ExecuteNonQuery

using (SqlConnection sqlConnection = dbUtil.GetSqlConnection(dbUtil.GetConnectionStringByName("NonConnectionString"))) 
{ 
    using (SqlCommand sqlCommand = new SqlCommand("SELECT * from users where user_name like 'Adam' AND password like '123456'", sqlConnection)) 
    { 
     sqlresult = sqlCommand.ExecuteNonQuery(); 
    } 
} 

rozważa SQLResult został zainicjowany wcześniej głównie jako int sqlresult; więc chciałbym wiedzieć, że jeśli użytkownik „Adam” istnieje w bazie danych, czy nie. a jeśli istnieje, to chcę, aby kontynuować za „czy” oświadczenie mówiąc na przykład:

if(sqlresult == 0) 
{ 
    MessageBox.Show("Adam exists!"); 
} 

więc ja po prostu nie wiem liczbę całkowitą, że powinien wrócić, a ja nie jestem też pewien, że jest to właściwy sposób, aby to zrobić.

dziękuję.

Odpowiedz

33

Jeśli chcesz sprawdzić, czy użytkownik istnieje, trzeba zmienić sql i używać COUNT lub EXISTS:

więc zamiast

SELECT * from users where user_name like 'Adam' AND password like '123456' 

to

SELECT COUNT(*) from users where user_name like 'Adam' AND password like '123456' 

teraz ty można użyć numeru ExecuteScalar, aby pobrać liczbę użytkowników z tą nazwą użytkownika i hasłem:

int userCount = (int) sqlCommand.ExecuteScalar(); 
if(userCount > 0) 
    // user exists .... 

Zauważ, że należy użyć SQL-parametrów, aby zapobiec sql-injection:

using (SqlCommand sqlCommand = new SqlCommand("SELECT COUNT(*) from users where user_name like @username AND password like @password", sqlConnection)) 
{ 
    sqlConnection.Open(); 
    sqlCommand.Parameters.AddWithValue("@username", userName); 
    sqlCommand.Parameters.AddWithValue("@password", passWord); 
    int userCount = (int) sqlCommand.ExecuteScalar(); 
    ... 
} 
+1

Warto zauważyć, że sqlCommand.ExecuteScalar() zwraca obiekt nie jest int: http://msdn.microsoft.com/en-us/library/system.data. sqlclient.sqlcommand.executescalar (v = vs.110) .aspx – TonE

+0

dziękuję za ten świetny przykład, mam pytanie, z twojego "używania" kodu blokowego, czy obiekt rzucany jest na brakujący w zmiennej userCount? lub nie jest potrzebne? – WhySoSerious

+1

@WhySoPious: dzięki za uwagę, dodałem go, ponieważ go brakowało. Jak już wspomniano, @TonE jest wymagane, ponieważ 'ExecuteScalar' zwraca' object'. –

7

Powinieneś używać ExecuteScalar do chekingowania, jeśli rekord istnieje. ExecuteNonQuery uruchamia instrukcję Transact-SQL dla połączenia i zwraca liczbę wierszy, których dotyczy aktualizacja, WSTAW lub USUŃ. Nie ma zastosowania do instrukcji SELECT

2

Powinieneś zrobić count(1) na stole zamiast select *, a następnie executescalar, aby uzyskać tę wartość całkowitą.

Korzystanie z istniejącego kodu chciałbym zmienić to być:

using (SqlConnection sqlConnection = dbUtil.GetSqlConnection(dbUtil.GetConnectionStringByName("NonConnectionString"))) 
     { 
      using (SqlCommand sqlCommand = new SqlCommand("SELECT count(1) from users where user_name = 'Adam' AND password = '123456'", sqlConnection)) 
      { 
       sqlresult = sqlCommand.ExecuteNonQuery(); 
      } 
     } 

Należy pamiętać, że użyłem równa wartości zamiast wartości podobnych.

Również gdybym to zrobił, zmieniłbym twój wbudowany sql, by użyć procedury przechowywanej.

3

użyłbym Select Top 1 ID zamiast count (*), ponieważ może to być znacznie szybciej

0

Jeśli pewnego dnia chcesz korzystać z EF to zrobić:

private MyDb db = new MyDb(); 

public bool UserExists(string userName, string password){ 

    return db.Users.Any(x => x.user_name.Equals(userName, StringComparison.InvariantCultureIgnoreCase) 
         && x.password.Equals(password, StringComparison.InvariantCultureIgnoreCase)); 
} 

Czy sposób ogólny, dzięki czemu można obsługiwać wiele udziałów w jednostkach:

public bool EntityExists<T>(Expression<Func<T, bool>> predicate) where T : class, new() 
{ 
    return db.Set<T>().Any(predicate); 
} 

Zastosowanie:

EntityExists<Users>(x => x.user_name.Equals(userName, StringComparison.InvariantCultureIgnoreCase) 
         && x.password.Equals(password, StringComparison.InvariantCultureIgnoreCase)); 
Powiązane problemy