Generalmente necesitamos guardar un registro e inmediatamente insertar otros relacionados en otras tablas. Un ejemplo claro sería el de la facturación, para el cual necesitamos por lo menos dos tablas: una para guardar la información de la factura y las partes implicadas, y otra para el detalle de la misma. Tal vez muchos se han encontrado con el problema de obtener el ID del registro recien insertado, para solucionar esto tenemos a nuestra disposición una función llamada SCOPE_IDENTITY.
(Para SQLServer CE investigar sobre @@IDENTITY).
Definición
SCOPE_IDENTITY() es una función capaz de devolver el valor de la columna de identidad (llave, index, etc) recien insertada.
Implementación
Para llevar a cabo la implementación de esta función tomaremos como ejemplo un caso en el cuál un registro se guarda en dos tablas: una tabla de Clientes y otra de Monitoreo de Actividad.
Estructura de Tablas
Clientes
- Cli_Id (int) (identidad) (NO NULL)
- Cli_Nombre (nvarchar(60)) (NO NULL)
- Cli_Direccion (nvarchar(50))(NULL)
- Cli_Telefono (nvarchar(30))(NULL)
- Cli_Email (nvarchar(30))(NULL)
Monitor
- Mon_Id (int) (identidad) (NO NULL)
- Mon_IdRegistro (int) (NO NULL)
- Mon_NombreTabla (nvarchar(50))(NO NULL)
Code-behind
C#
//Variable de Conexión SqlConnection con = new SqlConnection("Data Source=USER\\SQLEXPRESS;Initial Catalog=basePrueba;Integrated Security=True"); con.Open(); //Variable que contendrá el valor de la columna de identidad devuelto por la función SCOPE_IDENTITY() int idRegistro = 0; //Armo el Query para Clientes //A la hora de declarar el query agrego la función SCOPE_IDENTITY() SqlCommand cmd = new SqlCommand("INSERT INTO Clientes " + "(Cli_Nombre, Cli_Direccion, Cli_Telefono, Cli_Email) " + "VALUES" + "(@nombre, @direccion, @telefono, @email) " + "SELECT SCOPE_IDENTITY()", con); cmd.Parameters.Add("@nombre", SqlDbType.NVarChar).Value = txtNombre.Text; cmd.Parameters.Add("@direccion", SqlDbType.NVarChar).Value = txtDireccion.Text; cmd.Parameters.Add("@telefono", SqlDbType.NVarChar).Value = txtTelefono.Text; cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = txtEmail.Text; //Ejecuto la consulta y obtengo el valor devuelto por la misma idRegistro = Convert.ToInt32(cmd.ExecuteScalar()); //Armo Query para el Monitor de Actividades //En la consulta paso un parámetro con el valor obtenido de la consulta anterior cmd.CommandText = "INSERT INTO Monitor " + "(Mon_IdRegistro, Mon_NombreTabla) " + "VALUES" + "(@idRegistro, @nombreTabla)"; cmd.Parameters.Add("@idRegistro", SqlDbType.Int).Value = idRegistro; cmd.Parameters.Add("@nombreTabla", SqlDbType.NVarChar).Value = "Clientes"; cmd.ExecuteNoQuery(); con.Close();
VB.NET
'Variable de Conexión Dim con As New SqlClient.SqlConnection("Data Source=USER\\SQLEXPRESS;Initial Catalog=basePrueba;Integrated Security=True") con.Open() 'Variable que contendrá el valor de la columna de identidad devuelto por la función SCOPE_IDENTITY() Dim idRegistro As Integer = 0 'Armo el Query para Clientes 'A la hora de declarar el query agrego la función SCOPE_IDENTITY() Dim cmd As New SqlClient.SqlCommand("INSERT INTO Clientes " _ & "(Cli_Nombre, Cli_Direccion, Cli_Telefono, Cli_Email) " _ & "VALUES" _ & "(@nombre, @direccion, @telefono, @email) " _ & "SELECT SCOPE_IDENTITY()", con) cmd.Parameters.Add("@nombre", SqlDbType.NVarChar).Value = txtNombre.Text cmd.Parameters.Add("@direccion", SqlDbType.NVarChar).Value = txtDireccion.Text cmd.Parameters.Add("@telefono", SqlDbType.NVarChar).Value = txtTelefono.Text cmd.Parameters.Add("@email", SqlDbType.NVarChar).Value = txtEmail.Text 'Ejecuto la consulta y obtengo el valor devuelto por la misma idRegistro = Convert.ToInt32(cmd.ExecuteScalar()) 'Armo Query para el Monitor de Actividades 'En la consulta paso un parámetro con el valor obtenido de la consulta anterior cmd.CommandText = "INSERT INTO Monitor " _ & "(Mon_IdRegistro, Mon_NombreTabla) " _ & "VALUES" _ & "(@idRegistro, @nombreTabla)" cmd.Parameters.Add("@idRegistro", SqlDbType.Int).Value = idRegistro cmd.Parameters.Add("@nombreTabla", SqlDbType.NVarChar).Value = "Clientes" cmd.ExecuteNoQuery(); con.Close()
Seudocódigo
1. Declaro variable de conexión y le asigno un Connection String
2. Abro la Conexión
3. Declaro la variable 'idRegistro' que contendrá el valor de la columna de identidad del registro recién insertado
4. Declaro variable Command y le asigno un CommandText
--CommandText: Insertar en Clientes: en los campos (campos) los valores (valores) y seleccionar el valor del campo de identidad
5. Agrego los parámetros necesarios
6. Ejecuto la consulta y obtengo el valor solicitado
7. Asigno CommandText
--CommandtText: Insertar en Monitor: en los campos (campos) los valores (valores)
8. Agrego parámetros necesarios
--Parametro 'idRegistro': lo igualo al valor obtenido en la consulta anterior.
9. Ejecuto el query
10. Cierro la conexión