Próba sprawdzenia, czy najlepiej jest użyć ExecuteScalar
lub ExecuteNonQuery
, jeśli chcę zwrócić kolumnę tożsamości nowo wstawionego wiersza. Czytałem this question i zrozumieć różnice istnieją, ale patrząc na niektóre kodu pisałem kilka tygodni temu (podczas gdy mocno pożyczania od tej strony) Okazało się, że w moich wstawek używałem ExecuteScalar
, tak:ExecuteScalar vs ExecuteNonQuery podczas zwracania wartości tożsamości
public static int SaveTest(Test newTest)
{
var conn = DbConnect.Connection();
const string sqlString = "INSERT INTO dbo.Tests (Tester , Premise) " +
" VALUES (@tester , @premise) " +
"SET @newId = SCOPE_IDENTITY(); ";
using (conn)
{
using (var cmd = new SqlCommand(sqlString, conn))
{
cmd.Parameters.AddWithValue("@tester", newTest.tester);
cmd.Parameters.AddWithValue("@premise", newTest.premise);
cmd.Parameters.Add("@newId", SqlDbType.Int).Direction = ParameterDirection.Output;
cmd.CommandType = CommandType.Text;
conn.Open();
cmd.ExecuteScalar();
return (int) cmd.Parameters["@newId"].Value;
}
}
}
działa to dobrze, za to, co muszę, więc zastanawiam
- Czy powinienem używać
ExecuteNonQuery
tutaj, bo to jest bardziej „właściwego” do wykonywania wkładek? - Czy pobieranie wartości tożsamości było takie samo w obu kierunkach, ponieważ używam parametru wyjściowego?
- Czy są jakieś trafienia związane z wydajnością powiązane z takim czy innym sposobem?
- Czy ogólnie można to zrobić ogólnie?
Używam Visual Studio 2010, .NET 4.0 i SQL Server 2008r2, w przypadku, które robi różnicę.
(1) dlaczego "ExecuteNonQuery" jest bardziej właściwy "? (2) czy rozważałeś zastosowanie procedur przechowywanych? Jeśli nie, dlaczego nie? Z pewnością pomoże to w wyczyszczeniu wszystkich ad hoc SQL, które wstawiasz do swojej aplikacji - które, gdy będziesz musiał je zmienić, oznaczają, że musisz ponownie skompilować i ponownie wdrożyć aplikację. –
Hmmm ... ExecuteNonQuery służy zwykle do wykonywania SQL, który nie oczekuje zwrotu wyniku. ExecuteScalar zwraca wartość, więc nie trzeba przechodzić przez parametry. Możesz zmienić ostatnią część twojego SQL na 'SELECT SCOPE_IDENTITY(); następnie użyj' return (int) cmd.ExecuteScalar(); ' – Sam
Używam' ExecuteScalar', ponieważ używam 'SELECT SCOPE_IDENTITY' bez parametru wyjściowego, stąd pobrać pojedynczą wartość, która jest celem 'ExecuteScalar'. http://stackoverflow.com/a/9319609/284240 –