2011-04-07 53 views
22

Estoy intentando utilizar la cláusula DELETE en MS Access y tengo un problema cuando también uso la cláusula JOIN. He notado que esto se puede lograr usando la palabra clave DISTINCTROW.¿Cómo eliminar en MS Access cuando se usa JOIN?

Por ejemplo, la siguiente instrucción SQL no permite la eliminación:

DELETE Table1.* 
FROM Table1 INNER JOIN Table2 ON Table1.Name=Table2.Name; 

Sin embargo, esta afirmación:

DELETE DISTINCTROW Table1.* 
FROM Table1 INNER JOIN Table2 ON Table1.Name=Table2.Name; 
  • ¿Por qué la DELETE trabajo cuando se utiliza la palabra clave DISTINCTROW ?
  • Más específicamente, ¿qué está pasando en el motor JET para requerir esto?
+2

Teniendo en cuenta que 'DELETE' opera en filas enteras en lugar de columnas, especificando * cualquier cosa * entre las palabras clave 'DELETE 'y' FROM' no tiene sentido. – onedaywhen

Respuesta

22
Delete Table1.* 
From Table1 
Where Exists(Select 1 From Table2 Where Table2.Name = Table1.Name) = True 

Para ampliar mi respuesta, la especificación oficial de SQL no prevé el uso de combinaciones en las consultas de acción específica, ya que puede crear resultados ambiguos. Por lo tanto, es mejor (y Access es mucho más feliz) si puede evitar el uso de uniones en las consultas de acción como he aquí. El motivo por el que Access quiere DISTINCTROW es que es probable que la combinación entre las dos tablas cree duplicados de filas de la Tabla1 (es decir, que haya múltiples filas relacionadas en la Tabla 2) y, por lo tanto, Access se confunde. También descubrí que si intentas utilizar una combinación y una clave principal no existe, Access se bloqueará. En general, es mejor evitar una unión en una consulta de acción si puede.

+5

Su respuesta es exactamente correcta: el propósito de DISTINCTROW es resolver un multitarea en filas exclusivas de manera que sean editables. –

+2

Me gustaría agregar que la consulta proporcionada anteriormente puede tener un rendimiento extremadamente bajo cuando se usan combinaciones de bases de datos cruzadas (o Acceso a otra base de datos) que no se produce con DISTINCTROW. (en un caso fue 20 segundos vs no terminado después de 1 h) – Stefan

+0

@Stefan - Una versión alternativa de la misma consulta sería 'Donde PKCol In (...) = True' que elimina la correlación e incluso en escenarios de bases de datos cruzadas debería desempeñarse bien. Como no hay capacidad para analizar el plan de ejecución en Access, no hay forma de determinar fácilmente qué hace realmente DISTINCTROW y qué está haciendo mal al usar la función Exists. Nos queda el uso de prueba y error. – Thomas

2

Un problema a tener en cuenta: ¡Esto NO funciona con alias de tabla/consulta!

DELETE a.* 
from tblA as A 
where exists (select 1 from tblB as B where a.id=b.id) 

Elimina TODOS los registros en tblA! Lo intenté usando alias para tblA y tblB por separado: el mismo resultado (Access 2010).

sucede con SELECT, así (que utilizo a menudo antes de eliminar) ...

0
DELETE a.* 
FROM tblA AS A 
WHERE EXISTS (SELECT 1 FROM tblB AS B WHERE a.id=b.id) 

probar este

DELETE tblA 
FROM tblB 
WHERE EXISTS (SELECT * FROM tblA AS A,tblB AS B WHERE A.id=B.id) 
+0

Eliminar de TBLA en donde id (SELECT ID de tblB) – user7047561

+0

para unirse a la mesa: – user7047561

+0

BORRAR * DE Ttrans donde existe (seleccione un * de Ttrans a, b temp_tmbtrans donde ttrans.ref_code = b.ref_code . y ttrans.fund_account = b.fund_account y ttrans.tr_date = b.tr_date y ttrans.tr_code = b.tr_code y ttrans.sharecode = b.sharecode y ttrans.unit = b.unit y ttrans.amt = b.amt y ttrans.price = b.price y ttrans.account = b.account); – user7047561