none
Instrucción DELETE en conflicto con la restricción REFERENCE RRS feed

  • Pregunta

  • Buenas tardes a la comunidad de ayuda. Tengo una base para un sistema de Facturacion e Inventario, donde he creado varias tablas relacionales, pero entre ella tengo la tabla Factura y Detalle_Factura; que al querer eliminar Factura primero por código en C# con procedimientos almacenados, ésta entra en conflicto con Detalle_Factura por su id relacional. Por consiguiente, si elimino primero Detalle_Factura, lo hace bien, pero después en el mismo código quiero eliminar Factura, ahí se genera el conflicto. De tal manera, que si lo hago desde SQL Server Management Studio manualmente logro lo esperado, siempre y cuando elimine primero Detalle_Factura y después Factura. Les mostraré el código en C#, diciéndoles de antemano que trabajo en 3 capas y también les mostraré las relaciones entre las tablas. Gracias de antemano.

    Éste es mi código que estoy utilizando. Les recuerdo que primero tengo que eliminar Detalle_Factura para después Factura, teniendo en cuenta su respectivo Id como referencia.

                DetalleFactura detborra = new DetalleFactura();
                NegDetalle_Factura borra = new NegDetalle_Factura();

                NegUtilidades br = new NegUtilidades();
                Utilidades cls = new Utilidades();

                Factura borraF = new Factura();
                NegFactura brr = new NegFactura();


                if (txtNumero.Text == "" || txtNombre.Text == "" || txtApellidos.Text == "" || txtMonto.Text == "")
                {
                    MessageBox.Show("Verifique que todos los datos estén llenos", "ADVERTENCIA", MessageBoxButtons.OK);
                    MessageBox.Show("Los datos no Borraron", "BORRAR!!!", MessageBoxButtons.OK);
                }
                else
                {
                    cls.Numero = Convert.ToInt32(txtNumero.Text);
                    br.BorrarUtilidad(cls);
                    ///////////////
                    detborra.Id_Factura = Convert.ToInt32(lbIdFacturaDF.Text);
                    detborra.Id_Producto = Convert.ToInt32(lbIdProductoDF.Text);
                    detborra.Cantidad = Convert.ToInt32(txtCantidad.Text);
                    detborra.Monto = Convert.ToDouble(txtMonto.Text);
                    detborra.Descuento = Convert.ToDouble(txtDescuento.Text);
     -->               borra.BorrarDetalleFactura(detborra);
                    //////////////
                    borraF.Id_Factura = Convert.ToInt32(lbIdFacturaF.Text);
                    borraF.Id_Usuario = Convert.ToInt32(lbIdUsuarioF.Text);
                    borraF.Id_Cliente = Convert.ToInt32(lbIdClienteF.Text);
     -->               brr.BorrarFactura(borraF);



                    MessageBox.Show("Dato Eliminado Exitosamente");
                    Limpiar();



                }


    rammyni

    miércoles, 16 de septiembre de 2020 18:31

Respuestas

  • Un par de observaciones:

    La primera es que no es fácil comprobar si en tu código todo es correcto porque llama a unas subrutinas para borrar, que no podemos ver. Si hubiera un error en ellas, eso explicaría por qué no funciona.

    Adicionalmente, es común que una factura tenga muchas líneas de detalle. Para hacer el borrado, necesitas borrar todas las líneas antes de borrar la factura. Aparentemente, tu código únicamente borra una sola línea de detalle, no todas ellas.

    Una solución para ahorrarte problemas es que en la base de datos marques la Foreign Key con la cláusula ON DELETE CASCADE. Esto hace que al borrar la factura se borren automáticamente todas las líneas de detalle conectadas mediante esa FK, con lo que se simplifica mucho el código ya que no te tienes que preocupar de borrar las líneas.

    jueves, 17 de septiembre de 2020 6:23
    Moderador
  • Efectivamente, haciendo el ON DELETE CASCADE la ventaja es que esto solo afecta a la base de datos; no hay que hacer nada en el código para borrar las líneas de detalle.

    La cláusula se pone en la creación de la tabla, al final d la parte en la que defines el Foreign Key:

    create table laTabla(...,  nombreDeCampo int not null references laOtraTabla(NombreDeCampo) ON DELETE CASCADE, ...)

    Se puede escribir el foreign key de muchas formas, lo de arriba es solo un ejemplo, no hace fata que cambies la que estés usando. Lo importante es añadir al final el "on delete cascade". En la documentación viene descrita la sintaxis en detalle.

    viernes, 18 de septiembre de 2020 20:49
    Moderador
  • "Una solución para ahorrarte problemas es que en la base de datos marques la Foreign Key con la cláusula ON DELETE CASCADE"

    Dónde hago esta cláusula??? Al hacerlo, dejaría el código tal y como está?, ya no me debería de dar el error???

    Gracias


    rammyni

    viernes, 18 de septiembre de 2020 19:41

Todas las respuestas

  • Un par de observaciones:

    La primera es que no es fácil comprobar si en tu código todo es correcto porque llama a unas subrutinas para borrar, que no podemos ver. Si hubiera un error en ellas, eso explicaría por qué no funciona.

    Adicionalmente, es común que una factura tenga muchas líneas de detalle. Para hacer el borrado, necesitas borrar todas las líneas antes de borrar la factura. Aparentemente, tu código únicamente borra una sola línea de detalle, no todas ellas.

    Una solución para ahorrarte problemas es que en la base de datos marques la Foreign Key con la cláusula ON DELETE CASCADE. Esto hace que al borrar la factura se borren automáticamente todas las líneas de detalle conectadas mediante esa FK, con lo que se simplifica mucho el código ya que no te tienes que preocupar de borrar las líneas.

    jueves, 17 de septiembre de 2020 6:23
    Moderador
  • Hola Ramiro Castañeda, 

      

    ¿Alguna novedad sobre la consulta realizada? ¿Han sido útiles las  respuestas proporcionadas?  

    Espero su respuesta.  

    Gracias por usar los foros de MSDN.  

    Andres Aguilar 

    ____________________________  

     

    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde.

    Si tiene algún cumplido o reclamo sobre el soporte de MSDN sientase en la libertad de contactar  MSDNFSF@microsoft.com. 

    jueves, 17 de septiembre de 2020 16:41
    Moderador
  • "Una solución para ahorrarte problemas es que en la base de datos marques la Foreign Key con la cláusula ON DELETE CASCADE"

    Dónde hago esta cláusula??? Al hacerlo, dejaría el código tal y como está?, ya no me debería de dar el error???

    Gracias


    rammyni

    viernes, 18 de septiembre de 2020 19:41
  • Efectivamente, haciendo el ON DELETE CASCADE la ventaja es que esto solo afecta a la base de datos; no hay que hacer nada en el código para borrar las líneas de detalle.

    La cláusula se pone en la creación de la tabla, al final d la parte en la que defines el Foreign Key:

    create table laTabla(...,  nombreDeCampo int not null references laOtraTabla(NombreDeCampo) ON DELETE CASCADE, ...)

    Se puede escribir el foreign key de muchas formas, lo de arriba es solo un ejemplo, no hace fata que cambies la que estés usando. Lo importante es añadir al final el "on delete cascade". En la documentación viene descrita la sintaxis en detalle.

    viernes, 18 de septiembre de 2020 20:49
    Moderador