Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Borrar n Registros de una Tabla (https://www.clubdelphi.com/foros/showthread.php?t=26960)

Abel Garcia 08-11-2005 18:54:54

Borrar n Registros de una Tabla
 
Hola, Tengo una duda que en primera instancia pareseria sencilla pero no he encontrado como hacerlo, la idea seria borrar los primeros n registros de una tabla esto usando Firebird 1.5 , el problema es que me encontre un parrafo en el documento Firebird 1.5 Relese notes donde afirma que la siguiente posible intruccion que podria llegar ha hacer esto tendria el siguiente problema:

Two Gotchas with SELECT FIRST
1. This
delete from TAB1 where PK1 in (select first 10 PK1 from TAB1);
will delete all of the rows in the table. Ouch! the sub-select is evaluating each 10 candidate rows for
deletion, deleting them, slipping forward 10 more...ad infinitum, until there are no rows left.
y si efectivamente si ejecutas la instruccion no solo borra los 10 primero como pudieras esperar, sin no que borra todos los registros:
Alguien mas Tiene un idea de como hacer esto ?

Muchas gracias por su ayuda :)

Casimiro Notevi 08-11-2005 19:32:18

En un query haces el select de esos primeros 10 registros y luego los recorres del primero al último borrándolo.

vtdeleon 08-11-2005 19:42:10

Saludos
Cita:

Empezado por Abel Garcia
Two Gotchas with SELECT FIRST
1. This
delete from TAB1 where PK1 in (select first 10 PK1 from TAB1);
[font=Trebuchet MS][size=2]
will delete all of the rows in the table. Ouch! the sub-select is evaluating each 10 candidate rows for
deletion, deleting them, slipping forward 10 more...ad infinitum, until there are no rows left.
[le

CHANFLEE!! :eek: No sabia. Nunca se me habia presentado el caso de borrar los 1ro tantos de un registro.
Seria interesante que alguien nos dijera como se podria hacer en sentencias.

lucasarts_18 08-11-2005 20:09:18

Cita:

Empezado por Casimiro Notevi
En un query haces el select de esos primeros 10 registros y luego los recorres del primero al último borrándolo.

Esto es como los conocidos cursores en otros motores, creo que aquí se hace con la instrucción FOR..

Casimiro Notevi 08-11-2005 20:50:36

Desde delphi podrías hacer algo así,:

Código SQL [-]
 DMdoc.QRlineas.Close;
 DMdoc.QRlineas.SelectSQL.Text := 'select first 10 from tbLineas';
 DMdoc.QRlineas.Open
 while not DMdoc.QRlineas.Eof do
     DMdoc.QRlineas.Delete;

Abel Garcia 08-11-2005 21:28:26

Cita:

Empezado por Casimiro Notevi
Desde delphi podrías hacer algo así,:

Código SQL [-]
 DMdoc.QRlineas.Close;
 DMdoc.QRlineas.SelectSQL.Text := 'select first 10 from tbLineas';
 DMdoc.QRlineas.Open
 while not DMdoc.QRlineas.Eof do
     DMdoc.QRlineas.Delete;

Ok si Casimiro Notevi, esa seria una forma pero la idea seria sin usar por decir delphi, sino atravez de una sentencia SQL, obviamenete tambien seria sin usar un procedimiento en la base de datos, bueno si es que es posible hacerlo ?

Casimiro Notevi 08-11-2005 21:42:08

Cita:

Empezado por Abel Garcia
Ok si Casimiro Notevi, esa seria una forma pero la idea seria sin usar por decir delphi, sino atravez de una sentencia SQL, obviamenete tambien seria sin usar un procedimiento en la base de datos, bueno si es que es posible hacerlo ?

Y si no es desde delphi, ni desde un procedimiento o trigger, entonces cómo quiéres hacerlo?, en alguno de los dos sitios tendrás que poner la sentencia :)

Abel Garcia 08-11-2005 21:46:52

Cita:

Empezado por Casimiro Notevi
Y si no es desde delphi, ni desde un procedimiento o trigger, entonces cómo quiéres hacerlo?, en alguno de los dos sitios tendrás que poner la sentencia :)

Si ok, bueno segun mi idea era hacerlo con algo sencillo como una sentencia SQL
como la del inicio de este hilo:

delete from TAB1 where PK1 in (select first 10 PK1 from TAB1);

bueno si es que es posible ?

jachguate 08-11-2005 21:53:59

Cita:

Empezado por Casimiro Notevi
Y si no es desde delphi, ni desde un procedimiento o trigger, entonces cómo quiéres hacerlo?, en alguno de los dos sitios tendrás que poner la sentencia :)

que tal en la "línea de comandos" de isql, bien en la consola de windows o linux? :D

Tal como lo veo, no será posible... ¿no es esto acaso un fallo?. Firebird debiera procesar primero el subquery, almacenar el resultado en algún lugar (tabla temporal, memoria, etc) y luego hacer el borrado de las líneas coincidentes?

Desconocía como trabaja el motor en este caso particular, y confieso que he quedado sorprendido.. :o

sospecho que forzosamente tendrá que haber algo.... no puede hacerse con una sola sentencia SQL. Por ejemplo, creando un procedimiento almacenado, si que sería posible conseguirlo.

Hasta luego.

;)

vtdeleon 08-11-2005 22:13:57

Saludos
Cita:

Empezado por jachguate
Tal como lo veo, no será posible... ¿no es esto acaso un fallo?.

Pienso* que si debe ser.
Cita:

Empezado por jachguate
Firebird debiera procesar primero el subquery, almacenar el resultado en algún lugar (tabla temporal, memoria, etc) y luego hacer el borrado de las líneas coincidentes?

Eso pense*.
Cita:

Empezado por jachguate
Desconocía como trabaja el motor en este caso particular, y confieso que he quedado sorprendido.. :o

Hice la prueba y me he quedado como tú

Quien tenga Oracle, MSSQL y MYSQL, que prueben a ver. Me gustaria saber el resultado (con una base de datos de prueba, claro está:)).

*Mucho pensamientos:p

roman 08-11-2005 22:24:59

Cita:

Empezado por vtdeleon
Quien tenga Oracle, MSSQL y MYSQL, que prueben a ver.

Pues en MySql 4.x no se puede pues el equivalente a first (limit) no puede usarse un subconsultas. Sin embargo, en este caso, es inecesaria la subconsulta ya que basta hacer:

Código SQL [-]
delete from tabla limit 10

// Saludos

Abel Garcia 08-11-2005 22:26:35

Bueno pensandolo muy bien si es que existe una soluccion aun cuando sea con un procedimiento almacenado en la base de datos alguien tiene una idea, supongo que se tendria que Usar una Tabla temporal o algo asi alguien sabe como ?

lucasarts_18 08-11-2005 22:30:25

Cita:

Empezado por vtdeleon
Quien tenga Oracle, MSSQL y MYSQL, que prueben a ver. Me gustaria saber el resultado (con una base de datos de prueba, claro está:)).

En SQL Server funciona perfecto

Código SQL [-]
 
 delete from cliente 
 where nombre in (select TOP 2 nombre from cliente)

Hasta Luego -

lucasarts_18 08-11-2005 22:38:03

Cita:

Empezado por Abel Garcia
Bueno pensandolo muy bien si es que existe una soluccion aun cuando sea con un procedimiento almacenado en la base de datos alguien tiene una idea

esto podría servirte

Debes hacer algo así.

Código SQL [-]
 For select firts 10 from tabla into :variable
 begin
  ....instrucciones sql
   delete from tabla where campo = variable;
 end;

En el enlace que te deje sale más explicativo el uso de procedimientos almacenados y la instrucción For..Do.

Hasta Luego -

Abel Garcia 08-11-2005 22:49:57

Me temo que no podria ser por este metodo, lo que pasa que este metodo requiere que
por lo menos uno de los campos en la tabla sea del tipo unico algo asi como un consecutivo unico para cada registro por que si esto no fuera asi, entonces cuando se ejecute la sentencia delete borraria campos de mas. Ademas no se que pasa si parseas una tabla de los primeros 10 en donde ademas estas borrando registros de esta tabla Me parese raro . Habria que probar No Cren....?

lucasarts_18 08-11-2005 22:57:39

Tienes razón, debe haber un modo...:(.

Casimiro Notevi 09-11-2005 01:25:09

Cita:

Empezado por jachguate
que tal en la "línea de comandos" de isql, bien en la consola de windows o linux? :D

Ya hombre, se suponía que era para usar desde dentro de un programa. :)

Cita:

Empezado por jachguate
Tal como lo veo, no será posible... ¿no es esto acaso un fallo?. Firebird debiera procesar primero el subquery, almacenar el resultado en algún lugar (tabla temporal, memoria, etc) y luego hacer el borrado de las líneas coincidentes?
Desconocía como trabaja el motor en este caso particular, y confieso que he quedado sorprendido.. :o

Acabo de hacer algo así:
Código SQL [-]
   delete from
tblineasdocumentos
where codigocabecera in
  (select first 10 codigocabecera
   from tblineasdocumentos)
y me he quedado sin datos :mad:

Cita:

Empezado por jachguate
sospecho que forzosamente tendrá que haber algo.... no puede hacerse con una sola sentencia SQL.

Tiene que haber algo :(

Cita:

Empezado por jachguate
Por ejemplo, creando un procedimiento almacenado, si que sería posible conseguirlo.

Claro, así sí.

lucasarts_18 09-11-2005 13:54:16

Cita:

Empezado por Casimiro Notevi
Tiene que haber algo :(

Yo creo que todos estamos esperando ansiosamente como se haría desde un SP, o no ?

Saludos..

Casimiro Notevi 09-11-2005 14:16:23

en un procedimiento sería algo así, como ya ha escrito antes Lucasarts_18:

Código SQL [-]
   CREATE PROCEDURE BorrarPrimerosRegistros (CUANTOSBORRAR INTEGER)
   AS
   DECLARE VARIABLE COD INTEGER;
   begin
       for select first( :cuantosborrar ) codigo
           from tbclientes
           into :cod
       do
          delete from tbclientes where codigo= :COD;
   end


La franja horaria es GMT +2. Ahora son las 10:41:15.

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