none
Ayuda con lógica.

    Pregunta

  • Hola.

    Tengo dos años frustrado con esta facturación. Este es mi código en el botón Guardar de la factura, obviamente quite las instrucciones que no afectan para nada el desarrollo de la ejecución para simplificar. Si alguien se detiene a ayudar y según su lógica, no le ve problemas a este código, también le podría poner, también simplificados, los códigos de los módulos que se refieren en este.

    El detalle es, que a veces graba o no, la factura o los items de la misma. La variable Modifica1 obtiene su valor desde una lista de facturas donde se escoge la que se pretende modificar.

    Private Sub BotonGuardar_Click(sender As Object, e As EventArgs) Handles BotonGuardar.Click
           
            PreparaGuarda()
            If ComboDocumento.Text = "Cotización" Then
               Mensaje para que no se utilice este botón cuando este seleccionada esta opción.
            Else
    
                If Modifica1 = "Modificando" Then
    
                Else
                    TexNumero.EditValue = SiguienteIdFactura()
    
                End If
    
                Using connection As New SqlConnection(Conex)
                    Dim comando1 As New SqlCommand("Select Pedidos.* from Pedidos where factura = '" + Trim(TexNumero.EditValue) + "'", connection)
                    
                    Dim adapter1 As New SqlDataAdapter(comando1)
                    Dim table1 As New DataTable
                    adapter1.Fill(table1)
    
                    If table1.Rows.Count() > 0 Then
                        Dim msg = "Está modificando esta Factura, esta seguro?"
                        Dim title = "Advertencia!!"
                        Dim style = MsgBoxStyle.YesNo
                        Dim response = MsgBox(msg, style, title)
                       
                        If response = MsgBoxResult.Yes Then
                            If (TextEfectivo.EditValue = 0 And ComboCondicion.Text = "Al Contado") Or (ComboCliente.SelectedValue = 0 And ComboCondicion.Text = "A Crédito") Then
                                Dim msg1 = "Factura Al Contado NO pagada o Factura A Crédito sin seleccionar Cliente."
                                Dim title1 = "Advertencia!!"
                                Dim style1 = MsgBoxStyle.Information
                                Dim response1 = MsgBox(msg1, style1, title1)
                            Else
                                GuardarModifica()
                            End If
                            
                        End If
    
                    Else
                        
                        If (TextEfectivo.EditValue = 0 And ComboCondicion.Text = "Al Contado") Or (ComboCliente.SelectedValue = 0 And ComboCondicion.Text = "A Crédito") Then
                            Dim msg1 = "Factura Al Contado NO pagada o Factura A Crédito sin seleccionar Cliente."
                            Dim title1 = "Advertencia!!"
                            Dim style1 = MsgBoxStyle.Information
                            Dim response1 = MsgBox(msg1, style1, title1)
                        Else
                            StockOut()
                            GuardarNueva()
                            
                        End If
                       
                    End If
                   
                End Using
            End If
        
        End Sub
    

    martes, 10 de julio de 2018 23:52

Respuestas

  • Hola Formulaz5:

    Vaya por delante que me tomo su queja como algo que apunta a mi nombre, pues creo que he sido el que le ha pedido algo.

    Desde mi punto de vista, creo que no ve el apoyo que le brindan en los foros como es, pues al menos que yo sepa, es un apoyo voluntario, que realizan muchas personas por la comunidad de desarrolladores sin obtener ningún beneficio a cambio. Invierten su tiempo y esfuerzo por ayudar a los demás.

    Voy a ir por partes, añadiéndole, lo que yo veo de su código, y lo que le ha explicado ablanco muy correctamente de su código, y que no ha llegado a ver.

    Cuando le indica la concurrencia, si su software, que no lo sabemos, se puede ejecutar desde dos o más equipos a la vez, estos pueden solicitar grabar una factura al mismo tiempo, y en base de datos, esto lo que hace es solicitar el max y le añade 1. La primera solicitud le devuelve el 15, al cual le añade uno. (en este momento la segunda solicitud entra, y el max le devuelve 15 porque todavía no se ha consolidado el 16.....cuando grabe la primera será 16, pero la segunda generará una excepción.

    Análisis de posibles causas que le den errores. Siempre desde mi opinión.

    Método GuardarNueva()

    Si como dice dispone de try catch puede utilizar un logueador a disco de las excepciones, y así, puede saber, lo que ocurre. El del enlace es simple de implementar y ayuda mucho.

    Carga en sus variables valores que provienen de campos donde puede haber datos que no encajen en las conversiones, y por tanto generen una excepción no tratada. Ejemplo si cualquiera de las cajas de texto, tiene un valor que no es convertible a doublé, como un literal, ya no guarda.

    No se como carga comboCliente pero depende de su ValueMember, puede ser nulo.

    https://blogs.msdn.microsoft.com/jaredpar/2006/11/07/combobox-selecteditem-selectedvalue-selectedwhat/

    GrabaItemDirecto()

    Además de la captura de excepciones, que debiera de tener en todos los métodos que se conecten a un recurso externo.

    ¿Porqué Elimina? antes de empezar con las líneas. No debería de borrar líneas, ya que si existen, existen por algo que no tuvo en cuenta, por tanto es falsear información.

    No entiendo tampoco recorrer todas las filas de table1 para quedarse solo con 1 valor, para guardar el precio de coste.

    Agregar.Parameters.AddWithValue("@factura", Trim(TexNumero.EditValue))

    ¿Y si TextNumero no tiene un número?. Esta exponiendo la cadena quitándole espacios, pero a lo mejor no siempre detrás hay el valor que esperamos. No se suelen exponer datos que obtienes de la vista a la base de datos, sin tener consolidado su tipo. (Recuerde que yo no veo su aplicación ni como se construye, nada más que le intento indicar posibles, puntos de anomalía que pueden indicar el porqué le falla algunas veces).

     If table.Rows.Count() > 0 Then

    Esto si no borra sobra, pero si decide borrar porque si, el if tendría, el método de eliminar, y ya. luego el código sería el mismo, y evita duplicidades.

    En cuanto al max id.

    Te voy a poner código sql, si tienes un Managment studio

    create

    tablepruebaSimultaneidad(id int,valor varchar(10))

    go

    create

    proceduremax_Sim(@id intoutput)

    as

    select

    @id=ISNULL(max(id),0)frompruebaSimultaneidad

    return

    go

    ahora en dos ventanas paralelas.

    declare @contador int = 0;
    declare @max int=0;
    
    while @contador < 10000
    begin
    	exec max_Sim @max output
    	insert into pruebaSimultaneidad ( id,valor) values (@max+1,'a')
    	set @contador = @contador+1
    	
    end
    
    

    Ejecutas las dos al mismo tiempo mas o menos, y luego le haces una select a pruebasimultaneidad, y verás como hay algún id duplicado. Si todo fuera genial el max(id) de pruebasimultaneidad sería cercano a 20.000, pero verás como por ejemplo en mi caso, es 16771. Han ocurrido más de 3000 veces, donde el max ha devuelto el mismo resultado. Esto es una hipótesis, pero ocurre.

    Un saludo

    jueves, 12 de julio de 2018 5:25

Todas las respuestas

  • Hola Formulaz5:

    Creo que deberías de poner el código de GuardarModifica y GuardarNueva, y de SiguienteIdFactura ya que si tus errores, son, que a veces si y a veces no.....Pueden estar ahí. (a lo mejor no siempre consigue un id correcto y tu código se rompe porque le estas asignando un id que ya existe).

    Además, imagina que tu Select pedidos.... no se puede ejecutar, por cualquier razón, en este código no se ve que tengas ningún tipo de captura de excepciones. Si no lo tienes, sería interesante, por no decir imprescindible.

    En cuanto a la arquitectura del código, yo extraería todo el acceso a datos a otra capa, es más fácil de cambiar, si separas todo lo que se relaciona con la base de datos, en una/s clases que hablen con la base de datos, y no en la lógica de la vista. Mira este ejemplo, donde se explica una arquitectura en 3 capas, y te ayudará mucho.

    http://joseluisgarciab.blogspot.com/2014/09/programacion-en-3-capas.html

    Existen multitud de ejemplos en la web, sobre como programar en capas, este es uno fácil de seguir.

    Un saludo

    miércoles, 11 de julio de 2018 5:43
  • Como te comenta javi Fernandez, es complicado darte un diagnostico a simple visualización. Solo veo algo que no se si has tenido en cuenta.... si en el campo numero de factura se puede escribir cualquier cosa si alguien te escribe un ' tu aplicación fallará, más aún si escriten '; drop table pedidos -- te borraran la tabla pedidos. Ten cuidado con esas cosas 

    Comparte lo que sepas, aprende lo que no sepas (FGG)
    portalSQL
    El rincón del DBA

    miércoles, 11 de julio de 2018 6:25
    Moderador
  • Gracias por interesarte Javi Fernandez.

    Me parece bien lo de las capas, es mas organizado. Debo estudiar eso.

    Ahí te van  los códigos.

    GuardaNueva

     Private Sub GuardarNueva()
    
            Dim des As Double = Convert.ToDouble(TexDesc.Text)
            Dim impu As Double = Convert.ToDouble(TextImpu.Text)
            Dim net As Double = Convert.ToDouble(TexNeto.Text)
            Dim efe As Double = Convert.ToDouble(TextEfectivo.Text)
            Dim devu As Double = Convert.ToDouble(TextDevuel.Text)
            Dim pend As Double = Convert.ToDouble(TextPendiente.Text)
            Dim subt As Double = Convert.ToDouble(TexSubT.Text)
            Dim fech As String = (Convert.ToString(Today.ToShortDateString) + " " + Convert.ToString(Now.ToShortTimeString))
    
            Using connection As New SqlConnection(Conex)
                Dim comando3 As New SqlCommand("insert into Pedidos (codcli, factura, fecha, condicion, descuentos, impuestos, monto, pagado, cambio, pendiente, contado, tipopago, refpago, subtotal, observacion, tipodocumento, estado, usuario) values ('" & Convert.ToInt32(ComboCliente.SelectedValue) & "','" & Convert.ToInt32(TexNumero.EditValue) & "','" & fech & "','" & ComboCondicion.Text & "' , '" & des & "','" & impu & "','" & net & "','" & efe & "','" & devu & "', '" & pend & "','" & ComboCliente.Text & "','" & ComboTipoPa.Text & "','" & Trim(TextRefPago.Text) & "','" & subt & "','" & Trim(MemoEditObser.Text) & "','" & ComboDocumento.Text & "', '" & "Abierta" & "','" & Entorno.Usuari & "')", connection)
                connection.Open()
                comando3.ExecuteNonQuery()
                GrabaItemDirecto()
            End Using
    
        End Sub

    GrabaItemDirecto

     Private Sub GrabaItemDirecto()
              Using connection As New SqlConnection(Conex)
                Dim comando As New SqlCommand("select DetallePed.* from DetallePed where factura = '" & Trim(TexNumero.EditValue) & "'", connection)
                Dim Agregar As SqlCommand = New SqlCommand("insert into DetallePed values (@codigo, @factura, @cantidad, @precio, @monto, @itbis, @costo)", connection)
                Dim Elimina As SqlCommand = New SqlCommand("delete from DetallePed where factura='" & Trim(TexNumero.EditValue) & "'", connection)
                connection.Open()
                Dim adapter As New SqlDataAdapter(comando)
                Dim table As New DataTable
                adapter.Fill(table)
    
                If table.Rows.Count() > 0 Then
                    Elimina.ExecuteNonQuery()
    
                    For Each row As DataGridViewRow In DataGriDetalles.Rows
                        Agregar.Parameters.Clear()
    
                        Dim comando1 As New SqlCommand("select productos.* from productos where codigo = @codigo", connection)
                        comando1.Parameters.AddWithValue("@codigo", Convert.ToString(row.Cells(0).Value))
                        Dim adapter1 As New SqlDataAdapter(comando1)
                        Dim table1 As New DataTable
                        adapter1.Fill(table1)
    
                        For Each row1 As DataRow In table1.Rows
                            ItemFactura.cos = Convert.ToInt32(row1("costo"))
                        Next
                    
                        Agregar.Parameters.AddWithValue("@codigo", Convert.ToString(row.Cells("codigo").Value))
                        Agregar.Parameters.AddWithValue("@factura", Trim(TexNumero.EditValue))
                        Agregar.Parameters.AddWithValue("@cantidad", Convert.ToString(row.Cells("cantidad").Value))
                        Agregar.Parameters.AddWithValue("@precio", Convert.ToString(row.Cells("precio").Value))
                        Agregar.Parameters.AddWithValue("@itbis", Convert.ToInt32(row.Cells("itbis").Value))
                        Agregar.Parameters.AddWithValue("@monto", Convert.ToString(row.Cells("total").Value))
                        Agregar.Parameters.AddWithValue("@costo", ItemFactura.cos)
    
                        Agregar.ExecuteNonQuery()
    
                    Next
                Else
                    For Each row As DataGridViewRow In DataGriDetalles.Rows
                        Agregar.Parameters.Clear()
    
                        Dim comando1 As New SqlCommand("select productos.* from productos where codigo = @codigo", connection)
                        comando1.Parameters.AddWithValue("@codigo", Convert.ToString(row.Cells(0).Value))
                        Dim adapter1 As New SqlDataAdapter(comando1)
                        Dim table1 As New DataTable
                        adapter1.Fill(table1)
    
                        For Each row1 As DataRow In table1.Rows
                            ItemFactura.cos = Convert.ToInt32(row1("costo"))
                        Next
    Agregar.Parameters.AddWithValue("@codigo", Convert.ToString(row.Cells("codigo").Value))
                        Agregar.Parameters.AddWithValue("@factura", Trim(TexNumero.EditValue))
                        Agregar.Parameters.AddWithValue("@cantidad", Convert.ToString(row.Cells("cantidad").Value))
                        Agregar.Parameters.AddWithValue("@precio", Convert.ToString(row.Cells("precio").Value))
                        Agregar.Parameters.AddWithValue("@itbis", Convert.ToInt32(row.Cells("itbis").Value))
                        Agregar.Parameters.AddWithValue("@monto", Convert.ToString(row.Cells("total").Value))
                        Agregar.Parameters.AddWithValue("@costo", ItemFactura.cos)
    
                        Agregar.ExecuteNonQuery()
    
                    Next
                End If
            End Using
    
              End Sub
    GuardarModifica
     Private Sub GuardarModifica()
    
            DataGriDetalles.AllowUserToAddRows = False
    
                   Dim des As Double = Convert.ToDouble(TexDesc.Text)
            Dim impu As Double = Convert.ToDouble(TextImpu.Text)
            Dim net As Double = Convert.ToDouble(TexNeto.Text)
            Dim efe As Double = Convert.ToDouble(TextEfectivo.Text)
            Dim devu As Double = Convert.ToDouble(TextDevuel.Text)
            Dim pend As Double = Convert.ToDouble(TextPendiente.Text)
            Dim subt As Double = Convert.ToDouble(TexSubT.Text)
            Dim fech As String = (Convert.ToString(Today.ToShortDateString) + " " + Convert.ToString(Now.ToShortTimeString))
    
            Using connection As New SqlConnection(Conex)
               
                Dim comando2 As New SqlCommand("update Pedidos set factura='" & Trim(TexNumero.EditValue) & "', fecha='" & fech & "', codcli='" & Convert.ToInt32(ComboCliente.SelectedValue) & "', condicion='" & ComboCondicion.Text & "', monto='" & net & "', descuentos='" & des & "', impuestos='" & impu & "', pendiente='" & pend & "', contado='" & ComboCliente.Text & "', pagado='" & efe & "', subtotal='" & subt & "', cambio='" & devu & "', tipopago='" & ComboTipoPa.Text & "', refpago='" & Trim(TextRefPago.Text) & "', observacion='" & Trim(MemoEditObser.Text) & "', tipodocumento='" & ComboDocumento.Text & "', usuario='" & Entorno.Usuari & "' where factura='" & Trim(TexNumero.EditValue) & "'", connection)
                connection.Open()
                comando2.ExecuteNonQuery()
                GrabaItemDirecto()
            End Using
        End Sub

    Y por ultimo este es el modulo donde rebajo la cantidad de la tabla productos. Lo pongo porque es uno de los que falla igual.

    StockOut

     Private Sub StockOut()
    
            DataGriDetalles.AllowUserToAddRows = False
    
            For Each row As DataGridViewRow In DataGriDetalles.Rows
                Using connection As New SqlConnection(Conex)
                    
                    Dim str As String
                    str = Convert.ToString(row.Cells(0).Value)
                    Dim comando1 As New SqlCommand("select productos.* from productos where codigo = @codigo", connection)
                    comando1.Parameters.AddWithValue("@codigo", Convert.ToString(row.Cells(0).Value))
                    Dim comando2 As New SqlCommand("update productos set existencia = existencia-@cantidad where codigo = @codigo", connection)
    
                    Dim adapter1 As New SqlDataAdapter(comando1)
                    Dim table1 As New DataTable
    
                    Dim adapter2 As New SqlDataAdapter(comando2)
                    Dim table2 As New DataTable
    
                    adapter1.Fill(table1)
    
                    
                    Dim comando3 As New SqlCommand("insert into kardex (codigo, fecha, tipo, numdoc, salida, costo, precio) values (@codigo, @fecha, @tipo, @numdoc, @salida, @costo, @precio)", connection)
                    Dim adapter3 As New SqlDataAdapter(comando3)
                    Dim table3 As New DataTable
    
                    comando1.Parameters.Clear()
                    comando2.Parameters.Clear()
                    comando3.Parameters.Clear()
    
                    comando1.Parameters.AddWithValue("@codigo", Replace(Convert.ToString(row.Cells("codigo").Value), "'", "''"))
    
                    comando2.Parameters.AddWithValue("@cantidad", Convert.ToString(row.Cells("cantidad").Value))
                    comando2.Parameters.AddWithValue("@codigo", Replace(Convert.ToString(row.Cells("codigo").Value), "'", "''"))
    
                    comando3.Parameters.AddWithValue("@codigo", Replace(Convert.ToString(row.Cells("codigo").Value), "'", "''"))
                    comando3.Parameters.AddWithValue("@fecha", Trim(TexFecha.EditValue))
                    comando3.Parameters.AddWithValue("@tipo", "Factura")
                    comando3.Parameters.AddWithValue("@numdoc", Trim(TexNumero.EditValue))
                    comando3.Parameters.AddWithValue("@salida", Convert.ToString(row.Cells("cantidad").Value))
                    comando3.Parameters.AddWithValue("@costo", table1.Rows(0)(3).ToString)
                    comando3.Parameters.AddWithValue("@precio", Convert.ToString(row.Cells("total").Value))
    
                    connection.Open()
                    comando1.ExecuteNonQuery()
                    comando2.ExecuteNonQuery()
                    comando3.ExecuteNonQuery()
                End Using
            Next
    
        End Sub

    Nota: Sí uso Try, no lo puse para simplificar el código y no extender. He utilizado trazas en el codigo y en el servidor y no aparece nada raro.

    miércoles, 11 de julio de 2018 14:16
  • Buenos días, que hace esta función SiguienteIdFactura()? Te pregunto porque puede ser que lleguen dos facturas con el mismo Id a la BD y ahí es donde se está reventando.

    miércoles, 11 de julio de 2018 14:28
  • Ok. Olvide ponerla.

      Private Function SiguienteIdFactura() As Integer
            Return MaxId() + 1
        End Function
    
     Private Function MaxId() As Integer
    
            Using connection As New SqlConnection(Conex)
                connection.Open()
                Dim command As New SqlCommand("SELECT ISNULL(Max(Factura),100) FROM PEDIDOS", connection)
                Return Convert.ToInt32(command.ExecuteScalar())
    
            End Using
        End Function
    Ahí esta la composición completa de la función.

    miércoles, 11 de julio de 2018 14:31
  • Efectivamente es eso, puede ser que se estén realizando dos facturas a la vez y ambas lleguen con el mismo Id, en ese caso guarda una y la otra no se guarde, lo recomendable para esto es manejar otra tabla donde reserves los Id de las facturas, algo así como ConsecutivoFactura, en esa tabla guarda el último Id de la factura, y cada vez que llames a esa función, recuperalo de esa tabla.

    Saludos.

    miércoles, 11 de julio de 2018 15:15
  • Ok. Pero no me muestras en donde ese código puede fallar de esa manera, por tanto, lo que me recomiendas es ponerle mas elementos al asunto, por tanto mas complejo.
    miércoles, 11 de julio de 2018 15:22
  • Ok, mira, cuando haces esto

     Using connection As New SqlConnection(Conex)
                connection.Open()
                Dim command As New SqlCommand("SELECT ISNULL(Max(Factura),100) FROM PEDIDOS", connection)
                Return Convert.ToInt32(command.ExecuteScalar())

    Se puede dar el caso que se realizen dos facturas al mismo tiempo, si en tu tabla pedido el ultimo Id es 500, por ejemplo, ambas quedarían con 501, porque no has guardado nada en BD aún, Ahí está el problema, si manejaras otra tabla como te propuse, en esa el última sería el 500, cuando llegue la primera lo actualizas y queda en 501, la segunda tomaría 502, y al guardar en pedidos ambas si llegarían con Id's diferentes, me hice entender?

    miércoles, 11 de julio de 2018 15:37
  • Ahora sí, tronco. 

    Aunque hice el código precavido en ese sentido al momento de guardar la factura. Siempre busca el ultimo antes de.

    Por tanto, no se si soy tan bruto que, no lo veo. 

    Pero, si consulto esa tabla que propones antes de, pues seria lo mismo que ir directamenta a la tabla de facturas y chquear el ultimo numero.

    • Editado Formulaz5 miércoles, 11 de julio de 2018 15:42
    miércoles, 11 de julio de 2018 15:40
  • Eso es lo que no me agrada de estos foros.

    Te piden cosas y al final te dejan en el aire.

    Gracias por todo y a todos.

    jueves, 12 de julio de 2018 1:49
  • Hola Formulaz5:

    Vaya por delante que me tomo su queja como algo que apunta a mi nombre, pues creo que he sido el que le ha pedido algo.

    Desde mi punto de vista, creo que no ve el apoyo que le brindan en los foros como es, pues al menos que yo sepa, es un apoyo voluntario, que realizan muchas personas por la comunidad de desarrolladores sin obtener ningún beneficio a cambio. Invierten su tiempo y esfuerzo por ayudar a los demás.

    Voy a ir por partes, añadiéndole, lo que yo veo de su código, y lo que le ha explicado ablanco muy correctamente de su código, y que no ha llegado a ver.

    Cuando le indica la concurrencia, si su software, que no lo sabemos, se puede ejecutar desde dos o más equipos a la vez, estos pueden solicitar grabar una factura al mismo tiempo, y en base de datos, esto lo que hace es solicitar el max y le añade 1. La primera solicitud le devuelve el 15, al cual le añade uno. (en este momento la segunda solicitud entra, y el max le devuelve 15 porque todavía no se ha consolidado el 16.....cuando grabe la primera será 16, pero la segunda generará una excepción.

    Análisis de posibles causas que le den errores. Siempre desde mi opinión.

    Método GuardarNueva()

    Si como dice dispone de try catch puede utilizar un logueador a disco de las excepciones, y así, puede saber, lo que ocurre. El del enlace es simple de implementar y ayuda mucho.

    Carga en sus variables valores que provienen de campos donde puede haber datos que no encajen en las conversiones, y por tanto generen una excepción no tratada. Ejemplo si cualquiera de las cajas de texto, tiene un valor que no es convertible a doublé, como un literal, ya no guarda.

    No se como carga comboCliente pero depende de su ValueMember, puede ser nulo.

    https://blogs.msdn.microsoft.com/jaredpar/2006/11/07/combobox-selecteditem-selectedvalue-selectedwhat/

    GrabaItemDirecto()

    Además de la captura de excepciones, que debiera de tener en todos los métodos que se conecten a un recurso externo.

    ¿Porqué Elimina? antes de empezar con las líneas. No debería de borrar líneas, ya que si existen, existen por algo que no tuvo en cuenta, por tanto es falsear información.

    No entiendo tampoco recorrer todas las filas de table1 para quedarse solo con 1 valor, para guardar el precio de coste.

    Agregar.Parameters.AddWithValue("@factura", Trim(TexNumero.EditValue))

    ¿Y si TextNumero no tiene un número?. Esta exponiendo la cadena quitándole espacios, pero a lo mejor no siempre detrás hay el valor que esperamos. No se suelen exponer datos que obtienes de la vista a la base de datos, sin tener consolidado su tipo. (Recuerde que yo no veo su aplicación ni como se construye, nada más que le intento indicar posibles, puntos de anomalía que pueden indicar el porqué le falla algunas veces).

     If table.Rows.Count() > 0 Then

    Esto si no borra sobra, pero si decide borrar porque si, el if tendría, el método de eliminar, y ya. luego el código sería el mismo, y evita duplicidades.

    En cuanto al max id.

    Te voy a poner código sql, si tienes un Managment studio

    create

    tablepruebaSimultaneidad(id int,valor varchar(10))

    go

    create

    proceduremax_Sim(@id intoutput)

    as

    select

    @id=ISNULL(max(id),0)frompruebaSimultaneidad

    return

    go

    ahora en dos ventanas paralelas.

    declare @contador int = 0;
    declare @max int=0;
    
    while @contador < 10000
    begin
    	exec max_Sim @max output
    	insert into pruebaSimultaneidad ( id,valor) values (@max+1,'a')
    	set @contador = @contador+1
    	
    end
    
    

    Ejecutas las dos al mismo tiempo mas o menos, y luego le haces una select a pruebasimultaneidad, y verás como hay algún id duplicado. Si todo fuera genial el max(id) de pruebasimultaneidad sería cercano a 20.000, pero verás como por ejemplo en mi caso, es 16771. Han ocurrido más de 3000 veces, donde el max ha devuelto el mismo resultado. Esto es una hipótesis, pero ocurre.

    Un saludo

    jueves, 12 de julio de 2018 5:25
  • Gracias Javi.

    Sí lo veo como es, pues sólo fui categórico en su caso, pues me pidió "voluntariamente" mas detalles, los cuales envié.

    Gracias por recordar que no estoy pagando un centavo por la ayuda que se recibe por aquí.

    Si yo fuera bastante entendido del tema, pues fuera uno de los que ayudara muy atentamente, pues si soy voluntario, me responsabilizo de eso. Es como ir voluntario a ayudar en un desastre sísmico, pues no me cruzaría de brazos una vez allá. Si no quiero ayudar, no voy.

    Pero bien, sólo aclaro que sé cuan valiosa es la ayuda ofrecida por aquí. Pero reconozco que muchas veces te dejan en el aire, mas cuando te piden aclaraciones.

    En definitiva, me has dado pistas qué seguir y eso te lo agradezco en el corazón. Pues deseaba eso, no que me mimaran y me resolvieran todo, asi no aprendo. Aprendo de la forma que me has dicho las cosas.

    Y por eso lo veo bien que me lo hayas dicho de esta forma. Resta ahora reescribir la lógica de código que poseo y ver resultados.

    Muchísimas gracias.

    jueves, 12 de julio de 2018 17:35
  • De nada

    Suerte con el enigma

    jueves, 12 de julio de 2018 19:04
  • En sucesivas ocasiones, yo evitaría el tipo de críticas que vertiste.

    Tu no sabes, te haya pedido mas información o no, que puede haber pasado en la vida del que te contesta, y creo que es de mal gusto prejuzgar que te preguntan con la intención de dejarte tirado, más aún cuando aquí todos los que contestan lo hacen de forma voluntaria y bastante profesional muchas veces. 

    La respuesta que te dió Javi fernandez le honra, yo personalmente no te habría contestado por tu salida de tono, al fin y al cabo eres tu quien tiene el problema y los demás quien quieren ayudarte, que menos que un poquito de comprensión y de paciencia. 


    Comparte lo que sepas, aprende lo que no sepas (FGG)
    portalSQL
    El rincón del DBA

    viernes, 13 de julio de 2018 6:27
    Moderador