Registro contable cuadrado

09/05/2008 - 14:04 por Guillermo Rojas | Informe spam
Dos tablas de un sistema de contabilidad para registros contables:

regConth (registro contable encabezado)
-
regno int -- pk identity
fecha date
...

regContd (registro contable detalle)

regno int
ctano char(10) --cuenta contable
debito decimal
credito decimal
...

Tengo que hacer que cada registro (regno) este cuadrado: que la suma de los
debitos sea igual a la suma de los creditos. Si no esta no debe aceptarlo.
No veo como poner esta restriccion en SQL Server, si un trigger o check, etc
y en cual de las dos tablas o si tengo que validarlo desde la aplicacion.
Que me podrian decir para orientarme?

Preguntas similare

Leer las respuestas

#16 Carlos M. Calvelo
14/05/2008 - 21:14 | Informe spam
Hola Alfredo,

On 14 mei, 18:38, Alfredo Novoa wrote:
On Wed, 14 May 2008 09:01:21 -0700 (PDT), "Carlos M. Calvelo"

>Los DELETE's se saltan los checks y habrá que controlarlos con
>triggers.

No había caido. Otro fallo más de SQL para la larga lista.



Sería mucho menos trabajo tener una lista de lo que está bien.

Otro problema que no veo como hacerlo con checks es
que no tienes los valores del registro anterior (deleted).
Y si se hace un update cambiando la clave foranea en
la tabla detalles o la clave primaria en el encabezado...
... a ver ...

Saludos,
Carlos
Respuesta Responder a este mensaje
#17 Carlos M. Calvelo
15/05/2008 - 01:48 | Informe spam
Hola otra vez Alfredo,

On 14 mei, 21:14, "Carlos M. Calvelo" wrote:
Otro problema que no veo como hacerlo con checks es
que no tienes los valores del registro anterior (deleted).
Y si se hace un update cambiando la clave foranea en
la tabla detalles o la clave primaria en el encabezado...
... a ver ...




He estado pensando un poco mas sobre esto y creo que lo que se está
tratando de expresar aquí no es una restricción de integridad típica,
si no una regla de transición. Digamos una restricción de transición
(insert, update o delete).

Me explico:
Supongamos que tenemos estas tablas

Cabecera {
CID INT NOT NULL PRIMARY KEY,
CERRADO CHAR
}

Detalle {
DID INT NOT NULL PRIMARY KEY,
CID INT NOT NULL FOREIGN KEY REFERENCES Cabecera(CID),
DEBITO NOT NULL NUMERIC(15,5),
CREDITO NOT NULL NUMERIC(15,5)
}

La única restricción de integridad que me puedo imaginar es algo
como: (en un pseudo-SQL para que nos entendamos un poco)

CONSTRAINT
NOT EXISTS(SELECT *
FROM Cabecera C JOIN Detalle D ON C.CID=D.CID
WHERE C.CERRADO='Si'
GROUP BY C.CID
HAVING SUM(DEBITO)<>SUM(CREDITO))

Este constraint solo dice que CERRADO en la tabla Cabecera solo
podrá ser 'Si' cuando el total DEBITO sea igual al total CREDITO.

Que en esa situacion no se puedan introducir, actualizar o borrar
registros, lo cual si es posible hacer sin vulnerar la regla, es
solo una prohibición dada solo porque CERRADO = 'Si'.

Para asegurarse de que algo no cambia se necesita poder 'ver' las
versiones anterior y actual de los registros (deleted, inserted).
Y por lo tanto creo que no es posible sin hacer uso de triggers.

Saludos,
Carlos
Respuesta Responder a este mensaje
#18 Maxi Accotto
15/05/2008 - 02:00 | Informe spam
Hola, bueno la cosa no es asi, quien dijo que no se puede modificar? si
haces un update se modifica! para evitar esas cosas deberias definir reglas
de negocio que lo impidan, por ejemplo por medio de trigger, pero por
defecto sql te deja hacer la sentencia DML que tengas permiso y no viele
alguna restriccion si existe


Microsoft MVP SQLServer
www.sqltotalconsulting.com
-

"Penta" escribió en el mensaje de
noticias:
Toda la razon Alfredo.
Desconocia que para estos casos un registro cerrado no se puede
modificar, pero si se cierra por error ?? que se hace en dicho caso ??

Atte.
Penta.
Respuesta Responder a este mensaje
#19 Alfredo Novoa
15/05/2008 - 10:24 | Informe spam
Hola Maxi,

El Wed, 14 May 2008 21:00:10 -0300, Maxi Accotto escribió:

Hola, bueno la cosa no es asi, quien dijo que no se puede modificar?



Lo dije yo :-)

si
haces un update se modifica!



Si haces un update y este viola una regla de un CHECK no se modifica.

Pero los checks no funcionan con los borrados :-(

para evitar esas cosas deberias definir reglas
de negocio que lo impidan



Los manuales de SQL Server las llaman reglas de integridad definidas por el
usuario:

http://msdn.microsoft.com/en-us/lib...88258.aspx

Aunque esto es bastante tonto, por que todas las reglas de integridad son
definidas por los usuarios.

, por ejemplo por medio de trigger, pero por
defecto sql te deja hacer la sentencia DML que tengas permiso y no viele
alguna restriccion si existe



Como dijo Carlos, te deja ejecutar deletes aunque violen restricciones
CHECK :-(

CHECK constraints are not validated during DELETE statements. Therefore,
executing DELETE statements on tables with certain types of check
constraints may produce unexpected results.

http://msdn.microsoft.com/en-us/lib...88258.aspx


Saludos
Respuesta Responder a este mensaje
#20 Alfredo Novoa
15/05/2008 - 10:27 | Informe spam
Hola Carlos,

El Wed, 14 May 2008 16:48:12 -0700 (PDT), Carlos M. Calvelo escribió:

He estado pensando un poco mas sobre esto y creo que lo que se está
tratando de expresar aquí no es una restricción de integridad típica,
si no una regla de transición. Digamos una restricción de transición
(insert, update o delete).



Si, aunque una regla de transición tampoco tiene nada de atípico, pero
desafortunadamente SQL Server no permite definirlas de forma declarativa.

Para asegurarse de que algo no cambia se necesita poder 'ver' las
versiones anterior y actual de los registros (deleted, inserted).
Y por lo tanto creo que no es posible sin hacer uso de triggers.



En Tutorial D si que se podría definir fácilmente sin usar triggers.


Saludos
Alfredo
Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente AnteriorRespuesta Tengo una respuesta
Search Busqueda sugerida