Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Conexión con bases de datos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Conexión con bases de datos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 20-01-2010
HccSoft HccSoft is offline
Miembro
 
Registrado: may 2006
Posts: 14
Poder: 0
HccSoft Va por buen camino
Problema con Nº de pedidos SQL server ADO.

Estoy trabajando con una base de datos remota a la que acceden múltiples usuarios de varios países.

Para controlar la numeración utilizaba un campo integer que iba incrementando manualmente por años para luego crear un string más complejo del estilo 2010-PV000001.

Cuando el usuario desea crear un nuevo pedido el programa (no la base de datos) obtiene el último número integer, le suma uno y lo inserta en el nuevo registro dejando el resto en blanco.

Todo iba bien con la red interna hasta que este enero el número de usuarios empezó a incrementarse y se añadieron nuevos accesos internacionales con diferentes velocidades de ADLS. La semana pasada aleatoriamente se empezaron a repetir número de pedidos, no masivamente pero sí varios una o dos veces por semana. Visto esto estoy seguro que el problema irá en aumento y por eso os pido consejo.

¿Cómo lo solucionaríais?
¿Procedimiento almacenado?, bloqueo?

Gracias
Responder Con Cita
  #2  
Antiguo 20-01-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
¿Porqué no utilizas un campo Identity y le dejas ese trabajo al servidor?

A partir del Identity tú puedes componer el otro campo como te interese.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 20-01-2010
HccSoft HccSoft is offline
Miembro
 
Registrado: may 2006
Posts: 14
Poder: 0
HccSoft Va por buen camino
Cita:
Empezado por Neftali Ver Mensaje
¿Porqué no utilizas un campo Identity y le dejas ese trabajo al servidor?

A partir del Identity tú puedes componer el otro campo como te interese.
No lo utilizo porque cada año la numeración se ha de reiniciar a cero. Tendría que modificar cada 1 de enero el código y restar el incremento del campo identidad.
Responder Con Cita
  #4  
Antiguo 20-01-2010
Avatar de marcoszorrilla
marcoszorrilla marcoszorrilla is offline
Capo
 
Registrado: may 2003
Ubicación: Cantabria - España
Posts: 11.221
Poder: 10
marcoszorrilla Va por buen camino
Porque no le das un número de pedido provisional a cada usuario y solamente cuando graben el pedido le das el número real.

Aparte de esto si el número de Pedido fuera PK evitarías la repetición.

Un Saludo.
__________________
Guía de Estilo de los Foros
Cita:
- Ça c'est la caisse. Le mouton que tu veux est dedans.
Responder Con Cita
  #5  
Antiguo 20-01-2010
HccSoft HccSoft is offline
Miembro
 
Registrado: may 2006
Posts: 14
Poder: 0
HccSoft Va por buen camino
Cita:
Empezado por marcoszorrilla Ver Mensaje
Porque no le das un número de pedido provisional a cada usuario y solamente cuando graben el pedido le das el número real.

Aparte de esto si el número de Pedido fuera PK evitarías la repetición.

Un Saludo.
Tendría el mismo problema que ahora. El problema es que entre el SELECT que busca el número mayor de ese campo y el insert alguien ha ejecutado esa misma consulta teniendo ambos usuarios el mismo número. Para que pase ha de dar la casualidad que los dos usuarios creen un nuevo registro a la vez. No ocurre casi nunca pero es algo que no me puedo permitir que falle.

Entre el SELECT y el INSERT pueden pasar milisegundos pero ya es suficiente como para encontrar registros con el mismo número.

Si invierto el proceso tendría el mismo problema a la hora de guardar y crear el nuevo número. Si dos usuarios guardaran a la vez, ambos acabarían con el mismo número como ahora.
Responder Con Cita
  #6  
Antiguo 20-01-2010
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por HccSoft Ver Mensaje
Entre el SELECT y el INSERT pueden pasar milisegundos pero ya es suficiente como para encontrar registros con el mismo número.
En ese caso sólo se me ocurre que utilices transacciones y bloquees al resto de usuarios para esa operación.

A la hora de hacer el INSERT del registro, debes hacer el SELECT y el INSERT del contador, todo ello dentro de la misma transacción, de forma que se el INSERT del registro falla (por lo que sea) tampoco se actualice el contador.
Además, utilizando los diferentes tipos de ISOLATION (para la transacción) creo que puedes llegar a bloquear las lecturas del resto de usuarios para que no obtengan el mismo contador.

Si estás accediendo con ADO, en la conexión y en las consultas también puedes modificar esta característica.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #7  
Antiguo 20-01-2010
HccSoft HccSoft is offline
Miembro
 
Registrado: may 2006
Posts: 14
Poder: 0
HccSoft Va por buen camino
Cita:
Empezado por Neftali Ver Mensaje
En ese caso sólo se me ocurre que utilices transacciones y bloquees al resto de usuarios para esa operación.

A la hora de hacer el INSERT del registro, debes hacer el SELECT y el INSERT del contador, todo ello dentro de la misma transacción, de forma que se el INSERT del registro falla (por lo que sea) tampoco se actualice el contador.
Además, utilizando los diferentes tipos de ISOLATION (para la transacción) creo que puedes llegar a bloquear las lecturas del resto de usuarios para que no obtengan el mismo contador.

Si estás accediendo con ADO, en la conexión y en las consultas también puedes modificar esta característica.
Sí, es la solución que había pensado.

Por si a alguien le interesa la pongo aquí :

Código:
DECLARE @numero int

BEGIN TRAN
      SELECT @numero = max(N_PRESUPUESTO) FROM PEDIDOS WHERE fecha > '01/01/2010'

      INSERT INTO PEDIDOS (N_PRESUPUESTO) values (@numero+1)

COMMIT TRAN

select @@identity as pedido
Todo dentro de un ADOQUERY que retorna la identidad del nuevo registro.

Última edición por HccSoft fecha: 20-01-2010 a las 17:37:25.
Responder Con Cita
  #8  
Antiguo 20-01-2010
Avatar de Cañones
Cañones Cañones is offline
Miembro
 
Registrado: ene 2007
Ubicación: La Paz Entre Ríos
Posts: 354
Poder: 18
Cañones Va por buen camino
Cita:
Empezado por Neftali Ver Mensaje
En ese caso sólo se me ocurre que utilices transacciones y bloquees al resto de usuarios para esa operación.

A la hora de hacer el INSERT del registro, debes hacer el SELECT y el INSERT del contador, todo ello dentro de la misma transacción, de forma que se el INSERT del registro falla (por lo que sea) tampoco se actualice el contador.
Además, utilizando los diferentes tipos de ISOLATION (para la transacción) creo que puedes llegar a bloquear las lecturas del resto de usuarios para que no obtengan el mismo contador.

Si estás accediendo con ADO, en la conexión y en las consultas también puedes modificar esta característica.
No conosco SQL Server pero la teoría es la misma para todas las DD.BB y es la que te acaba de explicar Neftali. Por lo menos a mi me funciona.

Saludos.
Responder Con Cita
  #9  
Antiguo 21-01-2010
Avatar de marcoszorrilla
marcoszorrilla marcoszorrilla is offline
Capo
 
Registrado: may 2003
Ubicación: Cantabria - España
Posts: 11.221
Poder: 10
marcoszorrilla Va por buen camino
Cita:
Empezado por HccSoft Ver Mensaje
Tendría el mismo problema que ahora. El problema es que entre el SELECT que busca el número mayor de ese campo y el insert alguien ha ejecutado esa misma consulta teniendo ambos usuarios el mismo número. Para que pase ha de dar la casualidad que los dos usuarios creen un nuevo registro a la vez. No ocurre casi nunca pero es algo que no me puedo permitir que falle.

Entre el SELECT y el INSERT pueden pasar milisegundos pero ya es suficiente como para encontrar registros con el mismo número.

Si invierto el proceso tendría el mismo problema a la hora de guardar y crear el nuevo número. Si dos usuarios guardaran a la vez, ambos acabarían con el mismo número como ahora.
La forma de hacer lo que digo es con una tabla que guarda un contador y que se bloquea en el momento de grabar el número incrementado.

Un Saludo.
__________________
Guía de Estilo de los Foros
Cita:
- Ça c'est la caisse. Le mouton que tu veux est dedans.
Responder Con Cita
  #10  
Antiguo 21-01-2010
HccSoft HccSoft is offline
Miembro
 
Registrado: may 2006
Posts: 14
Poder: 0
HccSoft Va por buen camino
Cita:
Empezado por marcoszorrilla Ver Mensaje
La forma de hacer lo que digo es con una tabla que guarda un contador y que se bloquea en el momento de grabar el número incrementado.

Un Saludo.
Al final he agrupado todo en una misma transacción. El SELECT para buscar el número, un INSERT y finalmente otro SELECT con el índide identidad para poder acceder al nuevo registro.

De todas formas me interesaría saber como se puede bloquear el acceso a una tabla mientras realizas alguna operación. Nunca va mal tener varias soluciones para estos problemas.

Gracias a todos
Responder Con Cita
  #11  
Antiguo 21-01-2010
Avatar de marcoszorrilla
marcoszorrilla marcoszorrilla is offline
Capo
 
Registrado: may 2003
Ubicación: Cantabria - España
Posts: 11.221
Poder: 10
marcoszorrilla Va por buen camino
Obviamente el bloqueo de un registro varía de unos motores a otros por lo que la mejor solución es consultar la ayuda para el tipo de tablas-componentes-motor utilizado.

Un Saludo.
__________________
Guía de Estilo de los Foros
Cita:
- Ça c'est la caisse. Le mouton que tu veux est dedans.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Problemas al grabar Facturas o Pedidos? FelipeDiaz Conexión con bases de datos 4 14-01-2008 21:14:28
Pedidos con un mes de antiguedad ¿¿¿cómo??? !!!!!!!! david_uh SQL 5 06-08-2007 05:54:30
Ayuda con sistema de pedidos XBart OOP 2 20-07-2006 00:48:51
Ayuda con consulta de ultimos pedidos Faust SQL 2 10-07-2006 09:51:01
consulta sql (pedidos y cotizaciones) Caro SQL 2 13-06-2006 17:52:47


La franja horaria es GMT +2. Ahora son las 14:19:06.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi