example dbhelper c# sql-server executenonquery executescalar

dbhelper - execute sql command c# example



ExecuteScalar vs ExecuteNonQuery al devolver un valor de identidad (1)

Según lo sugerido por Aaron, un procedimiento almacenado lo haría más rápido porque le ahorra al servidor Sql el trabajo de compilar su lote SQL. Sin embargo, aún podría seguir con cualquiera de los enfoques: ExecuteScalar o ExecuteNonQuery . En mi humilde opinión, la diferencia de rendimiento entre ellos es tan pequeña, que cualquiera de los dos métodos es tan "correcto".

Dicho esto, no veo el punto de usar ExecuteScalar si está tomando el valor de identidad de un parámetro de salida. En ese caso, el valor devuelto por ExecuteScalar vuelve inútil.

Un enfoque que me gusta porque requiere menos código, usa ExecuteScalar sin parámetros de salida:

public static int SaveTest(Test newTest) { var conn = DbConnect.Connection(); const string sqlString = "INSERT INTO dbo.Tests ( Tester , Premise ) " + " VALUES ( @tester , @premise ) " + "SELECT SCOPE_IDENTITY()"; using (conn) { using (var cmd = new SqlCommand(sqlString, conn)) { cmd.Parameters.AddWithValue("@tester", newTest.tester); cmd.Parameters.AddWithValue("@premise", newTest.premise); cmd.CommandType = CommandType.Text; conn.Open(); return (int) (decimal) cmd.ExecuteScalar(); } } }

¡Feliz programación!

EDITAR : Tenga en cuenta que debemos emitir dos veces: de objeto a decimal y luego a int (gracias a techturtle por señalar esto).

Intento averiguar si es mejor usar ExecuteScalar o ExecuteNonQuery si deseo devolver la columna de identidad de una fila recién insertada. He leído esta pregunta y comprendo las diferencias allí, pero cuando revisé un código que escribí hace unas semanas (mientras tomaba muchos préstamos de este sitio), encontré que en mis inserciones estaba usando ExecuteScalar , así:

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; } } }

Esto funciona bien para lo que necesito, así que me pregunto

  1. ¿Debería usar ExecuteNonQuery aquí porque es "más adecuado" para hacer inserciones?
  2. ¿Recuperar el valor de identidad sería el mismo de cualquier manera ya que estoy usando un parámetro de salida?
  3. ¿Hay éxitos de rendimiento asociados de una manera u otra?
  4. ¿Hay generalmente una mejor manera de hacer esto en general?

Estoy usando Visual Studio 2010, .NET 4.0 y SQL Server 2008r2, en caso de que eso haga alguna diferencia.