Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » SQL Server »

Evitar solapamiento de periodos

Estas en el tema de Evitar solapamiento de periodos en el foro de SQL Server en Foros del Web. Hola, cómo puedo evitar el solapamiento de fechas(periodos) a la hora de realizar una operación; en concreto: tengo una tabla sql donde almaceno pagos a ...
  #1 (permalink)  
Antiguo 07/10/2015, 08:43
 
Fecha de Ingreso: octubre-2007
Mensajes: 273
Antigüedad: 16 años, 6 meses
Puntos: 5
Evitar solapamiento de periodos

Hola, cómo puedo evitar el solapamiento de fechas(periodos) a la hora de realizar una operación; en concreto:

tengo una tabla sql donde almaceno pagos a productores, la cuestión es que el usuario es quien debe seleccinar el periodo de pago, y deseo evitar que a un mismo productor se le liquide en periodos que se solapen las fechas.

Código SQL:
Ver original
  1. [B]tabla liquidacion[/B]:
  2. id_liquidacion
  3. productor_id
  4. periodo_ini
  5. periodo_fin
  6. toneladas_entregadas
  7. importe_total
  8. contribucion_fiscal
  9. importe_neto

dentro del procedimiento almacenado que realiza la operación de liquacion es donde deseo hacer la comprobación de superposición de fechas.

Gracias.
  #2 (permalink)  
Antiguo 07/10/2015, 08:56
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 17 años, 8 meses
Puntos: 774
Respuesta: Evitar solapamiento de periodos

a que te refieres con que se solapen fechas?podrias explicar mejor tu problema?
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #3 (permalink)  
Antiguo 07/10/2015, 10:29
 
Fecha de Ingreso: octubre-2007
Mensajes: 273
Antigüedad: 16 años, 6 meses
Puntos: 5
Respuesta: Evitar solapamiento de periodos

intentaré: El asunto es que no pueden existir liquidaciones para un mismo productor que el periodo que abarque una esté comprendido dentro del periodo de otra:

ejemplo:
liquidacion1 productorA 01/04/15 al 15/04/15
liquidacion2 porductorA 08/04/15 al 14/04/04/15

ó

liquidacion1 productoA 01/04/15 al 15/04/15
liquidacion2 productorA 16/03/15 al 05/04/15

ó

liquidacion1 productoA 01/04/15 al 15/04/15
liquidacion2 productorA 06/04/15 al 10/05/15

no se pueden dar los casos anteriores.


El periodo de liquidacion puede ser culquiera, siempre y cuando las fechas no estén comprendidas dentro de las fechas de una liquidacion ya realizada.
  #4 (permalink)  
Antiguo 07/10/2015, 10:31
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Evitar solapamiento de periodos

El primer consejo que yo te daría es que no hagas la validación en un SP donde realizas el alta. Crea una SF o SP que te permitan validar ese solapamiento ANTES de enviar a realizar el INSERT.
Mandar a la base a realizar operaciones que no se han validado previamente sólo trae como consecuencia tener que hacer la misma operación y petición muchas veces, hasta que al final una de ellas pasa.
Es un desperdicio de recursos de red, BBDD y tiempo de desarrollo.

Una de las primeras directivas que suelen dar las DTI de desarrollo es nunca enviar a hacer una alta o actualización sin validaciones previas. Cuando el dato se envia a dar de alta, no debe haber fallos. Generan procesos de baja performance.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 07/10/2015, 20:11
 
Fecha de Ingreso: octubre-2015
Ubicación: Sinaloa
Mensajes: 8
Antigüedad: 8 años, 6 meses
Puntos: 0
Respuesta: Evitar solapamiento de periodos

Crea una funcion que te devuelva un valor TRUE o FALSE (1 o 0) si es que encuentra un registro o mas para un rango de fechas y un productor especifico. Ese rango de fechas son las que seleccionan y la funcion deberá ser invocada antes de hacer el INSERT
Ejemplo:
Quiero capturar una liquidacion para Juan Cholo en las fechas 01/10/2015 - 07/10/2015 a la función le vas a enviar esos 3 parametros
1. Juan Cholo (lo ideal es enviar el codigo pero para el ejemplo asi lo dejaremos)
2. 01/10/2015
3. 07/10/2015
Dentro de la función harás esta consulta (o algo similar)

Select COUNT(*) From TablaLiquidaciones Where Productor = 'Juan Cholo' AND FechaLiquidacion BETWEEN '01/10/2015' AND '07/10/2015'

Si te regresa cero registros, quiere decir que el rango de fechas es permitido, de lo contrario no lo aceptes. Ya sabras que hacer.

Espero te sirva.. saludos!!
  #6 (permalink)  
Antiguo 08/10/2015, 07:31
 
Fecha de Ingreso: octubre-2007
Mensajes: 273
Antigüedad: 16 años, 6 meses
Puntos: 5
Respuesta: Evitar solapamiento de periodos

JCHCSK
Si con eso hay una situación, digamos que para tu ejemplo, Juan Cholo ya tiene creada una liquidacion en el periodo 01/10/2015 al 07/10/2015, y el usuario equivocadamente selecciona un periodo comprendido entre el 02/10/2015 y el 05/10/2015, ó el 03/10/2015 y el 15/10/2015; pues para ese caso tambien deberia evitarse el cálculo.

es decir mi consulta no debería limitarse solo a la existencia de periodos dentro del rango de fecha seleccionado por el usuario, es que he probado varias consultas y siempre hay algun caso no permitido que me permite liquidar.
  #7 (permalink)  
Antiguo 08/10/2015, 07:37
 
Fecha de Ingreso: octubre-2007
Mensajes: 273
Antigüedad: 16 años, 6 meses
Puntos: 5
Respuesta: Evitar solapamiento de periodos

Cita:
Iniciado por gnzsoloyo Ver Mensaje
El primer consejo que yo te daría es que no hagas la validación en un SP donde realizas el alta. Crea una SF o SP que te permitan validar ese solapamiento ANTES de enviar a realizar el INSERT.
Mandar a la base a realizar operaciones que no se han validado previamente sólo trae como consecuencia tener que hacer la misma operación y petición muchas veces, hasta que al final una de ellas pasa.
Es un desperdicio de recursos de red, BBDD y tiempo de desarrollo.

Una de las primeras directivas que suelen dar las DTI de desarrollo es nunca enviar a hacer una alta o actualización sin validaciones previas. Cuando el dato se envia a dar de alta, no debe haber fallos. Generan procesos de baja performance.
Entiendo lo que expones, pero en mi caso considero debo realizar la comprobacion de fecha dentro del procedimiento almacenado que realiza el calculo de liquidacion, ya sea haciendo la consulta directamente o llamando a una UDF que se encargue de esto. Es que este calculo en especifico se realiza como una unica transaccion en la que se realizan operaciones de insercion y actualizacion en varias tablas e incluso poco eficientes pero obligatoriamente uso de variables cursores.

Esa parte se le deje completamente al SGBD
  #8 (permalink)  
Antiguo 08/10/2015, 08:02
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Evitar solapamiento de periodos

Cita:
en mi caso considero debo realizar la comprobacion de fecha dentro del procedimiento almacenado que realiza el calculo de liquidacion
Los únicos casos que conozco donde se revalidan datos en un SP, son aquellos qque están relacionados a Facturación, Pagos e imputaciones de importes, por seguridad de procesos.
¿Qué te lleva a considerar que un solapamiento de fechas deba validarse en ese SP, si el proceso es interactivo con un usuario?
¿Tienes muy alta concurrencia?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 09/10/2015, 08:08
 
Fecha de Ingreso: octubre-2007
Mensajes: 273
Antigüedad: 16 años, 6 meses
Puntos: 5
Respuesta: Evitar solapamiento de periodos

gnzsoloyo entiendo perfectamente lo que expones, de hecho es una mala práctica de mi parte, pero sea en el mismo SP o fuera de este debo validar que el rango de fecha seleccionado por el usuario para realizarle la liquidacion monetaria a un productor no coincida con un periodo ya liquidado anteriormente o que las fechas seleccionadas queden dentro o una de las dos fechas quede dentro de un periodo ya liquidado. Disculpa si no me hago entender, esa es la ayuda que necesito. En cualquier caso habría que consultar la base de datos.
El problema es que las consultas de seleccion sobre la tabla liquidacion que hago siempre me dejan liquidar en fechas no validas para un productor.

Agradeceria me ayudaran.
  #10 (permalink)  
Antiguo 09/10/2015, 13:46
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Evitar solapamiento de periodos

Cita:
El problema es que las consultas de seleccion sobre la tabla liquidacion que hago siempre me dejan liquidar en fechas no validas para un productor.
Pues alli lo que tienes es un error en esa consulta de validación.
A mi entender eso es lo que deberías encarar, y no intentar meter toda la lógica en el mismo SP donde haces el alta.
¿te has puesto a verificar por qué te falla esa validación?
Es posible que incluso esa query esté bien, pero la lógica en la aplicación esté mal (lo he visto pasar), porque el flujo del árbol de decisiones tiene un error.

Postea la query que hace esa validación y veamos si es por alli. Te evitarías tener que meterte en un desarrollo más complicado sin necesidad.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #11 (permalink)  
Antiguo 09/10/2015, 14:26
 
Fecha de Ingreso: octubre-2007
Mensajes: 273
Antigüedad: 16 años, 6 meses
Puntos: 5
Respuesta: Evitar solapamiento de periodos

Esta es la query, evidentemente me falla la lógica.

Código SQL:
Ver original
  1. IF EXISTS(
  2.         SELECT dbo.liquidacion.id_liq
  3.         FROM dbo.liquidacion INNER JOIN [dbo].[documento] ON [dbo].[liquidacion].[id_liq] = [dbo].[documento].[id_documento]
  4.         WHERE ([dbo].[documento].[zafra_id] = @zafraId)
  5.         AND
  6.         (
  7.             (
  8.                    
  9.                 ([dbo].[liquidacion].[fecha_inicio] >= @periodoIni) AND ([dbo].[liquidacion].[fecha_fin] <= @periodoFin) AND ([dbo].[liquidacion].[productor] = @productorId)
  10.             )
  11.             OR
  12.             (
  13.                 ([dbo].[liquidacion].[fecha_inicio] = @periodoIni) AND ([dbo].[liquidacion].[fecha_fin] = @periodoFin) AND ([dbo].[liquidacion].[productor] = @productorId)
  14.             )
  15.             OR
  16.             (
  17.                 ([dbo].[liquidacion].[fecha_inicio] <= @periodoIni) AND ([dbo].[liquidacion].[fecha_fin] BETWEEN @periodoFin AND @periodoFin) AND ([dbo].[liquidacion].[productor] = @productorId)
  18.             )          
  19.         )
  20.     )  
  21.     BEGIN
  22.         RAISERROR('Ya existe una liquidación para el productor %s dentro del periodo seleccionado.', 16, 1, @nombreProductor )
  23.         GOTO quitarConRollBack 
  24.     END

Última edición por gnzsoloyo; 09/10/2015 a las 14:35
  #12 (permalink)  
Antiguo 12/10/2015, 12:57
 
Fecha de Ingreso: octubre-2007
Mensajes: 273
Antigüedad: 16 años, 6 meses
Puntos: 5
Respuesta: Evitar solapamiento de periodos

Weno, haciendo pruebas, creo que resolví, no es muy eficiente pero ahí va:

CREATE PROCEDURE [dbo].[liquidacion_ChequearPeriodoLiquidar]
@periodoIni datetime,
@periodoFin datetime,
@productorId int,
@zafraId int
-- WITH ENCRYPTION
AS

DECLARE @existeLiquidacion bit
SET @existeLiquidacion = 0

IF EXISTS(
SELECT id_liq FROM dbo.liquidacion l
INNER JOIN dbo.documento d ON l.id_liq = d.id_documento
WHERE
(d.zafra_id = @zafraId)
AND
(
(l.productor = @productorId) AND (l.fecha_inicio BETWEEN @periodoIni AND @periodoFin)
)
OR
(
(l.productor = @productorId) AND (l.fecha_fin BETWEEN @periodoIni AND @periodoFin)
)

)
BEGIN
SET @existeLiquidacion = 1
goto DEVOLVER_RESULTADO
END

IF EXISTS(
SELECT id_liq FROM dbo.liquidacion l
INNER JOIN dbo.documento d ON l.id_liq = d.id_documento
WHERE (d.zafra_id = @zafraId) AND (l.productor = @productorId)
AND (l.fecha_inicio > @periodoIni) AND (l.fecha_fin >= @periodoFin)
)
BEGIN
SET @existeLiquidacion = 1
goto DEVOLVER_RESULTADO
END

IF EXISTS(
SELECT id_liq FROM dbo.liquidacion l
INNER JOIN dbo.documento d ON l.id_liq = d.id_documento
WHERE (d.zafra_id = @zafraId) AND (l.productor = @productorId)
AND (l.fecha_inicio BETWEEN @periodoIni AND @periodoFin) AND (l.fecha_fin > @periodoFin)
)
BEGIN
SET @existeLiquidacion = 1
goto DEVOLVER_RESULTADO
END

IF EXISTS(
SELECT id_liq FROM dbo.liquidacion l
INNER JOIN dbo.documento d ON l.id_liq = d.id_documento
WHERE (d.zafra_id = @zafraId) AND (l.productor = @productorId)
AND ((@periodoIni >= l.fecha_inicio ) AND (@periodoFin <= l.fecha_fin))
)
BEGIN
SET @existeLiquidacion = 1
goto DEVOLVER_RESULTADO
END

DEVOLVER_RESULTADO:
SELECT @existeLiquidacion

GO

Etiquetas: sql, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:33.