Insertar registro com SqlCommand
-
Sunday, March 21, 2010 4:55 PM
A raiz de una consulta anterior estoy tratando de usar un SQLCommand para insertar un nuevo registro en esta tabla
USE [LA] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[ProveedorArticulos] ( [ProveedorArticuloID] [int] IDENTITY(1,1) NOT NULL , [ProveedorID] [int] NULL , [ArticuloID] [int] NULL , [ProveedorPrincipal] [bit] NULL , [ProveedorUnico] [bit] NULL , [CantidadPedidoHabitual] [real] NULL , [CantidadPedidoMinima] [real] NULL , [PlazoEntrega] [int] NULL , [PeriodosServicio] [int] NULL , [Observaciones] [varchar](150) COLLATE Modern_Spanish_CI_AS NULL , [FechaModificacion] [smalldatetime] NULL , [UsuarioModificacion] [int] NULL , PRIMARY KEY CLUSTERED ( [ProveedorArticuloID] ASC ) WITH ( PAD_INDEX = OFF , STATISTICS_NORECOMPUTE = OFF , IGNORE_DUP_KEY = OFF , ALLOW_ROW_LOCKS = ON , ALLOW_PAGE_LOCKS = ON ) ON [PRIMARY] ) ON [PRIMARY] GO ALTER TABLE [dbo].[ProveedorArticulos] WITH CHECK ADD FOREIGN KEY ( [ArticuloID] ) REFERENCES [Articulos] ( [ArticuloID] ) GO ALTER TABLE [dbo].[ProveedorArticulos] WITH CHECK ADD FOREIGN KEY ( [PeriodosServicio] ) REFERENCES [PeriodosServicio] ( [ProveedorIDArticuloID] ) GO ALTER TABLE [dbo].[ProveedorArticulos] WITH CHECK ADD CONSTRAINT [FK__Proveedor__Prove__40C567B9] FOREIGN KEY ( [ProveedorID] ) REFERENCES [Proveedores] ( [ProveedorID] ) GO ALTER TABLE [dbo].[ProveedorArticulos] CHECK CONSTRAINT [FK__Proveedor__Prove__40C567B9] GOel codigo que uso es
Try ' Creamos el comando, especificando el nombre del procedimiento almacenado que se desea ejecutar. Dim cmd As New SqlCommand("InsertProveedorArticulos") ' Configuramos el comando With cmd '.Connection = Cnx .CommandType = CommandType.StoredProcedure End With ' Conforme creamos los distintos parámetros asignamos sus valores. Dim p As SqlParameter ' Clave principal: no admite valores NULL p = New SqlParameter("@ProveedorID", SqlDbType.Int) 'Integer.TryParse(txtProveedorID.Text, proveedorID) p.Value = Proveedor cmd.Parameters.Add(p) ' Los restantes campos admiten valores NULL p = New SqlParameter("@ArticuloID", SqlDbType.Int) p.Value = IIf(ArticuloIDComboMAM.SelectedValue Is String.Empty, DBNull.Value, ArticuloIDComboMAM.SelectedValue) cmd.Parameters.Add(p) p = New SqlParameter("@ProveedorPrincipal", SqlDbType.Bit) p.Value = IIf(ProveedorPrincipalCheckBox.Checked, 1, 0) cmd.Parameters.Add(p) p = New SqlParameter("@ProveedorUnico", SqlDbType.Bit) p.Value = IIf(ProveedorUnicoCheckBox.Checked, 1, 0) cmd.Parameters.Add(p) p = New SqlParameter("@CantidadPedidoHabitual", SqlDbType.Real) p.Value = IIf(CantidadPedidoHabitualCuadroDeTexto.Text = String.Empty, DBNull.Value, CInt(CantidadPedidoHabitualCuadroDeTexto.Text)) cmd.Parameters.Add(p) p = New SqlParameter("@CantidadPedidoMinima", SqlDbType.Real) p.Value = IIf(CantidadPedidoMinimaCuadroDeTexto.Text = String.Empty, DBNull.Value, CInt(CantidadPedidoMinimaCuadroDeTexto.Text)) cmd.Parameters.Add(p) p = New SqlParameter("@PlazoEntrega", SqlDbType.Int) p.Value = IIf(PlazoEntregaCuadroDeTexto.Text = String.Empty, DBNull.Value, CInt(PlazoEntregaCuadroDeTexto.Text)) cmd.Parameters.Add(p) p = New SqlParameter("@PeriodosServicio", SqlDbType.Int) p.Value = 1 cmd.Parameters.Add(p) p = New SqlParameter("@Observaciones", SqlDbType.NVarChar, 150) p.Value = IIf(ObservacionesCuadroDeTexto.Text = String.Empty, DBNull.Value, ObservacionesCuadroDeTexto.Text) cmd.Parameters.Add(p) p = New SqlParameter("@FechaModificacion", SqlDbType.SmallDateTime) p.Value = ",'" + ArmarFecha(Today + " " + TimeOfDay) + "'," cmd.Parameters.Add(p) p = New SqlParameter("@UsuarioModificacion", SqlDbType.Int) p.Value = gUsuarioID.ToString cmd.Parameters.Add(p) ' Ejecutamos el procedimiento Dim n As Integer = BD.EjecutarComando(cmd) 'Dim n As Integer = cmd.ExecuteNonQuery() MessageBox.Show(String.Format("{0} registro añadido.", n)) Catch ex As Exception MessageBox.Show(ex.Message) End TryPublic Function EjecutarComando(ByVal Comando As SqlCommand) As Integer Dim exito As Integer Conectar() 'Dim cmd As SqlCommand 'cmd = New SqlCommand(Comando, Cnx) Try Comando.ExecuteNonQuery() exito = 1 Catch ex As Exception exito = 0 End Try Comando.Dispose() Cerrar() Return exito End FunctionY el procedimiento almacenadoCREATE PROCEDURE [dbo].[InsertProveedorArticulos] -- declare variables here @ProveedorID int , @ArticuloID int , @ProveedorPrincipal bit , @ProveedorUnico bit , @CantidadPedidoHabitual real , @CantidadPedidoMinima real , @PlazoEntrega int , @PeriodosServicio int , @Observaciones varchar(150) , @FechaModificacion smalldatetime , @UsuarioModificacion int AS INSERT INTO [LA].[dbo].[ProveedorArticulos] ( [ProveedorID] , [ArticuloID] , [ProveedorPrincipal] , [ProveedorUnico] , [CantidadPedidoHabitual] , [CantidadPedidoMinima] , [PlazoEntrega] , [PeriodosServicio] , [Observaciones] , [FechaModificacion] , [UsuarioModificacion] ) VALUES ( @ProveedorID , @ArticuloID , @ProveedorPrincipal , @ProveedorUnico , @CantidadPedidoHabitual , @CantidadPedidoMinima , @PlazoEntrega , @PeriodosServicio , @Observaciones , @FechaModificacion , @UsuarioModificacion ) GONo me da ningun error, pero no añade ningún registro.
Entiendo que no hay que pasar el campo
[ProveedorArticuloID] [int] IDENTITY(1,1)
ya que es IDENTITY, pero no estoy seguro, os agradecere si me podeis ayudar comprobando donde esta el problema.
Gracias.
Miguel Angel Martinez correomam@gmail.com
All Replies
-
Sunday, March 21, 2010 4:57 PMModeratorHola ProveedorID no lo tienes que declarar ni incluirlo en la sentencia sql.
Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta por favor marca las respuestas que te hayan ayudado como "Respuesta".
Si la respuesta te ha sido util Votala.
Mi Blog: Jtorrecilla
Enlace a Faq de Winforms en Ingles Muy bueno -
Sunday, March 21, 2010 5:08 PM
Supongo que te refieres a
ProveedorArticuloID
no a ProveedorID
Miguel Angel Martinez correomam@gmail.com -
Sunday, March 21, 2010 5:12 PMModerator
Perdon lei mal la pregunta,
Haz esto: dim resultado as integer
resultado=cmd.ExecuteNonQuery()
if resultado>0 then
Msgbox("Se ha insertado el registro.")
end if
Por otro lado:
p = New SqlParameter("@FechaModificacion", SqlDbType.SmallDateTime) p.Value = ",'" + ArmarFecha(Today + " " + TimeOfDay) + "',"
esa parte es incorrecta te sobras las "," y ArmarFecha debera devolverte un valor del tipo DateTime,para que funcione correctamente.
Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta por favor marca las respuestas que te hayan ayudado como "Respuesta".
Si la respuesta te ha sido util Votala.
Mi Blog: Jtorrecilla
Enlace a Faq de Winforms en Ingles Muy bueno- Marked As Answer by mam01 Sunday, March 21, 2010 6:44 PM
-
Sunday, March 21, 2010 5:39 PMModerator
"man01" escribió:
> No me da ningun error, pero no añade ningún registro.
Sí te dará un error a la hora de ejecutar el método ExecuteNonQuery, pero cuando lo capturas, no muestras la descripción del mismo. Si lo deseas comprobar, en el bloque Catch de la función EjecutarComando, inserta lo siguiente:
Try
Comando.ExecuteNonQuery()
exito = 1
Catch ex As Exception
exito = 0
MessageBox.Show(ex.Message)End Try
No se añade ningún registro porque NO HAS ABIERTO LA CONEXIÓN, y al ejecutar el método ExecuteNonQuery es cuando se produce la excepción. Antes de llamar al citado método, tienes que abrir expresamente la conexión:
Public Function EjecutarComando(ByVal Comando As SqlCommand) As Integer
Dim exito As Integer
Conectar()
'Dim cmd As SqlCommand
'cmd = New SqlCommand(Comando, Cnx)
Try
' Indicamos el objeto SqlConnection del comando
Comando.Connection = Cnx
' Abrimos explícitamente la conexión
Cnx.Open()Comando.ExecuteNonQuery()
exito = 1
Catch ex As Exception
exito = 0
MessageBox.Show(ex.Message)End Try
Comando.Dispose()
Cerrar()
Return exito
End FunctionTen en cuenta que al objeto Command le tienes que indicar el objeto Connection que va a utilizar, y éste objeto Connection tienes que abrirlo expresamente para ejecutar la consulta SQL, e inmediatamente cerrarlo cuando la misma se haya ejecutado.
> Entiendo que no hay que pasar el campo
> [ProveedorArticuloID] [int] IDENTITY(1,1)
> ya que es IDENTITY, pero no estoy seguro
Efectivamente. Si el campo está definido como IDENTITY, no lo puedes incluir en el procedimiento almacenado, ni tampoco asignarle un valor, porque es el propio SQL Server el que le asignará su valor cuando se añada el nuevo registro a la tabla.
Enrique Martínez [MS MVP - VB]- Proposed As Answer by Enrique M. MontejoMVP, Moderator Sunday, March 21, 2010 5:41 PM
- Marked As Answer by mam01 Sunday, March 21, 2010 6:44 PM
-
Sunday, March 21, 2010 6:31 PMModerator
hola
porque no pruebas algo como esto
Try
' Creamos el comando, especificando el nombre del procedimiento almacenado que se desea ejecutar.
Using cmd As New SqlCommand("InsertProveedorArticulos", Cnx)
cmd.CommandType = CommandType.StoredProcedure
' Conforme creamos los distintos parámetros asignamos sus valores.
Dim p As SqlParameter
' Clave principal: no admite valores NULL
p = New SqlParameter("@ProveedorID", SqlDbType.Int)
p.Direction = ParameterDirection.Output
cmd.Parameters.Add(p)
' Los restantes campos admiten valores NULL
p = New SqlParameter("@ArticuloID", SqlDbType.Int)
p.Value = IIf(ArticuloIDComboMAM.SelectedValue Is String.Empty, DBNull.Value, ArticuloIDComboMAM.SelectedValue)
cmd.Parameters.Add(p)
p = New SqlParameter("@ProveedorPrincipal", SqlDbType.Bit)
p.Value = IIf(ProveedorPrincipalCheckBox.Checked, 1, 0)
cmd.Parameters.Add(p)
p = New SqlParameter("@ProveedorUnico", SqlDbType.Bit)
p.Value = IIf(ProveedorUnicoCheckBox.Checked, 1, 0)
cmd.Parameters.Add(p)
p = New SqlParameter("@CantidadPedidoHabitual", SqlDbType.Real)
p.Value = IIf(CantidadPedidoHabitualCuadroDeTexto.Text = String.Empty, DBNull.Value, CInt(CantidadPedidoHabitualCuadroDeTexto.Text))
cmd.Parameters.Add(p)
p = New SqlParameter("@CantidadPedidoMinima", SqlDbType.Real)
p.Value = IIf(CantidadPedidoMinimaCuadroDeTexto.Text = String.Empty, DBNull.Value, CInt(CantidadPedidoMinimaCuadroDeTexto.Text))
cmd.Parameters.Add(p)
p = New SqlParameter("@PlazoEntrega", SqlDbType.Int)
p.Value = IIf(PlazoEntregaCuadroDeTexto.Text = String.Empty, DBNull.Value, CInt(PlazoEntregaCuadroDeTexto.Text))
cmd.Parameters.Add(p)
p = New SqlParameter("@PeriodosServicio", SqlDbType.Int)
p.Value = 1
cmd.Parameters.Add(p)
p = New SqlParameter("@Observaciones", SqlDbType.NVarChar, 150)
p.Value = IIf(ObservacionesCuadroDeTexto.Text = String.Empty, DBNull.Value, ObservacionesCuadroDeTexto.Text)
cmd.Parameters.Add(p)
p = New SqlParameter("@FechaModificacion", SqlDbType.SmallDateTime)
p.Value = ",'" + ArmarFecha(Today + " " + TimeOfDay) + "',"
cmd.Parameters.Add(p)
p = New SqlParameter("@UsuarioModificacion", SqlDbType.Int)
p.Value = gUsuarioID.ToString
cmd.Parameters.Add(p)
Dim n As Integer = cmd.ExecuteNonQuery()
If n = 0 Then
MessageBox.Show("No se han actualizado registros")
else
Dim id As Integer = CInt(cmd.Parameters["@ProveedorID"])
MessageBox.Show(String.Format("Se ha creado el proveedor con Id: {0}", id))
End If
End Using
Catch ex As Exception
MessageBox.Show(ex.Message)
End Tryy en procedure de esta forma
CREATE PROCEDURE [dbo].[InsertProveedorArticulos]
-- declare variables here
@ProveedorID int OUTPUT,
@ArticuloID int ,
@ProveedorPrincipal bit ,
@ProveedorUnico bit ,
@CantidadPedidoHabitual real ,
@CantidadPedidoMinima real ,
@PlazoEntrega int ,
@PeriodosServicio int ,
@Observaciones varchar(150) ,
@FechaModificacion smalldatetime ,
@UsuarioModificacion int
AS
INSERT INTO
[LA].[dbo].[ProveedorArticulos]
(
[ArticuloID] ,
[ProveedorPrincipal] ,
[ProveedorUnico] ,
[CantidadPedidoHabitual] ,
[CantidadPedidoMinima] ,
[PlazoEntrega] ,
[PeriodosServicio] ,
[Observaciones] ,
[FechaModificacion] ,
[UsuarioModificacion] )
VALUES
(
@ArticuloID ,
@ProveedorPrincipal ,
@ProveedorUnico ,
@CantidadPedidoHabitual ,
@CantidadPedidoMinima ,
@PlazoEntrega ,
@PeriodosServicio ,
@Observaciones ,
@FechaModificacion ,
@UsuarioModificacion )SELECT @ProveedorID = SCOPE_IDENTITY()
GOcomo veras no requieres una funcion nueva solo para ejecutar el comando, puede hacerlo directo y consulta por el id que se genero en el procedure
ademas si usas el using para crear el command no necesitar preocuparte por cerrarlo, o destruir el objeto
saludos
Leandro Tuttini
Blog
Buenos Aires
Argentina- Proposed As Answer by jtorrecillaMVP, Moderator Sunday, March 21, 2010 6:35 PM
- Marked As Answer by mam01 Sunday, March 21, 2010 6:44 PM
-
Sunday, March 21, 2010 6:42 PMModerator
"Leandro Tuttini" escribió:
> como veras no requieres una funcion nueva solo para ejecutar el comando
¿Tampoco es necesario ABRIR EL OBJETO SQLCONNECTION para ejecutar la consulta de acción?
Entiendo que el problema del usuario man01 es que no abre la conexión para ejecutar el método ExecuteNonQuery, salvo que ésta la abra en el método Conectar(). Así que por mucho que utilice tu ejemplo, si no abre la conexión, va a ejecutar lo que yo sé. :-)
Enrique Martínez [MS MVP - VB]- Edited by Enrique M. MontejoMVP, Moderator Sunday, March 21, 2010 6:45 PM
-
Sunday, March 21, 2010 6:44 PMModeratorSoftjaen, llevas razon es necesario abrir la conexion.
Para el correcto funcionamiento, y que otros usuarios se puedan beneficiar de la solucion de esta pregunta por favor marca las respuestas que te hayan ayudado como "Respuesta".
Si la respuesta te ha sido util Votala.
Mi Blog: Jtorrecilla
Enlace a Faq de Winforms en Ingles Muy bueno -
Sunday, March 21, 2010 6:47 PMModerator
"jtorrecilla" escribió:
> Softjaen, llevas razon es necesario abrir la conexion.
¡Claro que es necesario! Estamos utilizando lo que se conoce como la arquitectura conectada de ADO .NET, por tanto, si no hay una conexión abierta, no se puede ejecutar ninguna consulta SQL, tanto de selección como de acción.
Un saludo
Enrique Martínez [MS MVP - VB] -
Sunday, March 21, 2010 6:49 PM
Gracias por vuestras correcciones, efectivamente tenia un error en
p = New SqlParameter("@FechaModificacion" , SqlDbType.SmallDateTime)
p.Value = ",'" + ArmarFecha(Today + " " + TimeOfDay) + "',"
esa parte es incorrecta te sobras las "," y ArmarFecha debera devolverte un valor del tipo DateTime,para que funcione correctamente.
Y tampoco abría la conexion como bien dice SofJaen, pero no detectaba el error.
He incorporado las ideas de Leandro.
Como siempre vuestro apoyo es inestimable.
Miguel Angel Martinez correomam@gmail.com -
Sunday, March 21, 2010 6:53 PMModerator
hola
En realidad no la puse porque pense o di por sentado que la estaba abriendo en algun otro punto del codigo, el cual no estoy pudiendo veren el bloque que ha posteando
es mas en la reforma del codigo que le sugeria tampoco puse el bloque del using que encerraria al objeto de conexion, porque no se de donde lo esta tomando, al menos el codigo que ha puesto no lo puedo ver
pero si, tienes toda la razon, sino lo esta abriendo seguro obntendra un error, pero llegado ese punto con la reforma que plantee, seguro podra visualizar el mensaje y agregar la linea de apertura de la conexion
algo que si vi, es que en este metodo
Public Function EjecutarComando(ByVal Comando As SqlCommand) As Integer
Dim exito As Integer
Conectar()
'Dim cmd As SqlCommand
'cmd = New SqlCommand(Comando, Cnx)
Try
Comando.ExecuteNonQuery()
exito = 1
Catch ex As Exception
exito = 0
End Try
Comando.Dispose()
Cerrar()
Return exito
End Functionusa en Conectar() que no se si solo esta creando la conexion o la esta abriendo alli mismo, no sabria decirlo
saludos
Leandro Tuttini
Blog
Buenos Aires
Argentina- Edited by Leandro TuttiniMVP, Moderator Sunday, March 21, 2010 7:01 PM
-
Sunday, March 21, 2010 7:00 PMModerator
Si el código que está utilizando el usuario man01, es el mismo que ésta mañana yo le he indicado que ejecutara, que también utiliza una instrucción Using para ejecutar el procedimiento almacenado. Pero, ¡claro! En mi ejemplo le indicaba claramente que tenía que abrir la conexión, cosa que él ha omitido a la hora de adaptar el ejemplo a sus necesidades.
Y como en el bloque Catch sólo se limitaba a devolver el valor 0, pues tampoco era consciente de la excepción que con toda seguridad se produce cuando se llama al método ExecuteNonQuery sin estar la conexión abierta del objeto SqlCommand.
Enrique Martínez [MS MVP - VB] -
Sunday, March 21, 2010 7:03 PMModerator
hola
para la fecha prueba usar
p = New SqlParameter("@FechaModificacion", SqlDbType.SmallDateTime)
p.Value = DateTime.Now.Date
cmd.Parameters.Add(p)como has definido el parametro de tipo fecha deberia reconocer el formato sin problemas
saludos
Leandro Tuttini
Blog
Buenos Aires
Argentina

