Deshabilitar Relaciones

06/05/2004 - 11:47 por Jesús | Informe spam
Hola :
Estoy realizando un proceso para borrar datos de una tabla
a la cual referencian muchas otras tablas mediante FK.
Después de muchas pruebas he visto que la solución que
menos tiempo me tarda es deshabilitar las relaciones
mientras se borra y volver a habilitarlas otra vez (ALTER
TABLE tabla NOCHECK|CHEK). La disminución de tiempo ha
sido abismal. Mi pregunta se refiere a que si hay forma de
que esa deshabilitación de restricciones se pueda hacer
solo para el borrado ya que durante el tiempo que se está
borrando se pueden insertar datos que violan la integridad
referencial. Quiero evitar que mientras se está borrando
se inserten datos incoherentes. ¿Es posible? ¿Cómo?.
Gracias de antemano.
Jesús

Preguntas similare

Leer las respuestas

#1 Adrian D. Garcia
06/05/2004 - 13:10 | Informe spam
No se puede hacer lo que dices. Las restricciones se aplican en todos los
casos, o no se aplican.
Quizas puedas deshabilitar las restricciones y aplicar las mismas reglas de
verificacion en triggers/disparadores de INSERT sobre la tabla. Con lo cual
las eliminaciones se ejecutaran con buena performance pero las inserciones
se ejecutaran con peor performance que si estuvieran las restricciones
definidas ya que realizar la verificacion de claves foraneas en un trigger
es mucho mas costoso que si se realiza por medio de una restriccion.

Saludos

Adrian D. Garcia
NDSoft
MCSD
"Jesús" escribió en el mensaje
news:8fe901c4334f$287425f0$
Hola :
Estoy realizando un proceso para borrar datos de una tabla
a la cual referencian muchas otras tablas mediante FK.
Después de muchas pruebas he visto que la solución que
menos tiempo me tarda es deshabilitar las relaciones
mientras se borra y volver a habilitarlas otra vez (ALTER
TABLE tabla NOCHECK|CHEK). La disminución de tiempo ha
sido abismal. Mi pregunta se refiere a que si hay forma de
que esa deshabilitación de restricciones se pueda hacer
solo para el borrado ya que durante el tiempo que se está
borrando se pueden insertar datos que violan la integridad
referencial. Quiero evitar que mientras se está borrando
se inserten datos incoherentes. ¿Es posible? ¿Cómo?.
Gracias de antemano.
Jesús
Respuesta Responder a este mensaje
#2 Jesús
06/05/2004 - 14:59 | Informe spam
Gracias por la respuesta.
Jesús.

No se puede hacer lo que dices. Las restricciones se


aplican en todos los
casos, o no se aplican.
Quizas puedas deshabilitar las restricciones y aplicar


las mismas reglas de
verificacion en triggers/disparadores de INSERT sobre la


tabla. Con lo cual
las eliminaciones se ejecutaran con buena performance


pero las inserciones
se ejecutaran con peor performance que si estuvieran las


restricciones
definidas ya que realizar la verificacion de claves


foraneas en un trigger
es mucho mas costoso que si se realiza por medio de una


restriccion.

Saludos

Adrian D. Garcia
NDSoft
MCSD
"Jesús" escribió en el mensaje
news:8fe901c4334f$287425f0$
Hola :
Estoy realizando un proceso para borrar datos de una tabla
a la cual referencian muchas otras tablas mediante FK.
Después de muchas pruebas he visto que la solución que
menos tiempo me tarda es deshabilitar las relaciones
mientras se borra y volver a habilitarlas otra vez (ALTER
TABLE tabla NOCHECK|CHEK). La disminución de tiempo ha
sido abismal. Mi pregunta se refiere a que si hay forma de
que esa deshabilitación de restricciones se pueda hacer
solo para el borrado ya que durante el tiempo que se está
borrando se pueden insertar datos que violan la integridad
referencial. Quiero evitar que mientras se está borrando
se inserten datos incoherentes. ¿Es posible? ¿Cómo?.
Gracias de antemano.
Jesús


.

Respuesta Responder a este mensaje
#3 Javier Loria
07/05/2004 - 09:41 | Informe spam
Hola Jesus:
Lo unico que necesitas es utilizar transacciones, con esto bastara para
lograr lo que deseas.
Los ALTER TABLE participan en TRANSACCIONES por ende mantienen una de
las propiedades de la Transacciones ACID, que es la INDEPENDENCIA, deben ser
invisibles para el resto de los usuarios hasta que se haga COMMIT.
Para probarlo, abre una sesion de Query Analizer y en alguna BD de
pruebas ejecutas:
== Creacion de Tablas
CREATE TABLE Madres(
Madre INT NOT NULL
CONSTRAINT PK_Madres
PRIMARY KEY (Madre)
)
CREATE TABLE Hijas(
Madre INT NOT NULL
, Hija INT NOT NULL
, CONSTRAINT PK_Hijas
PRIMARY KEY(Madre, Hija)
, CONSTRAINT FK_HijasMadres
FOREIGN KEY (Madre) REFERENCES Madres(Madre),
)
GO
INSERT Madres VALUES(1)
INSERT Hijas VALUES(1,1)
GO
BEGIN TRAN
ALTER TABLE Hijas
NOCHECK CONSTRAINT FK_HijasMadres
DELETE Madres
INSERT Hijas VALUES(2,1)

SELECT * FROM Madres
SELECT * FROM Hijas
=Como veras el codigo deja abierta una transaccion y podes hacer operaciones
que incumplen la llave Foranea.
En el mismo QA abre otra ventana, y ejecutas:
=INSERT Hijas
VALUES(3,1)
= Veras como se queda "esperando" el commit de la otra transaccion, de
manera que a menos que hagas commit en la primera ventana no podras
modificar los datos.
Por supuesto ahora en la primer ventana podrias escribir el Alter Table
para volver a habilitar la Llave Foranea y cuando sea haga COMMIT la segunda
ventana dara error.
De manera tal que la forma de hacer lo que deseas es usando
transacciones.
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.
Jesús escribio:
Hola :
Estoy realizando un proceso para borrar datos de una tabla
a la cual referencian muchas otras tablas mediante FK.
Después de muchas pruebas he visto que la solución que
menos tiempo me tarda es deshabilitar las relaciones
mientras se borra y volver a habilitarlas otra vez (ALTER
TABLE tabla NOCHECK|CHEK). La disminución de tiempo ha
sido abismal. Mi pregunta se refiere a que si hay forma de
que esa deshabilitación de restricciones se pueda hacer
solo para el borrado ya que durante el tiempo que se está
borrando se pueden insertar datos que violan la integridad
referencial. Quiero evitar que mientras se está borrando
se inserten datos incoherentes. ¿Es posible? ¿Cómo?.
Gracias de antemano.
Jesús
Respuesta Responder a este mensaje
#4 jboca
07/05/2004 - 23:21 | Informe spam
Hola Jesus, otra cosa que puedes hacer es usar conexiones pesimistas,
estas se encargan de bloquear tus entradas mientras estes haciendo este
proceso, pero tranquilo quedan en colay no hay problema, luego el abre la
entrada y no las dejara entrar si no cumplen con las reglas de integridad
referencial.

Espero te sea util

John Jairo Bocachica
Colombia

Javier Loria wrote:

Hola Jesus:
Lo unico que necesitas es utilizar transacciones, con esto bastara para
lograr lo que deseas.
Los ALTER TABLE participan en TRANSACCIONES por ende mantienen una de
las propiedades de la Transacciones ACID, que es la INDEPENDENCIA, deben ser
invisibles para el resto de los usuarios hasta que se haga COMMIT.
Para probarlo, abre una sesion de Query Analizer y en alguna BD de
pruebas ejecutas:
==> Creacion de Tablas
CREATE TABLE Madres(
Madre INT NOT NULL
CONSTRAINT PK_Madres
PRIMARY KEY (Madre)
)
CREATE TABLE Hijas(
Madre INT NOT NULL
, Hija INT NOT NULL
, CONSTRAINT PK_Hijas
PRIMARY KEY(Madre, Hija)
, CONSTRAINT FK_HijasMadres
FOREIGN KEY (Madre) REFERENCES Madres(Madre),
)
GO
INSERT Madres VALUES(1)
INSERT Hijas VALUES(1,1)
GO
BEGIN TRAN
ALTER TABLE Hijas
NOCHECK CONSTRAINT FK_HijasMadres
DELETE Madres
INSERT Hijas VALUES(2,1)

SELECT * FROM Madres
SELECT * FROM Hijas
=> Como veras el codigo deja abierta una transaccion y podes hacer operaciones
que incumplen la llave Foranea.
En el mismo QA abre otra ventana, y ejecutas:
=> INSERT Hijas
VALUES(3,1)
=> Veras como se queda "esperando" el commit de la otra transaccion, de
manera que a menos que hagas commit en la primera ventana no podras
modificar los datos.
Por supuesto ahora en la primer ventana podrias escribir el Alter Table
para volver a habilitar la Llave Foranea y cuando sea haga COMMIT la segunda
ventana dara error.
De manera tal que la forma de hacer lo que deseas es usando
transacciones.
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.
Jesús escribio:
> Hola :
> Estoy realizando un proceso para borrar datos de una tabla
> a la cual referencian muchas otras tablas mediante FK.
> Después de muchas pruebas he visto que la solución que
> menos tiempo me tarda es deshabilitar las relaciones
> mientras se borra y volver a habilitarlas otra vez (ALTER
> TABLE tabla NOCHECK|CHEK). La disminución de tiempo ha
> sido abismal. Mi pregunta se refiere a que si hay forma de
> que esa deshabilitación de restricciones se pueda hacer
> solo para el borrado ya que durante el tiempo que se está
> borrando se pueden insertar datos que violan la integridad
> referencial. Quiero evitar que mientras se está borrando
> se inserten datos incoherentes. ¿Es posible? ¿Cómo?.
> Gracias de antemano.
> Jesús
Respuesta Responder a este mensaje
#5 jboca
07/05/2004 - 23:21 | Informe spam
Hola Jesus, otra cosa que puedes hacer es usar conexiones pesimistas,
estas se encargan de bloquear tus entradas mientras estes haciendo este
proceso, pero tranquilo quedan en colay no hay problema, luego el abre la
entrada y no las dejara entrar si no cumplen con las reglas de integridad
referencial.

Espero te sea util

John Jairo Bocachica
Colombia

Javier Loria wrote:

Hola Jesus:
Lo unico que necesitas es utilizar transacciones, con esto bastara para
lograr lo que deseas.
Los ALTER TABLE participan en TRANSACCIONES por ende mantienen una de
las propiedades de la Transacciones ACID, que es la INDEPENDENCIA, deben ser
invisibles para el resto de los usuarios hasta que se haga COMMIT.
Para probarlo, abre una sesion de Query Analizer y en alguna BD de
pruebas ejecutas:
==> Creacion de Tablas
CREATE TABLE Madres(
Madre INT NOT NULL
CONSTRAINT PK_Madres
PRIMARY KEY (Madre)
)
CREATE TABLE Hijas(
Madre INT NOT NULL
, Hija INT NOT NULL
, CONSTRAINT PK_Hijas
PRIMARY KEY(Madre, Hija)
, CONSTRAINT FK_HijasMadres
FOREIGN KEY (Madre) REFERENCES Madres(Madre),
)
GO
INSERT Madres VALUES(1)
INSERT Hijas VALUES(1,1)
GO
BEGIN TRAN
ALTER TABLE Hijas
NOCHECK CONSTRAINT FK_HijasMadres
DELETE Madres
INSERT Hijas VALUES(2,1)

SELECT * FROM Madres
SELECT * FROM Hijas
=> Como veras el codigo deja abierta una transaccion y podes hacer operaciones
que incumplen la llave Foranea.
En el mismo QA abre otra ventana, y ejecutas:
=> INSERT Hijas
VALUES(3,1)
=> Veras como se queda "esperando" el commit de la otra transaccion, de
manera que a menos que hagas commit en la primera ventana no podras
modificar los datos.
Por supuesto ahora en la primer ventana podrias escribir el Alter Table
para volver a habilitar la Llave Foranea y cuando sea haga COMMIT la segunda
ventana dara error.
De manera tal que la forma de hacer lo que deseas es usando
transacciones.
Saludos,

Javier Loria
Costa Rica
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.
Jesús escribio:
> Hola :
> Estoy realizando un proceso para borrar datos de una tabla
> a la cual referencian muchas otras tablas mediante FK.
> Después de muchas pruebas he visto que la solución que
> menos tiempo me tarda es deshabilitar las relaciones
> mientras se borra y volver a habilitarlas otra vez (ALTER
> TABLE tabla NOCHECK|CHEK). La disminución de tiempo ha
> sido abismal. Mi pregunta se refiere a que si hay forma de
> que esa deshabilitación de restricciones se pueda hacer
> solo para el borrado ya que durante el tiempo que se está
> borrando se pueden insertar datos que violan la integridad
> referencial. Quiero evitar que mientras se está borrando
> se inserten datos incoherentes. ¿Es posible? ¿Cómo?.
> Gracias de antemano.
> Jesús
email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida