c# sql visual-studio ado.net

c# - Consultas paramterizadas



sql visual-studio (5)

Soy nuevo en Visual C #, y estoy confundido sobre cómo escribir consultas parametrizadas. Aquí está mi código sin ellos,

using System; using System.Windows.Forms; using System.Data.SqlClient; namespace Insert_Data { public partial class Form1 : Form { private void button1_Click(object sender, EventArgs e) { SqlConnection con = new SqlConnection("Data Source=ZTABASSUM//SQLEXPRESS01;Initial Catalog=IntroDataBase;Integrated Security=True"); con.Open(); SqlCommand sc = new SqlCommand("Insert into employee values (''"+ textBox1.Text +"'' , " + textBox2.Text + ", ''" + textBox3.Text + "'', " + textBox4.Text + ", " + textBox5.Text + ");", con); int o = sc.ExecuteNonQuery(); MessageBox.Show(o + ":Record has been inserted"); con.Close(); } } }

No estoy seguro de cómo escribir consultas parametrizadas para cada cuadro de texto.


Debería usar el método create parameter en el objeto de comando SQL

Cambie su cadena en el comando SQL para

"Insert into employee values (@Employee1,@Employee2,@Employee3,@Employee4,@Employee5);"

Luego, antes de ejecutar la consulta, agregue los parámetros:

sc.Parameters.AddRange(new[]{ new SqlParameter("@Employee1",SqlDbType.VarChar,255){ Value= textBox1.Text}, new SqlParameter("@Employee2",SqlDbType.VarChar,255){ Value= textBox2.Text}, new SqlParameter("@Employee3",SqlDbType.VarChar,255){ Value= textBox3.Text}, new SqlParameter("@Employee4",SqlDbType.VarChar,255){ Value= textBox4.Text}, new SqlParameter("@Employee5",SqlDbType.VarChar,255){ Value= textBox5.Text} });

Nota: Esto supone que el tipo de sus variables de SQL será un VARCHAR y el tamaño será 255 Para obtener más información sobre el método que se está utilizando y el constructor de SqlParameter está utilizando, consulte MSDN para obtener más documentación.


Deje de usar AddWithValue ya que infiere el tipo de base de datos (mal) y tampoco es un código limpio en mi opinión.

Aquí hay un código simple para comenzar.

OracleConnection connection = GetConnection(); OracleCommand command = connection.CreateCommand(); command.CommandText = procedure; command.CommandType = CommandType.StoredProcedure; command.Parameters.Add("INID", OracleDbType.Int32).Value = person.PersonID; command.Parameters.Add("REFCURSOR", OracleDbType.RefCursor).Direction = ParameterDirection.Output;

No importa que sea Oracle, el mismo principio se aplica a SQL.


Si tiene un contexto de base de datos, puede hacerlo así:

int rowsAffected = context. ExecuteStoreCommand("Insert into employee values ({0}, {1}, {2}, {3}, {4})", textBox1.Text, textBox2.Text, textBox3.Text, textBox4.Text, textBox5.Text); MessageBox.Show(rowsAffected + ":Record has been inserted");/

cf https://msdn.microsoft.com/en-us/library/ee358769%28v=vs.100%29.aspx


consultas parametrizadas se utiliza para evitar la inyección sql. La consulta que no contiene parámetros (datos) directamente se denomina consulta parametrizada. al usar esto podemos evitar la inyección sql (un tipo de pirateo).

Ejemplo de consulta parametrizada en c #

string strQuery; SqlCommand cmd; strQuery = "insert into customers (CustomerID, CompanyName) values(@CustomerID, @CompanyName)"; cmd = new SqlCommand(strQuery); cmd.Parameters.AddWithValue("@CustomerID", "A234"); cmd.Parameters.AddWithValue("@CompanyName", "DCB"); String strConnString = system.Configuration.ConfigurationManager.ConnectionStrings["conString"].ConnectionString; SqlConnection con = new SqlConnection(strConnString); cmd.CommandType = CommandType.Text; cmd.Connection = con; try { con.Open(); cmd.ExecuteNonQuery(); return true; } catch (Exception ex) { Response.Write(ex.Message); return false; } finally { con.Close(); con.Dispose(); }

..

Del mismo modo que puede utilizar para seleccionar consulta también ..

para referencia, vea este enlace


Agregué notas en el código junto con una recapitulación de best practices después.

// best practice - use meaningful method names private void buttonSaveEmployee_Click(object sender, EventArgs e) { // best practice - wrap all database connections in a using block so they are always closed & disposed even in the event of an Exception // best practice - retrieve the connection string by name from the app.config or web.config (depending on the application type) (note, this requires an assembly reference to System.configuration) using(SqlConnection con = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["MyConnectionName"].ConnectionString)) { // best practice - use column names in your INSERT statement so you are not dependent on the sql schema column order // best practice - always use parameters to avoid sql injection attacks and errors if malformed text is used like including a single quote which is the sql equivalent of escaping or starting a string (varchar/nvarchar) // best practice - give your parameters meaningful names just like you do variables in your code SqlCommand sc = new SqlCommand("INSERT INTO employee (FirstName, LastName, DateOfBirth /*etc*/) VALUES (@firstName, @lastName, @dateOfBirth /*etc*/)", con); // best practice - always specify the database data type of the column you are using // best practice - check for valid values in your code and/or use a database constraint, if inserting NULL then use System.DbNull.Value sc.Parameters.Add(new SqlParameter("@firstName", SqlDbType.VarChar, 200){Value = string.IsNullOrEmpty(textBoxFirstName.Text) ? (object) System.DBNull.Value : (object) textBoxFirstName.Text}); sc.Parameters.Add(new SqlParameter("@lastName", SqlDbType.VarChar, 200){Value = string.IsNullOrEmpty(textBoxLastName.Text) ? (object) System.DBNull.Value : (object) textBoxLastName.Text}); // best practice - always use the correct types when specifying your parameters, in this case a string is converted to a DateTime type before being assigned to the SqlParameter.Value // note - this is not a very robust way to parse a date as the user is never notified in the event of failure, the purpose here is simply to show how to use parameters of various types DateTime dob; sc.Parameters.Add(new SqlParameter("@dateOfBirth", SqlDbType.Date){Value = DateTime.TryParse(textBoxDateOfBirth.Text, out dob) ? (object) dob : (object) System.DBNull.Value}); // best practice - open your connection as late as possible unless you need to verify that the database connection is valid and wont fail and the proceeding code execution takes a long time (not the case here) con.Open(); int o = sc.ExecuteNonQuery(); MessageBox.Show(o + ":Record has been inserted"); // the end of the using block will close and dispose the SqlConnection // best practice - end the using block as soon as possible to release the database connection } }

Resumen de mejores prácticas para trabajar con ADO.NET

  • Envuelva todas las conexiones de la base de datos en un bloque de uso para que siempre estén cerradas y eliminadas incluso en el caso de una excepción. Consulte el uso de Statement (C # Reference) para obtener más información sobre el uso de declaraciones
  • Recupere las cadenas de conexión por nombre de la aplicación.config o web.config (dependiendo del tipo de aplicación)
  • Utilice siempre parámetros para valores entrantes a
    • Evite los ataques de inyección sql
    • Evite los errores si se usa texto mal formado, como incluir una comilla simple que es el equivalente en sql de escaparse o iniciar una cadena (varchar / nvarchar)
    • Dejar que el proveedor de la base de datos reutilice los planes de consulta (no soportados por todos los proveedores de bases de datos) lo que aumenta la eficiencia
  • Cuando se trabaja con parámetros
    • Dale a tus parámetros Sql nombres significativos tal como lo haces con variables en tu código
    • Especifique el tipo de datos de la base de datos de la columna que está utilizando, esto asegura que no se usen tipos de parámetros incorrectos que podrían conducir a resultados inesperados
    • Valide sus parámetros entrantes antes de pasarlos al comando, hay una expresión llamada basura en la basura. Valide los valores entrantes tan pronto como sea posible en la pila
    • Use los tipos correctos cuando asigne los valores de sus parámetros, por ejemplo: no asigne el valor de cadena de un DateTime, en su lugar asigne una instancia actual de DateTime al valor del parámetro
    • No utilice el método AddWithValue , la razón principal es que es muy fácil olvidar especificar el tipo de parámetro o la precisión / escala cuando sea necesario. Para obtener información adicional, consulte ¿Podemos dejar de usar AddWithValue?
  • Al usar conexiones de bases de datos
    • Abra la conexión lo más tarde posible y ciérrela lo antes posible. Esta es una guía general cuando se trabaja con cualquier recurso externo
    • Nunca comparta conexiones de bases de datos (por ejemplo, tener un host singleton una conexión de base de datos compartida). Haga que su código siempre cree una nueva instancia de conexión de base de datos cuando sea necesario y luego haga que el código de llamada se deshaga de él y "deséchelo" cuando esté listo. La razón de esto es
      1. La mayoría de los proveedores de bases de datos tienen algún tipo de agrupación de conexiones, por lo que es muy barato hacerlo en código administrado
      2. Elimina cualquier error futuro si el código comienza a trabajar con múltiples hilos