lunes, 10 de junio de 2013

Ejecutar un procedimiento almacenado de SQL Server desde C#

Para explicar este tema se creó una sencilla aplicación de formas en Visual Studio utilizando C#, también se creó una base de datos que cuenta con tres tablas y un procedimiento almacenado para de acuerdo a las variables que recibe el parámetro realice un insert en alguna de las tablas.
El procedimiento almacenado comparará al variable edad y dependiendo de ella insertará a la persona en la tabla debida, además retorna una variable  de comprobación para asegurar que la operación fue satisfactoria.

Realizando una prueba.

Cuando ocurre un error: en este ejercicio pueden surgir varios pues no se validan los datos que se envían al procedimiento almacenado.
 Cuando la operación fue satisfactoria:

Comprobación de la inserción en SQL Server


Diseño  de la forma:

Elementos del combobox:


Código de la aplicación:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;//libreria para manejar sql

namespace Personal
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnguardar_Click(object sender, EventArgs e)
        {
            //declaramos una cadena de conexión con los datos de nuestro
            //manejador y la base de datos
            string cadenaconexion = @"Data Source=HUGUITO-PC\HUGO;Initial Catalog=Prueba;Integrated Security=True";
            //una variable boleana para determinar si se realizó la operación
            //que realiza el procedimiento almacenado, la inicializamos como false
            bool success = false;
            //declrarmos la conexión
            SqlConnection LaConexion = null;
            //declaramos una transacción para que todo lo que se realiza en ella, desde una
            //simple inserción hasta multiples o, que involucren más operaciones sobre la
            //base de datos puedan deshacerse si se presenta un error
            SqlTransaction LaTransaccion = null;
            //variable para el valor de retorno
            int Valor_Retornado = 0;
            //iniciamos un try catch
            try
            {
                //seguimos con la conexion
                LaConexion = new SqlConnection();
                //asignamos a la conexión la cadena de conexión que declaramos anteriormente
                LaConexion.ConnectionString = cadenaconexion;
                //se abre la conexión
                LaConexion.Open();
                //se inicia la transacción
                LaTransaccion = LaConexion.BeginTransaction(System.Data.IsolationLevel.Serializable);
                //especificamos el comando, en este caso el nombre del Procedimiento Almacenado
                SqlCommand comando = new SqlCommand("SPPersonal", LaConexion, LaTransaccion);
                //se indica al tipo de comando que es de tipo procedimiento almacenado
                comando.CommandType = CommandType.StoredProcedure;
                //se limpian los parámetros
                comando.Parameters.Clear();
                //comenzamos a mandar cada uno de los parámetros, deben de enviarse en el
                //tipo de datos que coincida en sql server por ejemplo c# es string en sql server es varchar()
                comando.Parameters.AddWithValue("@Nombre", txtnombre.Text);
                comando.Parameters.AddWithValue("@Apellp", txtapellp.Text);
                comando.Parameters.AddWithValue("@Apellm", txtapellm.Text);
                comando.Parameters.AddWithValue("@Edad",Convert.ToInt32(txtedad.Text));
                comando.Parameters.AddWithValue("@Sexo", cboxsexo.SelectedItem);
                //declaramos el parámetro de retorno
                SqlParameter ValorRetorno = new SqlParameter("@Comprobacion", SqlDbType.Int);
                //asignamos el valor de retorno
                ValorRetorno.Direction = ParameterDirection.Output;
                comando.Parameters.Add(ValorRetorno);
                //executamos la consulta
                comando.ExecuteNonQuery();
                // traemos el valor de retorno
                Valor_Retornado = Convert.ToInt32(ValorRetorno.Value);
                //dependiendo del valor de retorno se asigna la variable success
                //si el procedimiento retorna un 1 la operación se realizó con éxito
                //de no ser así se mantiene en false y pr lo tanto falló la operación
                if (Valor_Retornado ==1)
                    success = true;
           }
            catch (Exception)
            {
                //al ocurrir un error mostramos un mensaje
                MessageBox.Show("Error en la operación", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
               //si el procedimeinto se efectuó con éxito
                if (success)
                {
                    //se realiza la transacción
                    LaTransaccion.Commit();
                    //cerramos la conexión
                    LaConexion.Close();
                    //mensaje de operación satisfactoria
                    MessageBox.Show("Persona guardada\nsatisfactoriamente", "Aviso", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                    //si se presentó algun error
                else
                {
                    //se deshace la transacción
                    LaTransaccion.Rollback();
                    //cerramos la conexión
                    LaConexion.Close();
                }
            }
        }


    }
}


Base de datos con las tres tablas y el procedimiento almacenado:

create database Prueba
go
use Prueba
go

create table Menores
(
ID_Menores int primary key identity(1,1),
Nombre_M varchar(30) not null,
Apellp_M varchar(20) not null,
Apellm_M varchar(20) not null,
Sexo_M char(1) not null,
Fecha_Reg_M date not null
)

create table Adultos
(
ID_Adutos int primary key identity(1,1),
Nombre_A varchar(30) not null,
Apellp_A varchar(20) not null,
Apellm_A varchar(20) not null,
Sexo_A char(1) not null,
Fecha_Reg_A date not null
)

create table Adulto_Mayor
(
ID_Mayores int primary key identity(1,1),
Nombre_AM varchar(30) not null,
Apellp_AM varchar(20) not null,
Apellm_AM varchar(20) not null,
Sexo_AM char(1) not null,
Fecha_Reg_AM date not null
)
create procedure SPPersonal
(
@Nombre varchar(30),
@Apellp varchar(20),
@Apellm varchar(20),
@Edad int,
@Sexo char(1),
@Comprobacion int output
)
as
begin
--inicia la transacción
begin transaction
--inician las comparaciones de edad para determinar donde insertar a la persona
--si existe un error al insertar se pasa  a la parte de error
      if(@Edad<18)
      begin
            INSERT INTO Menores(Nombre_M,Apellp_M,Apellm_M,Sexo_M,Fecha_Reg_M)VALUES(@Nombre,@Apellp,@Apellm,@Sexo,GETDATE())
            if @@ERROR>0
            goto error
      end
      else if(@Edad>=18 and @Edad<65)
      begin
            INSERT INTO Adultos(Nombre_A,Apellp_A,Apellm_A,Sexo_A,Fecha_Reg_A)VALUES(@Nombre,@Apellp,@Apellm,@Sexo,GETDATE())
            if @@ERROR>0
            goto error
      end
      else if(@Edad>=65)
      begin
            INSERT INTO Menores(Nombre_M,Apellp_M,Apellm_M,Sexo_M,Fecha_Reg_M)VALUES(@Nombre,@Apellp,@Apellm,@Sexo,GETDATE())
            if @@ERROR>0
            goto error
      end
      --si no hubo errores se termina la transacción y se asigna a @Comprobacion el valor de 1
      --para indicar en c# que fue exitosa la operación
      commit transaction
      set @Comprobacion=1
      return
--si hubo algún error se deshace la transacción y se asigna a @Comprobación el valor de 0
--para indicar en c# que hubo un error

error:     
rollback transaction
set @Comprobacion=0
end

1 comentario: