76533483-C-Sql-Base-de-datos

16
ADO .NET Acceso a una base de datos de SQL Server con ADO.NET y Visual C# Código de ejemplo válido para cualquier versión de Visual C# Introducción Este artículo en realidad consta de varias partes, aunque todas esas partes formarán un todo, y ese todo es un ejemplo muy básico (o elemental) de cómo acceder a una base de datos de tipo SQL Server usando ADO.NET y Visual Basic, (cualquier versión, ya sea la 1.x o la 2.0), permitiendo navegar entre los registros, añadir el Guille, la Web del Visual Basic, C#, .NET y más... Lo Nuevo - VS2005 - . NET - ADO.NET - ASP.NET - C ó mo... - Colabora - VB6 - API - Bases - HTML - Sistema - Links La OFERTA de alojamiento más económica: 2.95 Eur XtraGrid Suite .NET Advanced and feature complete data grid and UI library for VS.NET Visual Bubble The largest independent resource website for Mindjet MindManager Excel Tablas Dinamicas Automatice el reporting de su empresa generando reportes Excel. ASP.NET Combobox r.a.d.combobox – AJAX XHTML & accessibility compliance Anuncios Goooooogle Anunciarse en este sitio Publicado el 05/Feb/2006 Actualizado el 05/Feb/2006 Autor: Guillermo 'guille' Som Página 1 de 16 Acceso a una base de datos de SQL Server con ADO.NET y Visual C# 20/07/2006 http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htm AcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Transcript of 76533483-C-Sql-Base-de-datos

Page 1: 76533483-C-Sql-Base-de-datos

ADO .NET

Acceso a una base de datos deSQL Server con ADO.NET yVisual C#Código de ejemplo válido para cualquier versión de Visual C#

Introducción

Este artículo en realidadconsta de varias partes,aunque todas esas partesformarán un todo, y ese todoes un ejemplo muy básico (oelemental) de cómo accedera una base de datos de tipoSQL Server usando ADO.NETy Visual Basic, (cualquierversión, ya sea la 1.x o la2.0), permitiendo navegarentre los registros, añadir

el Guille, la Web del Visual Basic, C#,.NET y más...

Lo Nuevo - VS2005 - .NET - ADO.NET - ASP.NET -Cómo... - Colabora - VB6 - API - Bases - HTML - Sistema -

Links

La OFERTA de alojamiento más económica:2.95 Eur

XtraGrid Suite .NETAdvanced and feature completedata grid and UI library forVS.NET

Visual BubbleThe largest independent resourcewebsite for Mindjet MindManager

Excel Tablas DinamicasAutomatice el reporting de suempresa generando reportesExcel.

ASP.NET Comboboxr.a.d.combobox – AJAXXHTML & accessibility compliance

Anuncios Goooooogle Anunciarse en este sitio

Publicado el 05/Feb/2006Actualizado el 05/Feb/2006Autor: Guillermo 'guille' Som

Página 1 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 2: 76533483-C-Sql-Base-de-datos

nuevos datos, modificar oborrar los existentes.

También veremos cómosaber las instancias de SQLServer que hay instaladas enel equipo, las cuales semostrarán en un combo; alseleccionar la instancia,veremos cómo mostrar lasbases de datos que tiene esainstancia, (excepto las delsistema o propias de SQL),las cuales estarán en otrocombo.Si la tabla de prueba noexiste en la base de datosseleccionada, tendremos laposibilidad de crearla.

Además de lo dicho, en este ejemplo también verás cómo hacer losiguiente:-Deshabilitar los controles que estén incluidos en un GroupBox.-Conectar a la base de datos de SQL Server usando la autenticación integrada deWindows.-Obtener todos los datos indicados en una orden SELECT y guardarlos en unDataTable.-Moverse por los registros de la tabla usando los típicos comandos: Primero,Anterior, Siguiente y Último.-Añadir nuevos registros (o filas) a la tabla.-Eliminar una fila de la tabla.-Actualizar los datos de la fila actual.

Y como valor añadido, la utilidad de ejemplo también tiene código para:-Saber las instancias de SQL Server.-Saber las bases de datos de una instancia de SQL Server.-Saber si una tabla en concreto existe en una base de datos de SQL.-Crear una tabla (la usada en esta aplicación de ejemplo).

Espero que te sea de utilidad y que esté más claro y menos "liante" que el otroejemplo que ya tenía publicado.

Nota:A lo largo de este artículo, te muestro el código de Visual C#, pulsa estelink si quieres ver el artículo con el código de ejemplo para Visual Basic.

Al final tienes el link al zip con el código de ejemplo para Visual C#, el cual esválido tanto para las versiones 2003 y 2005.

Nos vemosGuillermo

P.S.Pulsa aquí para ver un ejemplo parecido para una base de datos de tipo Access con

Página 2 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 3: 76533483-C-Sql-Base-de-datos

OleDb.

Estructura de la tabla de ejemplo

Para que este código funcione, debes tener una base de datos en la que se incluyauna tabla llamada Prueba.Pulsa aquí si quieres saber cómo crear una base de datos de SQL Server usandocódigo de Visual C#.

La estructura de esa tabla (Prueba) es la que se muestra en la siguiente tabla.Si no la tienes creada en la base de datos que elijas, el programa te preguntará sila quieres crear, así que no te preocupes de que no la tengas creada.

El formulario para acceder a la base de datos

La aplicación de ejemplo tiene un formulario con el siguiente aspecto:

Nombre campo Tipo ComentarioID int Clave principal auto-numérica (identidad)Nombre nvarchar 50 caracterese-mail nvarchar 128 caracteresFechaAlta datetime -Comentario nvarchar 2048 caracteres

Página 3 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 4: 76533483-C-Sql-Base-de-datos

El formulario de la aplicación de ejemplo

Como vemos, este formulario utiliza los campos que tiene la tabla que vamos ausar, por tanto, si vas a usar otra tabla diferente a la usada en el ejemplo, tendrásque crear tu propio diseño del formulario. En el código he intentado separar elcódigo que depende de los campos, de forma que te resulte fácil de modificar.

Empezando por arriba, tenemos un ComboBox (cboInstancias) en el quemostraremos las instancias de SQL Server que hay instaladas en el equipo. Pulsaaquí si quieres saber cómo averiguar las instancias de SQL Server que hay en elequipo usando código de Visual C#.A la derecha, tenemos otro ComboBox (cboBases) en el que mostraremos lasbases de datos que tiene la instancia de SQL Server que hayamos seleccionado delprimer combo. Pulsa aquí para saber cómo averiguar las bases de datos quecontiene una instancia de SQL Server usando código de Visual C#.El botón que está en la parte derecha, (btnConectar), (en la misma fila que losdos combos) nos servirá para conectarnos a la base de datos y a la instanciaseleccionadas usando autenticación de Windows.En ese botón se crea la conexión a la base de datos y se asigna el DataAdapterque usaremos para conectar directamente con la base de datos. Por tanto será enel código de ese botón donde tendrás que escribir todo lo necesario para realizar laconexión, cargar los datos en la tabla (DataTable) y empezar a mostrar los datos.Al pulsar en el botón de conectar, el código comprueba si la tabla de pruebasexiste, de no ser así, nos preguntará si la queremos crear.

En el GroupBox tenemos los controles para mostrar los datos, navegar entre lasfilas, actualizar, crear y eliminar registros.Los botones de navegación (o movimiento) nos servirán para ir a los distintosregistros: Primero, anterior, siguiente y último.El botón de Actualizar lo usaremos para actualizar los datos del registro actual.El botón Nuevo lo usaremos para añadir un nuevo registro. Cuando pulsamos enese botón, se usarán los datos que actualmente tengamos en las cajas de textos,salvo el ID, ya que en la tabla de ejemplo es autonumérico, y por tanto se creasolo.

Página 4 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 5: 76533483-C-Sql-Base-de-datos

El botón de Eliminar lo usaremos para eliminar el registro que esté actualmenteactivo. Cuando se elimina el registro, los datos permanecen en los controles, por siqueremos volver a crearlo, (pulsando en el botón Nuevo), aunque el ID usado serádiferente al mostrado, ya que al crear un nuevo registro (o fila) el valor del campoID se genera automáticamente.

Nota IMPORTANTE:Las tres operaciones indicadas se hacen directamente en la base dedatos, es decir, no trabajamos en modo desconectado, sino quecualquier cambio se reflejará inmediatamente en la base de datos.

El resto de controles simplemente los usamos para mostrar los datos.

Las variables comunes para todo el código

A lo largo de la aplicación usaremos algunas variables comunes, en realidad sontres:dt del tipo DataTable, será la tabla a la que asignaremos los datos de la tabla de labase de datosda del tipo SqlDataAdapter, será el adaptador que nos permitirá acceder a la basede datos, para leer los datos y actualizarlos.fila del tipo int, será el índice de la fila actual, con idea de saber cual será lasiguiente, la anterior o la fila que queremos actualizar.

// Las variables que usaremos en este ejemploprivate DataTable dt;private SqlDataAdapter da;private int fila;

Form_Load: Deshabilitar los controles y asignar elpath de la base de datos

Al empezar la aplicación, en el evento Form_Load, deshabilitaremos los controlesque están en el GroupBox, además, averiguaremos las instancias de SQL Serverque hay actualmente en el equipo y las asignaremos en el combo correspondiente,también añadiremos al otro combo las bases de datos que contenga la instanciapredeterminada de SQL Server, y si hay alguna base de datos (que no sea delsistema), seleccionaremos la primera (índice cero).

En este evento utilizamos una función llamada instanciasInstaladas, esa es laque nos indica las instancias de SQL Server que tenemos instaladas en nuestroequipo y si quieres ver el código puedes hacerlo desde este link.En este mismo evento y en el correspondiente al cambio de selección del combo delas instancias, también usamos una función (basesDeDatos), que recibe comoparámetro el nombre de la instancia seleccionada, para saber las bases de datosque tiene la instancia de SQL Server que hemos seleccionado, el código de esa

Página 5 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 6: 76533483-C-Sql-Base-de-datos

función lo puedes ver siguiendo este link.

private void Form1_Load(object sender, EventArgs e) {this.Text="Ejemplo acceso SQL Server C#";

// Limpiar los controles del GroupBox y// deshabilitarlos hasta que se conecte a la base de datosforeach(Control c in this.GroupBox1.Controls){

// Limpiar los textboxif( c is TextBox ){

c.Text = "";}// Deshabilitarlosc.Enabled = false;

}this.GroupBox1.Enabled = false;this.GroupBox1.Text = "Debes conectar antes de usar los datos";//// Las instancias de SQL Server que hay instaladasstring[] instancias;instancias = instanciasInstaladas();foreach(string s in instancias){

if( s == "MSSQLSERVER" ){cboInstancias.Items.Add("(local)");

}else{cboInstancias.Items.Add(@"(local)\" + s);

}}cboInstancias.Text = "(local)";

// Los nombres de las bases de datosstring[] bases = basesDeDatos("(local)");if( bases != null ){

this.cboBases.Items.AddRange(bases);}if( this.cboBases.Items.Count > 0 ){

this.cboBases.SelectedIndex = 0;}

}

Al seleccionar una instancia, asignar las bases de datos quecontiene

Como te he comentado antes, cuando seleccionamos una de las instancias delcombo con los servidores (o instancias) de SQL Server, asignamos en el combo delas bases de datos, las que esa instancia contiene.El código del evento SelectedIndexChanged es el siguiente, en el quecomprobamos si hay alguna base de datos (la función que comprueba las basesque hay en la instancia indicada, devuelve Nothing si solo están las bases delpropio SQL Server), las agregamos al combo y seleccionamos el primer elemento.

private void cboInstancias_SelectedIndexChanged(object sender, EventArgse) {

string[] bases = basesDeDatos(cboInstancias.Text);cboBases.Items.Clear();if( bases != null ){

this.cboBases.Items.AddRange(bases);}if( cboBases.Items.Count > 0 ){

cboBases.SelectedIndex = 0;}

Página 6 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 7: 76533483-C-Sql-Base-de-datos

}

Conectar a la base de datos

Para conectar con la base de datos y obtener los datos, necesitamos una cadena deconexión al servidor de SQL Server que indique que base de datos vamos a usar.Los datos los obtendremos mediante una cadena de selección (SELECT).

En el siguiente código comprobamos también si la tabla que usaremos existe en labase de datos seleccionada, para ello usaremos la función existeTabla a la que lepasaremos el objeto conexión que hemos creado y el nombre de la tabla quequeremos comprobar si existe o no, que en nuestro ejemplo se llama Prueba.

Nota:En realidad el objeto SqlConnection no hace falta para rellenar losdatos por medio del DataAdapter, pero si lo necesitamos paracomprobar si la tabla existe.

Una vez que tenemos la conexión creada y que sabemos que la tabla existe,crearemos los objetos que nos permitirán acceder a la base de datos (mediante unobjeto del tipo SqlDataAdapter), y llenaremos el objeto DataTable con los datosque hayamos indicado en la cadena de selección.

Crearemos los comandos que necesitaremos para actualizar los datos en la base dedatos (UPDATE, INSERT y DELETE). Esos comandos los creamos con un objetodel tipo SqlCommandBuilder que aunque no es la forma más efectiva, al menoses la más fácil de usar, y como de lo que en este artículo se trata es que sea fácil,pues eso... Los comandos los asignaremos a los objetos correspondientes deladaptador, esto en realidad no es necesario, pero algunas veces me ha dado erroral no hacerlo, así que... ¡mejor estar seguros de que se asignan!.

Debido a que la tabla de ejemplo utiliza un campo autoincremental, tendremos queasignar a la propiedad MissingSchemaAction el valor AddWithKey, de estaforma, al añadir nuevos registros se incrementará el valor del ID.

En la tabla de ejemplo, estamos usando un campo que contiene caracteres quepueden ser conflictivos, en este caso es simplemente un guión, pero podría ser unavocal acentuada, una eñe o contener espacios, en este caso lo que hacemos esindicar en el objeto del tipo CommandBuilder que utilice prefijo y sufijo para"envolver" automáticamente esos campos conflictivos, esa indicación la hacemosmediante las propiedades QuotePrefix y QuoteSufix.

Por último creamos el nuevo objeto del tipo DataTable, que será el que usemoscon el método Fill del adaptador, al usar ese método, será cuando se conecte conla base de datos y asigne a la tabla los datos indicados en la cadena de selección(SELECT).

En este ejemplo, le indico que traiga todos los datos, pero también podría haberseleccionado con una cláusula WHERE otros diferentes.

Página 7 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 8: 76533483-C-Sql-Base-de-datos

Otra cosa importante que debemos tener en cuenta con el códigode selección (SELECT) es que si en lugar de indicar un asterisco paraque se utilicen todos los campos ( SELECT * ), indicamos solo loscampos que nos interesan, en las actualizaciones y lecturas de datossolo podremos incluir los campos indicados.Por ejemplo, si hacemos: SELECT ID, Nombre FROM Prueba, tan solotendremos acceso a esos dos campos, y cualquier intento de acceder aotros campos (aunque sean válidos y existan en la tabla) dará error.

Finalmente habilitamos nuevamente los controles que están en el GroupBox paraque podamos navegar, añadir, eliminar, actualizar y escribir en las cajas de texto,y mostraremos el primer registro, para ello llamamos al código del evento delbotón para mostrar el primer registro.Si no hay datos, (es decir, si la tabla no contiene alguna fila), deshabilitamos elbotón de actualizar y el de eliminar, para permitir solo añadir nuevos datos.

private void btnConectar_Click(object sender, EventArgs e) {// Conectar y mostrar los datos//// La cadena de conexiónstring sCnn = "Server=" + cboInstancias.Text +

"; " + "database=" + cboBases.Text +"; integrated security=yes";

SqlConnection cnn = new SqlConnection(sCnn);if( existeTabla(cnn, "Prueba") == false ){

if( MessageBox.Show("NO existe la tabla Prueba, que es la usadapara este ejemplo.\n" +

"¿Quieres crearla?", "No existe la tabla",MessageBoxButtons.YesNo) == DialogResult.Yes )

{if( crearTablaPrueba() == false ){

return;}

}else{

return;}

}

// La cadena de selecciónstring sSel = "SELECT * FROM Prueba ORDER BY ID";//// Comprobar si hay algún errortry{

// Crear un nuevo objeto del tipo DataAdapterda = new SqlDataAdapter(sSel, sCnn);// Crear los comandos de insertar, actualizar y eliminarSqlCommandBuilder cb = new SqlCommandBuilder(da);// Como hay campos con caracteres especiales,// al usarlos incluirlos entre corchetes.cb.QuotePrefix = "[";cb.QuoteSuffix = "]";// Asignar los comandos al DataAdapter// (se supone que lo hace automáticamente, pero...)da.UpdateCommand = cb.GetUpdateCommand();da.InsertCommand = cb.GetInsertCommand();da.DeleteCommand = cb.GetDeleteCommand();//// Esta base de datos usa el ID con valores automáticosda.MissingSchemaAction = MissingSchemaAction.AddWithKey;//dt = new DataTable();

Página 8 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 9: 76533483-C-Sql-Base-de-datos

// Llenar la tabla con los datos indicadosda.Fill(dt);//// Habilitar los controlesforeach(Control c in this.GroupBox1.Controls){

c.Enabled = true;}this.GroupBox1.Enabled = true;this.GroupBox1.Text = "Conexión realizada";

// Y mostrar el primer registroif( dt.Rows.Count > 0 ){

btnFirst_Click(null, null);}else{

fila = -1;btnActualizar.Enabled = false;

}}catch(Exception ex){

MessageBox.Show("ERROR al conectar o recuperar los datos:\n" +ex.Message, "Conectar con la base",MessageBoxButtons.OK, MessageBoxIcon.Error);

}}

La función para saber si existe la tabla indicada

private bool existeTabla(SqlConnection cnn, string nombreTabla) {// Devuelve true si la tabla indicada está en la base usada con la

conexiónDataTable dt = new DataTable();bool existe = false;//try{

SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM INFORMATION_SCHEMA.TABLES " +"WHERE TABLE_TYPE = 'BASE TABLE' " +"ORDER BY TABLE_TYPE", cnn);

//da.Fill(dt);if( nombreTabla == null)

nombreTabla = "Prueba";foreach(DataRow dr in dt.Rows){

if( dr["TABLE_NAME"].ToString() == nombreTabla ){return true;

}}//return existe;

}catch(Exception ex){

MessageBox.Show("ERROR: " + ex.Message, "Comprobar tabla");return false;

}}

Página 9 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 10: 76533483-C-Sql-Base-de-datos

El método para crear la tabla de ejemplo (Prueba)

private bool crearTablaPrueba() {// Crear la tabla de prueba en la base e instancias seleccionadas// Devuelve true si todo fue bienbool creada = false;string sCnn = "Server=" + cboInstancias.Text + "; database=" +

cboBases.Text + "; integrated security=yes";string sCmd = "CREATE TABLE [dbo].[Prueba]( " +

"[ID] [int] IDENTITY(1,1) NOT NULL, " + "[Nombre][nvarchar](50) COLLATE Modern_Spanish_CI_AS NULL," +

"[e-mail] [nvarchar](128) COLLATE Modern_Spanish_CI_ASNULL," +

"[FechaAlta] [datetime] NULL," + "[Comentario] [nvarchar](2048) COLLATE Modern_Spanish_CI_AS NULL," +

"CONSTRAINT [PK_Prueba] PRIMARY KEY CLUSTERED (" +"[ID] ASC)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY])" +" ON [PRIMARY]";

SqlConnection cnn = null;try{

cnn = new SqlConnection(sCnn);cnn.Open();SqlCommand cmd = new SqlCommand(sCmd, cnn);

cmd.ExecuteNonQuery();creada = true;

}catch(Exception ex){

MessageBox.Show("Error al crear la tabla:\n" + ex.Message);

}finally{

if( cnn != null ){if( cnn.State == ConnectionState.Open ){

cnn.Close();}

}}

return creada;}

Añadir nuevos registros

Para añadir nuevos registros, lo primero que tenemos que hacer es crear unanueva fila.Para ello utilizamos el método NewRow del objeto DataTable.

Al usar ese método, nos aseguramos que la nueva fila creada tiene todos los datossobre la estructura de la tabla (o de la selección que hemos hecho), de forma quepodamos asignar los campos, etc.

La asignación de los campos la hacemos mediante el método asignarDatos,aunque podríamos haberlo hecho directamente.El hacerlo mediante ese método es para que nos resulte más cómo adaptar esteejemplo a otra tabla diferente a la que yo propongo, ya que en ese métodoharíamos todas las asignaciones que debamos hacer, salvo la del campo ID ya queal ser autonumérico no podemos asignarle un valor, porque ese valor lo asignará

Página 10 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 11: 76533483-C-Sql-Base-de-datos

automáticamente ADO.NET.

Una vez que la fila tiene asignados los valores de los campos, la añadimos a las filade la tabla. Esto es necesario, ya que el método NewRow solo crea una fila, perono la "relaciona" (o añade) a la tabla actual.

Finalmente actualizamos los datos mediante el método Update del adaptador.En realidad no hace falta hacer esa actualización en este preciso momento, pero sino lo hacemos, debemos añadir otro botón para que los datos se asignen a la basede datos, ya que al añadir un nuevo valor a la tabla, lo haremos en la "copia" quetenemos localmente en memoria, y no directamente en la base de datos, comoocurría, por ejemplo, con VB6 y los Recordsets.

Una vez actualizados los datos en la base de datos, le indicamos a la tabla queacepte los cambios que hayamos hecho, de forma que quede sincronizadanuevamente.Esto es necesario, ya que si no lo hacemos, la tabla mantendrá los cambios quehayamos hecho y si nuevamente "sincronizamos" esos datos con la base real, sepodrían producir errores.

Es importante que sepamos que cuando llamamos al método Updatedel adaptador, se realizan todas las actualizaciones, es decir, no soloañadir nuevos datos, como "se supone" que es lo que hace este método,sino que si hubiésemos eliminado filas, o modificado algunas, esasmodificaciones también se reflejarían en la base de datos.

Debido a cómo funcionan los campos autincrementales, para asegurarnos de queen realidad el valor de ese ID se actualiza correctamente, si es el primer registroque añadimos (o vale cero, como es la comprobación que hacemos aquí),deberíamos volver a leer los datos reales de la base de datos (que será después dehaber añadido el primer registro) con idea de que ese ID tenga el valor correcto.Esto no es necesario en los siguientes datos que vayamos añadiendo, ya que enotros casos el valor del ID se asignará correctamente.

Como ves, también controlamos los errores que se puedan producir... ¡nunca estáde más!

private void btnNuevo_Click(object sender, EventArgs e) {// Crear un nuevo registroDataRow dr = dt.NewRow();// Asignar los datos de los textbox a la filaasignarDatos(dr);

// Añadir la nueva fila a la tabladt.Rows.Add(dr);// Guardar físicamente los datos en la basetry{

da.Update(dt);dt.AcceptChanges();// Si es el primer registro de la base,// volver a leer los datos para actualizar los IDsif( Convert.ToInt32("0" + dr["ID"].ToString()) == 0 ){

dt = new DataTable();da.Fill(dt);

}// Posicionarlo en la última filabtnLast_Click(null, null);

}catch(DBConcurrencyException ex){MessageBox.Show("Error de concurrencia:\n" + ex.Message);

}catch(Exception ex){

Página 11 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 12: 76533483-C-Sql-Base-de-datos

MessageBox.Show(ex.Message);}

}

Si la caja de textos para la fecha no tiene nada, usamos un valor "nulo" paraasignar a ese campo.De todas formas, deberíamos usar un try/catch para comprobar que la fechaasignada es válida.

private void asignarDatos(DataRow dr) {// Usar los datos que hay en los textboxdr["Nombre"] = txtNombre.Text;dr["e-mail"] = txtEmail.Text;if( txtFechaAlta.Text == "" ){

dr["FechaAlta"] = DBNull.Value;}else{

dr["FechaAlta"] = txtFechaAlta.Text;}dr["Comentario"] = txtComentario.Text;

}

Actualizar los registros modificados

La actualización de los datos, es decir, cuando modificamos un registro (o fila) yqueremos que esos datos se guarden, es muy simple. En el código del método deactualizar, primero comprobamos que el valor de la variable fila sea válido, esdecir, esté dentro del rango de filas que tiene el DataTable.

Si es así, asignamos a una variable del tipo DataRow la fila en cuestión yposteriormente llamamos al método asignarDatos que vimos antes, que comosabes es el que se encarga de asignar las cajas de texto a los camposcorrespondientes.

Una vez que la fila tiene los nuevos datos, volvemos a llamar al método Update deladaptador, como comenté antes, esta llamada al método Update solo es necesariosi queremos asignar directamente los datos en la base, es decir, hacer que loscambios se hagan en ese preciso momento.

También encerramos esa actualización dentro de un Try/Catch para detectar loserrores que se puedan producir.

private void btnActualizar_Click(object sender, EventArgs e) {// Actualizar los datos en la fila actualif( fila < 0 || fila > dt.Rows.Count - 1 ) return;

DataRow dr = dt.Rows[fila];// Asignar los datos de los textbox a la filaasignarDatos(dr);

try{da.Update(dt);dt.AcceptChanges();

}catch(DBConcurrencyException ex){MessageBox.Show("Error de concurrencia:\n" + ex.Message);

}catch(Exception ex){MessageBox.Show(ex.Message);

Página 12 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 13: 76533483-C-Sql-Base-de-datos

}}

Eliminar el registro actual

Una vez que tenemos un registro mostrado, podemos pulsar en el botón Eliminar,para hacerlo, usamos el método Delete de la fila indicada y a continuación leindicamos al adaptador que actualice los datos físicamente en la base y a la tabla letenemos que indicar que acepte los cambios, con idea de que esa fila que hemoseliminado, la elimine también de la memoria.

Cuando eliminamos un registro, en nuestro programa se dejan los datos, de formaque si nos arrepentimos, podamos volver a crearlos, no recuperarlos, sino crear unregistro nuevo, con su nuevo ID, etc.

private void btnEliminar_Click(object sender, EventArgs e) {// Eliminar la fila actualif( fila < 0 || fila > dt.Rows.Count - 1 ) return;

try{// Eliminar la fila de la tabladt.Rows[fila].Delete();// Actualizar físicamente la base de datosda.Update(dt);// Aceptar los cambios en la copia localdt.AcceptChanges();

}catch(DBConcurrencyException ex){MessageBox.Show("Error de concurrencia:\n" + ex.Message);

}catch(Exception ex){MessageBox.Show(ex.Message);

}

}

Nota:Si lo que realmente te interesa es que los datos NO se eliminendirectamente en la base de datos, (ni se actualicen ni creen nuevos),hasta que tu quieras, la llamada al método Update del adaptador y lallamada al método AcceptChanges de la tabla no deberías llamarla enestos tres métodos que acabamos de ver, sino que puedes hacerlo, porejemplo, cuando el usuario "realmente" quiera que todos esos cambiosse hagan físicamente en la base de datos.Pero eso es, como siempre, a tu criterio.

Moverse entre registros, con comandos para ir alprimero, al último, al anterior y al siguiente

Página 13 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 14: 76533483-C-Sql-Base-de-datos

Para movernos entre los registros usaremos cuatro métodos, uno para ir alprincipio, otro para ir al final, otro para ir al registro anterior y otro para elsiguiente.

En estos cuatro métodos usaremos un método extra que será el que se encarguede comprobar si todo está correcto (o casi) y de mostrar los datos adecuados encada caja de texto. Al igual que antes con el método asignarDatos, lo he puestopor separado, entre otras cosas para facilitar la modificación del código para otrastablas.

También para que no haya que estar repitiendo en el resto de los métodos lascomprobaciones de que el valor de fila indicado está dentro del rango válido. Eserango debe estar entre cero para el primer registro y uno menos del número totalde filas para el último, por tanto, si el valor del número de la fila indicado no escorrecto, no hacemos nada, simplemente salimos del método.

En caso de que sigamos, quiere decir que es un valor de fila correcto, por tantoleemos esa fila (asignándola a una variable de tipo DataRow) y asignamos losvalores a las cajas de texto, en este caso si que usamos el valor del campo ID conidea de que veamos ese valor.

Por último habilitamos el botón de actualizar y eliminar, ya que se supone que haydatos.

private void mostrarDatos(int f) {int uf = dt.Rows.Count - 1;if( f < 0 || uf < 0 ) return;//DataRow dr = dt.Rows[f];txtID.Text = dr["ID"].ToString();txtNombre.Text = dr["Nombre"].ToString();txtEmail.Text = dr["e-mail"].ToString();txtFechaAlta.Text = dr["FechaAlta"].ToString();txtComentario.Text = dr["Comentario"].ToString();//btnActualizar.Enabled = true;btnEliminar.Enabled = true;

}

Los cuatro métodos para movernos son los siguientes, veamos que es lo quehacemos en cada uno de ellos, aunque creo que viendo el código queda clara laintención.

Nota:Como veremos en el código, en realidad no hace falta pasarle ningúnparámetro al método mostrarDatos, ya que al tener la variable filadisponible en todo el formulario, podríamos usar esa variable en lugardel parámetro, pero... lo dejo así por si se te ocurre hacer cambios y nousar esa variable, que hay gente que no le gusta usar variables"globales" al formulario o clase...

Para ir al primero, simplemente asignamos cero a la variable de la fila actual yllamamos al método de mostrar los datos.

Página 14 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 15: 76533483-C-Sql-Base-de-datos

private void btnFirst_Click(object sender, EventArgs e) {// Posicionarse en la primera filafila = 0;// Mostrar los datos de la fila indicadamostrarDatos(fila);

}

Para ir al último, averiguamos cual es la última fila, que como vemos es el valordevuelto por la propiedad Count de la colección de filas (Rows), menos uno, ya quecomo sabemos todos los arrays y colecciones de .NET siempre empiezan con elíndice cero.

private void btnLast_Click(object sender, EventArgs e) {// Posicionarse en la última filafila = dt.Rows.Count - 1;// Mostrar los datos de la fila indicadamostrarDatos(fila);

}

Para ir al anterior simplemente le restamos uno al valor de la fila actual, perodebemos hacer una comprobación de que no sea menor de cero, ya que es posibleque estemos en el primer registro y pulsemos en el botón de ir al anterior. En casode que estemos en el primero, seguiremos en ese mismo registro.

private void btnPrev_Click(object sender, EventArgs e) {// Posicionarse en la fila anteriorfila = fila - 1;if( fila < 0 ) fila = 0;// Mostrar los datos de la fila indicadamostrarDatos(fila);

}

Por último, para ir al siguiente, hacemos lo mismo que antes, pero en lugar derestar uno, lo que hacemos es añadir uno al valor de la fila actual, y en el caso deque sea mayor que la última fila, pues nos quedamos en esa última fila.

private void btnNext_Click(object sender, EventArgs e) {// Posicionarse en la fila siguienteint uf = dt.Rows.Count - 1;fila = fila + 1;if( fila > uf ) fila = uf;// Mostrar los datos de la fila indicadamostrarDatos(fila);

}

Link al código de ejemplo

Aquí tienes los links al código de ejemplo para Visual C#. El proyecto está creadocon Visual Studio 2003, pero funcionará igualmente en la versión 2005 y concambios menores, también en la versión 2002.

El código para Visual C#: ejemploDatosSQLCS.zip - 11.00 KB

Página 15 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.

Page 16: 76533483-C-Sql-Base-de-datos

(MD5 checksum: 9ADF5E65CA151BE0B1045C61B6E1985A)

La cajita de Panorama Box:

Calificación:Lectores: 20

Autor: Guillermo guilleSom

Calif. Autor:DCE: 1

Normal Calificar

Mi Panorama SOSEscribe para Nosostros

Página 16 de 16Acceso a una base de datos de SQL Server con ADO.NET y Visual C#

20/07/2006http://www.elguille.info/NET/ADONET/ejemplo_adonet_sql_csharp.htmAcroPDF - A Quality PDF Writer and PDF Converter to create PDF files. To remove the line, buy a license.