Configure una planilla quincenal en Evolution 1.19.1.2
La planilla esta en C#
Cuando genero la planilla, me da el siguiente error:
2020-02-06 12:21:54,507 [28] FATAL 8425d8f7-504a-466b-a261-c3e34363d80b - Error al ejecutar las fórmulas del tipo de planilla Planilla Quincenal Administrativa periodo 38
System.AggregateException: One or more errors occurred. ---> System.Data.ConstraintException: Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
at System.Data.DataSet.EnableConstraints()
at System.Data.DataSet.set_EnforceConstraints(Boolean value)
at System.Data.DataTable.EndLoadData()
at System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue)
at System.Data.Common.DataAdapter.Fill(DataSet dataSet, String srcTable, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)
at Aseinfo.VH4.MicroServices.GenPla.Ejecutores.NetLangCursor.OpenCursor(String databaseProvider, String connectionString, Int32 defaultCommandTimeOut) in C:\vh4\VH4\MicroServices\GenPla\NetLang\NetLangCursor.cs:line 58
at Aseinfo.VH4.MicroServices.GenPla.Ejecutores.EjecutorFormulacionNetLang.InitializeCursor(Cursor cursor, NetLangExecutorGeneratedBase execInstance, CancellationToken token) in C:\vh4\VH4\MicroServices\GenPla\NetLang\EjecutorFormulacionNetLang.cs:line 262
at Aseinfo.VH4.MicroServices.GenPla.Ejecutores.EjecutorFormulacionNetLang.<>c__DisplayClass7_0.<EjecutarFormulas>b__5(Cursor cursor) in C:\vh4\VH4\MicroServices\GenPla\NetLang\EjecutorFormulacionNetLang.cs:line 130
at System.Threading.Tasks.Parallel.<>c__DisplayClass31_0`2.<ForEachWorker>b__0(Int32 i)
at System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.<ForWorker>b__1()
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IList`1 list, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.ForEachWorker[TSource,TLocal](IEnumerable`1 source, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Action`3 bodyWithStateAndIndex, Func`4 bodyWithStateAndLocal, Func`5 bodyWithEverything, Func`1 localInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.ForEach[TSource](IEnumerable`1 source, Action`1 body)
at Aseinfo.VH4.MicroServices.GenPla.Ejecutores.EjecutorFormulacionNetLang.EjecutarFormulas() in C:\vh4\VH4\MicroServices\GenPla\NetLang\EjecutorFormulacionNetLang.cs:line 128
at Aseinfo.VH4.MicroServices.GenPla.Common.Ejecutores.EjecutorFormulacionBase.EjecutarGeneracion() in C:\vh4\VH4\MicroServices\GenPla\Common\Ejecutores\EjecutorFormulacionBase.cs:line 748
---> (Inner Exception #0) System.Data.ConstraintException: Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
at System.Data.DataSet.EnableConstraints()
at System.Data.DataSet.set_EnforceConstraints(Boolean value)
at System.Data.DataTable.EndLoadData()
at System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable, String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue)
at System.Data.Common.DataAdapter.Fill(DataSet dataSet, String srcTable, IDataReader dataReader, Int32 startRecord, Int32 maxRecords)
at System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior)
at System.Data.Common.DbDataAdapter.Fill(DataSet dataSet)
at Aseinfo.VH4.MicroServices.GenPla.Ejecutores.NetLangCursor.OpenCursor(String databaseProvider, String connectionString, Int32 defaultCommandTimeOut) in C:\vh4\VH4\MicroServices\GenPla\NetLang\NetLangCursor.cs:line 58
at Aseinfo.VH4.MicroServices.GenPla.Ejecutores.EjecutorFormulacionNetLang.InitializeCursor(Cursor cursor, NetLangExecutorGeneratedBase execInstance, CancellationToken token) in C:\vh4\VH4\MicroServices\GenPla\NetLang\EjecutorFormulacionNetLang.cs:line 262
at Aseinfo.VH4.MicroServices.GenPla.Ejecutores.EjecutorFormulacionNetLang.<>c__DisplayClass7_0.<EjecutarFormulas>b__5(Cursor cursor) in C:\vh4\VH4\MicroServices\GenPla\NetLang\EjecutorFormulacionNetLang.cs:line 130
at System.Threading.Tasks.Parallel.<>c__DisplayClass31_0`2.<ForEachWorker>b__0(Int32 i)
at System.Threading.Tasks.Parallel.<>c__DisplayClass17_0`1.<ForWorker>b__1()
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)<---
Revisando todos los factores y cursores, detecté que el cursor que me daba problema era uno de vacaciones con el siguiente SQL:
SELECT ppl_codigo,
vac_codemp,
CASE
WHEN dva_desde < ppl_fecha_ini AND dva_hasta > ppl_fecha_fin
THEN gen.fn_diff_two_dates_30(ppl_fecha_ini, ppl_fecha_fin)
WHEN dva_desde < ppl_fecha_ini AND dva_hasta >= ppl_fecha_ini AND dva_hasta <= ppl_fecha_fin
THEN gen.fn_diff_two_dates_30(ppl_fecha_ini, dva_hasta)
WHEN dva_desde >= ppl_fecha_ini AND dva_desde <= ppl_fecha_fin AND dva_hasta > ppl_fecha_fin
THEN gen.fn_diff_two_dates_30(dva_desde, ppl_fecha_fin)
WHEN dva_desde >= ppl_fecha_ini AND dva_hasta <= ppl_fecha_fin
THEN gen.fn_diff_two_dates_30(dva_desde, dva_hasta)
ELSE 0
END vac_dias
FROM acc.dva_dias_vacacion
JOIN acc.vac_vacaciones ON dva_codvac = vac_codigo
JOIN sal.ppl_periodos_planilla ON
((dva_desde < ppl_fecha_ini AND dva_hasta > ppl_fecha_fin)
OR (dva_desde < ppl_fecha_ini AND dva_hasta >= ppl_fecha_ini AND dva_hasta <= ppl_fecha_fin)
OR (dva_desde >= ppl_fecha_ini AND dva_desde <= ppl_fecha_fin AND dva_hasta > ppl_fecha_fin)
OR (dva_desde >= ppl_fecha_ini AND dva_hasta <= ppl_fecha_fin))
WHERE ppl_codigo = $$CODPPL$$
AND sal.empleado_en_gen_planilla('$$SESSIONID$$', vac_codemp) = 1
Si lo ejecutó en la base de datos si me regresa registros, probando cambiar el cursor, ya no me daba fallaba si lo dejaba de la siguiente forma:
SELECT $$CODPPL$$ ppl_codigo,
vac_codemp,
CASE
WHEN dva_desde < ppl_fecha_ini AND dva_hasta > ppl_fecha_fin
THEN gen.fn_diff_two_dates_30(ppl_fecha_ini, ppl_fecha_fin)
WHEN dva_desde < ppl_fecha_ini AND dva_hasta >= ppl_fecha_ini AND dva_hasta <= ppl_fecha_fin
THEN gen.fn_diff_two_dates_30(ppl_fecha_ini, dva_hasta)
WHEN dva_desde >= ppl_fecha_ini AND dva_desde <= ppl_fecha_fin AND dva_hasta > ppl_fecha_fin
THEN gen.fn_diff_two_dates_30(dva_desde, ppl_fecha_fin)
WHEN dva_desde >= ppl_fecha_ini AND dva_hasta <= ppl_fecha_fin
THEN gen.fn_diff_two_dates_30(dva_desde, dva_hasta)
ELSE 0
END vac_dias
FROM acc.dva_dias_vacacion
JOIN acc.vac_vacaciones ON dva_codvac = vac_codigo
JOIN sal.ppl_periodos_planilla ON
((dva_desde < ppl_fecha_ini AND dva_hasta > ppl_fecha_fin)
OR (dva_desde < ppl_fecha_ini AND dva_hasta >= ppl_fecha_ini AND dva_hasta <= ppl_fecha_fin)
OR (dva_desde >= ppl_fecha_ini AND dva_desde <= ppl_fecha_fin AND dva_hasta > ppl_fecha_fin)
OR (dva_desde >= ppl_fecha_ini AND dva_hasta <= ppl_fecha_fin))
WHERE ppl_codigo = $$CODPPL$$
AND sal.empleado_en_gen_planilla('$$SESSIONID$$', vac_codemp) = 1
Básicamente se cambio para que tomara de fijo el período de planilla, aunque no tiene ningún efecto en los registros que regresa.
Ya no se tiene este inconveniente, alguna idea de porque es que da error, para comprender si se debe evitar realizar cursores de cierta manera
Carlos, ya que quitaste el ppl_codigo de los campos del select, deberías convertir el JOIN sal.ppl_ ... en un EXISTS para que sea más eficiente.
Lo mismo con la función sal.empleo_en_gen_planilla(..) = 1 deberías usar la función tabla que es más rápida en un EXISTS.