Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > MS SQL Server
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 10-03-2010
Ledian_Fdez Ledian_Fdez is offline
Miembro
 
Registrado: jun 2006
Ubicación: Ciudad Habana, Cuba
Posts: 242
Poder: 18
Ledian_Fdez Va por buen camino
Post ayuda con este query

Holas amigos de este foro:

Tengo dos tablas (DetalleB, DetalleBS) relacionadas entre si (uno a mucho) por iddetalle.
Necesito eliminar de la tabla DetalleB el registro que cumplan que idfactura = 15361, pero primero debo eliminar los registros de la tabla DetalleBS que esten relacionados.

Esta consulta:
Código SQL [-]
select iddetalle from DetalleBS
where idfactura = 15361
me devuelve : varios registros

ejemplo:
iddetalle 12,13,14 ...
Necesito eliminar de la tabla DetalleBS todos esos registros, por ejemplo:

Código SQL [-]
delete from DetalleBS
where iddetalle  = 12

Pero intento buscar una forma donde me lo elimine todos automaticamante. sin tener que ponérselo yo uno por uno, pensé en:

Código SQL [-]
delete from DetalleBS
where iddetalle  = (select iddetalle from DetalleB
where idfactura = 15361)

Pero me da el error:
Cita:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Podrían ayudarme
Responder Con Cita
  #2  
Antiguo 10-03-2010
Avatar de Caro
*Caro* Caro is offline
Moderadora
 
Registrado: jul 2004
Ubicación: Cochabamba, Bolivia
Posts: 2.544
Poder: 22
Caro Va por buen camino
Hola Ledian_Fdez, la consulta sería esta para borrar el detalle:

Código SQL [-]
Delete from DetalleBS
where idfactura = 15361

Saluditos
__________________
Disfruten cada minuto de su vida a lado de sus seres queridos como si fuese el ultimo, uno nunca sabe lo que puede pasar.
Responder Con Cita
  #3  
Antiguo 10-03-2010
Ledian_Fdez Ledian_Fdez is offline
Miembro
 
Registrado: jun 2006
Ubicación: Ciudad Habana, Cuba
Posts: 242
Poder: 18
Ledian_Fdez Va por buen camino
Thumbs down nada aun!!!

Esto es un procedimiento que intento hacer para una aplicacion que por algun error me genera documentos dobles y necesito eliminarlos todos.

Código SQL [-]
craate procedure EliminaDocumentoGeneradosDobles
@FactNo varchar(30)
as

declare 
  @FactId int,
  @FDet int

--para saber el idfactura conociendo su numero
select @FactId = idfactura from fac_factura
where NumCons = @FactNo

  --para saber el iddetalle conociendo su idfactura
  select @FDet = iddetalle from Fac_DetalleB
  where idfactura = @FactId 

 /* Ese Select me devuelve por ejemplo 3 registros y en @FDet solo se guarda      el ultimo*/
 
begin tran  

  delete from Fac_DetalleBS
  where iddetalle = @FDet

  /* aqui me jenera un error porque solo se elimino en la tabla Fac_DetalleBS el ultimo registro que contenia*/

  delete from Fac_DetalleB
  where idfactura = @FactId

  if @@error <> 0 
    begin
      RollBack
      raiserror ( 'Error al eliminar factura.', 16, -1)
    end
  else
    Commit

Por eso es que intentaba buscar otra solución tal como:

Código SQL [-]
delete from Fac_DetalleBS
where iddetalle  = (select iddetalle from Fac_DetalleB
where idfactura = 15361)

No se si me hago entender.
Responder Con Cita
  #4  
Antiguo 10-03-2010
Avatar de afunez2007
afunez2007 afunez2007 is offline
Miembro
 
Registrado: oct 2007
Ubicación: La Ceiba, Honduras
Posts: 170
Poder: 17
afunez2007 Va por buen camino
Lightbulb

Esta situacion se parece mucho a las utilidades que uo paso haciendo.

Por ejemplo eventualmente un cliente me dice que elimine las facturas anteriores al año 2005, entonces el asunto es que estan las cabeceras y los detalles.

Como lo resuelvo yo? La respuesta es hacer una utilidad que primero te permita seleccionar el rango de facturas que eliminaras podria ser una qry de la siguiente forma:
Código Delphi [-]
qryConsulta.Active:=False;
qryConsulta.Sql.Text:='SELECT *FROM CABECERA WHERE FECHA < '+QuotedStr('31/12/2006');
qryConsulta.Active:=True;

Seguidamente una vez que tengo en la pantalla una consulta con las facturas que deso borrar, hago un ciclo de la siguiente manera:
Código Delphi [-]
qryConsulta.First;
While not qryConsulta.Eof do 
begin
    qryDelete.Sql.Clear;
    qryDelete.Sql.Text:='DELETE FROM DETALLE WHERE NOFACTURA='+QuotedStr(qryConsulta.FieldByName('NOFACTURA').Text);
    qryDelete.ExecSql;
    qryConsulta.Next;
end;

//Una vez terminado el ciclo que borra los Detalles, borramos las cabeceras que se quedaron solas
qryConsulta.Active:=False;
qryDelete.Sql.Clear;
qryDelete.Sql.Text:='DELETE FROM CABECERA WHERE FECHA<'+QuotedStr('31/12/2006');
qryDelete.ExecSql;

Bueno esto es lo que yo suelo hacer, ojala te sirva

Saludos
__________________
Si robas, roba un beso, si mientes que sea por amor y si engañas que sea a la muerte!!
Responder Con Cita
  #5  
Antiguo 10-03-2010
Ledian_Fdez Ledian_Fdez is offline
Miembro
 
Registrado: jun 2006
Ubicación: Ciudad Habana, Cuba
Posts: 242
Poder: 18
Ledian_Fdez Va por buen camino
Thumbs up aun no !!!

Eso esta muy bueno, pero en mi caso solo puse una parte del código, me pasa con muchas mas tablas y pensé que con un procedimiento almacenado lo podría resolver.

Gracias de todas formas y es muy valida tu ayuda, lo tendré en cuanta para otras ocasiones.

Aun estoy en espera de mas ideas. Aunque me encanta trabajar con SQL.
Responder Con Cita
  #6  
Antiguo 11-03-2010
sinalocarlos sinalocarlos is offline
Miembro
 
Registrado: sep 2006
Posts: 152
Poder: 18
sinalocarlos Va por buen camino
A mi entender lo correcto seria manejar la propiedad de "cascade" en los foreign key para el delete entre las tablas detalles, asi cuando borrases un detalle en la tabla de Fac_DetalleB se eliminaria de la tabla de Fac_DetalleBS sin tener que tirar codigo de tu parte.

sin embargo el mundo no es tan bello como quisieramos y existen ocaciones en donde el borrado de los detalles de las tablas secundarias es en base a validaciones y es ahi donde nos metemos en problemas al usar un delete on cascade y casi casi nos vemos forsados a ejecutar procedimientos.

en tu caso el borrado de las tablas quedaria:

Código SQL [-]
delete from Fac_DetalleBS
from Fac_DetalleBS inner join Fac_DetalleB on 
Fac_DetalleBS.iddetalle =  Fac_DetalleB.iddetalle
inner join fac_factura on Fac_DetalleB.idfactura =  fac_factura.idfactura
where fac_factura.NumCons = @FactNo

y con eso te ahorras la consulta para sacar el id de la factura, para eliminar los detalles de la tabla Fac_DetalleB se usaria la misma logica:


Código SQL [-]
delete from Fac_DetalleB
from Fac_DetalleB inner join fac_factura on 
Fac_DetalleB.idfactura =  fac_factura.idfactura
where fac_factura.NumCons = @FactNo
y listo.

incluso existe una tercera opcion:

usando un trigger instead of delete en la tabla Fac_DetalleB

Código SQL [-]
create trigger trg_fac_detalleb
on fac_detalleb
instead of delete
as
begin
    delete from fac_detallebs
    from fac_detallebs inner join deleted on 
    fac_detalleb.iddetalle = deleted.iddetalle 
    
    delete from fac_detalleb
    from fac_detalleb inner join deleted on 
    fac_detalleb.iddetalle = deleted.iddetalle 
    

end

y asi la eliminacion de los detalles se haria automatico con el borrado.

tu decides.

por cierto, si detectas algun error en sintaxis el problema es que no tengo SQL la mano y lo teclee todo en notepad
Responder Con Cita
  #7  
Antiguo 11-03-2010
Avatar de ElKurgan
[ElKurgan] ElKurgan is offline
Miembro Premium
 
Registrado: nov 2005
Posts: 1.234
Poder: 20
ElKurgan Va camino a la fama
Cita:
Empezado por Ledian_Fdez Ver Mensaje
Código SQL [-]
delete from DetalleBS
where iddetalle  = (select iddetalle from DetalleB
where idfactura = 15361)

¿Has probado con poner "IN" en lugar de "="?
Lo digo porque el mensaje te lo dice claramente, se devuelven muchas filas donde se esperaba sólo una...

Código SQL [-]
delete from DetalleBS
where iddetalle  in (select iddetalle from DetalleB
where idfactura = 15361)

Un saludo
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Mirar por favor este query y comentar... El_Raso Firebird e Interbase 33 18-11-2008 12:53:44
ayuda con este codigo kurono Varios 4 13-06-2008 01:03:29
una ayuda con este error please dariana20 SQL 3 14-06-2006 23:14:06
como quedaria el SQL para este Query?? JCarlos Conexión con bases de datos 2 15-11-2004 12:59:28
Ayuda con este error???? danytorres Varios 1 27-10-2004 11:38:09


La franja horaria es GMT +2. Ahora son las 21:08:12.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi