Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   SQL (https://www.clubdelphi.com/foros/forumdisplay.php?f=6)
-   -   borrar registro en un query (https://www.clubdelphi.com/foros/showthread.php?t=42999)

mjjj 27-04-2007 21:50:46

borrar registro en un query
 
hola amigos... ayudenme con el siguiente problem...

quiero borrar un registro de un query.

selecciono el registro de un dbgrid y presiono un boton que tiene el siguiente codigo.... query1.delete, efectivamente el registro se elimina del dbgrid, pero al hacer un nueva busqueda este vuelve a aparecer.

Que pasa con eso... he tratado con query1.post y me tira un error de dataset not in edit or insert modo... entonces agregue query1.edit antes del delete y me tira este otro error... cannot modify a read only dataset

uffff... ojala me entiendan.... gracias

Caral 27-04-2007 21:57:00

Hola mjjj
Para empezar lo normal es identificar:
Query es un aposento de una sentencia sql, que trae informacion de una tabla o varias, osea, borrar un query, es raro, esto te lo digo nada mas como comentario sin afan de critica.
Segundo, antes de un query.delete; deberia haber algo, que voy a borrar?
Entonces, resumiendo, si colocas el codigo con el que estas haciendo la operacion sera mas facil interpretar el problema.
Otra cosa importante, que base de datos usas?, que campos, que claves?
Saludos

mjjj 27-04-2007 22:15:37

a ver, voy a tratar de ser mas claro....

estoy usando tablas paradox, sin KEY, lo que hago es realizar una busqueda utilizando un query luego selecciono el registro que quiero borrar desde un dbgrid, una vez seleccionado el registro, presiono un boton con el codigo query1.delete... se borra el registro del dbgrid, pero al realizar nuevamente la busqueda este vueve aparecer....

esta operacion le he utilizado en tablas, en ese caso me a funcionado perfectamente...

gracias

Caral 28-04-2007 00:53:22

Hola
Tienes un query, el cual carga un dbgrid, apretando un boton quieres borrar el dato elegido.
Bueno el query genera una informacion y contiene unos campos en el, va, con otro query se elimina el dato que se quiere, aqui un ejemplo:
Código Delphi [-]
begin
      DataModule1.AC1.BeginTrans;
      try
         Query.SQL.Text := 'Delete * from TUTABLA where TUCAMPO = '+TUTABLATUCAMPOTuDato.AsString;
         Query.ExecSQL;
         DataModule1.AC1.CommitTrans;
      except
         on E:Exception do
         begin
            DataModule1.AC1.RollbackTrans;
            MessageDlg('Se ha producido un error.',mtError,[mbok],9);
         end;
      end;
Aqui como veras se hace la conexion directa al modulo de datos y al conector, se inicializa, se ejecuta, de lo contrario, envia un mensaje.
Saludos

mjjj 28-04-2007 01:58:44

ufffff... perdon la ignorancia... que es un datamodule, trata de explicarme con manzanas lo que hace cada linea del codigo asi yo puedo adaptarlo a mi programa.... se que es mucho pedir, pero me harias un gran favor

tengo que agregar otro query a mi form... en ese agrego las lineas SQL... el otro lo dejo tal cual??

ayuda please

gracias

Caral 28-04-2007 02:12:07

Hola mjjj
Me parece que como las manzanas estas un poco verde en esto.:D
Bueno eso no es un pecado, seria muy bueno que pusieras una copia del codigo que estas haciendo, asi veriamos como va.
Usa las etiquetas del club se vera mejor.
Saludos

egostar 28-04-2007 02:24:35

Hasta donde se los Queries son objetos de solo lectura, asi que para poder borrar un registro del Query, debes usar el objeto UpdateSQL para que se encargue de realizar el proceso de borrado.

Salud OS.

Caral 28-04-2007 02:29:10

Hola Egostar
Ahora si que me dejaste, que, como, cuando, donde?:D
Saludos

vtdeleon 28-04-2007 02:56:53

egostar tiene razon, aunque he visto una propiedad llamada Requestlive (algo asi) para modificar, eliminar,..y todo lo demas.

Caral, seguro el amigo mjjj esta realizando una consulta "select", solo para ver registros, entonces trata de usar el método Delete. El Query arrojara un error porque este es solo de lectura y no de insercion como un table. Con un UpdateSql relacionado o vinculado con el Query se podria solucionar el problema, ya que UpdateSql contendria la sentencia necesaria para el borrado, en este caso "Delete...".

El codigo que expones mas arrib (caral) funciona bien, pero el Query nunca te arrojaria registros para visualizar, sino para ejecutar.

Caral 28-04-2007 03:08:30

Hola
De plano coincido tanto con el maestro Egostar como con tigo vtdeleon, pero es muy dificil evacuar una duda sin el criterio, mas o menos completo, si la duda es:
Cita:

selecciono el registro de un dbgrid
se supone que hay algun query o tabla involucrado en el asunto e independiente de:
Cita:

presiono un boton que tiene el siguiente codigo.... query1.delete
Para mi el asunto radicaba en el supuesto (tambien para mi) segundo query, que por supuesto si contiene una sentencia select, no caminaria nunca el delete, estoy de acuerdo en que no debuelve nada por el Query.ExecSQL;, pero solucionado facilmente con un simple Query.open;.
Es muy interesante que de un problema tan sencillo se logre un aprendizaje tan bueno, me alegro mucho que me indiquen mis errores, seguro que asi algun dia sere un maestro como vosotros, bueno, casi.:D
Saludos

egostar 28-04-2007 03:36:25

Bueno, ya hice unas pruebas con el mentado UpdateSQL.

Imagino que nuestro amigo mjjj ya tiene un Query, un DataSource y un DbGrid.

Agregamos un UpdateSQL a nuestra forma y modificamos las siguientes propiedades del Query
  • CachedUpdate a True
  • RequestLive a True
  • UpDateObject es el UpdateSQL
Debemos crear la sentencia DeleteSQL en el UpdateSQL, puede hacerse automatico o manual, yo lo hice manualmente ya que solo me interesa el Delete y no InsertSQL ni ModifySQL.

Código SQL [-]
delete from llamadaH
where Folio = :OLD_Folio

En un botón metemos este código

Código Delphi [-]
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  try
    UpDateSQL1.Apply(ukDelete);
    Query1.CommitUpdates;
  except
    ShowMessage('Algo oscuro paso');
  end;
  Query1.Close;
  Query1.Open;
end;

Ejecutamos nuestro programa, aqui quiero comentar algo, aunque me manda error al borrar, la linea si es borrada, debo checar porque esta pasando eso, creo que por ahi lei un comentario de roman que decia que evitaba el uso del UpdateSQL porque le parecia el lado oscuro del VCL de Delphi:D.

Bueno, pues seguimos viendo la mejor manera de resolver este problema, por el momento debo salir.

Salud OS.

Caral 28-04-2007 03:42:15

Hola
Siguiendo con esto que esta interesante, pienso que mjjj, va captando el asunto:
Cita:

tengo que agregar otro query a mi form... en ese agrego las lineas SQL... el otro lo dejo tal cual??
Creo que seria conveniente explicar un poco la mecanica del uso de un query, por lo menos vasicamente, por favor corrijanme.
A una de las preguntas hechas por mjjj:
El datamodule, como su nombre lo dice es el modulo donde se colocan los conectores de las bases de datos, Tables, querys entre otros, el uso del datamodule es una practica muy buena, en mi caso, lo utilizo para el conector exclusivamente, ya se, ya se.:D
Como sabes el componente table, trae todo el contenido de un tabla a diferencia del componente query que filtra el contenido segun la sentencia sql que utilices, como bien dice el maestro vtdeleon y antes el maestro Egostar, una consulta select solo traera registros para consultar, osea verlos, en grid u otros, ahora como han dicho los maestros si la consulta sql, va a modificar una tabla, esta tendra que ser mas especifica incluso en algunos casos tomar en cuenta las llaves, los campos enlazados ect.
En sintesis:
Consulta con query que devuelve sin modificar,
Código Delphi [-]
Query1.Close;
Query1.sql.text:= 'select * from Tabla';
Query1.open;
Modificar o en tu caso borrar, ojo teniendo en cuenta lo explicado por los maestros:
Código Delphi [-]
Query1.Close;
Query1.sql.text:= 'Delete * from Tabla';
Query1.open;// si se quieren valores de regreso
Query1.ExecSQL;// si nada mas se quiere actualizar
Hago enfasis en que son dos query diferentes osea si usas el mismo programa para ver y borrar usas dos query o tambien puedes usar el text como en este caso, a esto tendrias que hacer un open denuevo.
Bueno, creo que mas o menos es asi, recuerden que soy novato y nada mas trato de ayudar, bueno con poca experiencia:D .
saludos

roman 28-04-2007 05:49:30

Hola,

Si los datos provienen de una sóla tabla, no es necesario usar un objeto TUpdateSQL, sino que basta poner RequestLive en true. En Paradox ni siquiera es necesario que la consulta incluya un campo llave pero imagino que dependiendo de la base que se use, pueda serlo.

Da la impresión de que el compañero mjjj no ha puesto RequestLive en true pero si CachedUpdates, por ello el registro se borra localmente (en el caché), pero no en la tabla porque no aplica ApplyUpdates. Claro que si lo aplica, y RequestLive sigue en false, le marcará el mismo error al momento de hacerlo.

Como yo veo las cosas- que no significa que esté bien, UpdateSQL es necesario sólo cuando de la consulta SELECT no es posible identificar unívocamente a cada registro y por tanto tiene uno que "ayudar" poniendo explícitamente la condición que lo identifique (en el UpdatSQL en este caso).

// Saludos

egostar 29-04-2007 19:19:30

Hola

Pues veo que todos los dias se aprende algo, yo siempre pense que un Query solo podia ser editable si se usaba el UpDateSQL.

Pues nada, poniendo la propiedad RequestLive a True y CachedUpdates en False, pude insertar, borrar y modificar en un Query como si fuese un objeto TTable y sin usar el objeto UpdateSQL por supuesto.

Sin complicaciones roman nos ha dado una buena lección.

Creo que debo ponerme a leer mas la ayuda de delphi :D.

Salud OS.

roman 30-04-2007 00:25:11

Ya ves, lo que uno hace por evitar usar el UpdateSQL :D

Es que, ya en serio, yo al menos, no entiendo que se ponga este ejemplo en la ayuda de Delphi:

InsertSQL:
Código SQL [-]
INSERT INTO "Country.db"
(Name, Capital, Continent)
VALUES (:Name, :Capital, :Continent)
WHERE :OLD_Name = "Rangoon"

// Saludos

mjjj 02-05-2007 18:39:44

amigos... no he podido solucionar mi problema, lo expondre nuevamente

tengo un query que hace una busqueda... select * from load.db where prensa = 'NA' ... los resultados aparecen en un dbgrid asociado.

desde el dbgrid selecciono con el mouse (un click) el registro que quiero borrar... luego al apretar un boton llamado (borrar OT), quiero que el registro seleccionado se borre...

eso por un lado, el otro tema que me desvela es semejante al anterior, solo que en vez de eliminar el registro lo quiero modificar en cierto campo especifico

tengo la propiedad del query requestlive en true, y no funciona

nose como hacerlo... se que han trato de ayudarme, espero el ultimo espujon para terminar este tema

gracias

vtdeleon 02-05-2007 19:41:30

Ya qeu intentaste lo del RequestLive, instantaste lo del SQLUpdate?'

Saludos

roman 02-05-2007 20:19:54

¿Y la propiedad CachedUpdates? Porque, sobre todo siendo paradox, una consulta así debe sí o sí, ser editable.

// Saludos

egostar 02-05-2007 20:40:07

En el ejemplo que comente anteriormente

Cita:

Empezado por YO MISMO
Pues nada, poniendo la propiedad RequestLive a True y CachedUpdates en False, pude insertar, borrar y modificar en un Query como si fuese un objeto TTable y sin usar el objeto UpdateSQL por supuesto.

Si CachedUpdates lo pongo en True me da un error que dice

Cita:

Table is not Index
La tabla que uso no tiene indices debido al comentario de mjjj

Cita:

Empezado por mjjj
a ver, voy a tratar de ser mas claro....

estoy usando tablas paradox, sin KEY,..............

La pongo en False y hace bien todo, Insertar, Borrar y Modificar.

Para borrar en un bóton puse lo siguiente:

Código Delphi [-]
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
  Query1.Delete;
end;

Pues todo funciona bien, lo que pienso es que hay algo en las propiedades del DbGrid que no esta funcionando correctamente.

Checa que las en la propiedad Options del DbGrid tanga esto:

Cita:

dgEditing = True
dgRowSelect = False
Salud OS.

roman 02-05-2007 20:57:04

A todo esto, ¿has examinado la propiedad CanModify del Query una vez abierto?

// Saludos

egostar 02-05-2007 21:04:39

Cita:

Empezado por roman
A todo esto, ¿has examinado la propiedad CanModify del Query una vez abierto?

// Saludos

En el evento AfterOpen del Query puse esto

Código Delphi [-]
  
procedure TForm1.Query1AfterOpen(DataSet: TDataSet);
begin
  If Query1.CanModify = true then begin
     ShowMessage('Can Modify es True');
  end
  else ShowMessage('Can Modify es False');
end;

Y si, me pone CanModify en True.

Salud OS.

roman 02-05-2007 21:10:33

Je, je, hola egostar. En realidad le preguntaba a mjjj. No es que te quiera hacer el feo pero ya veo que a ti te funciona correctamente :)

// Saludos

egostar 02-05-2007 21:14:17

:D:D:DAh bueno, solo que sea por eso......

Pues bien, que valga el post para que haga la prueba y te conteste.

Salud OS.

Caral 02-05-2007 21:30:26

Hola
Para mi sigue radicando en el uso de un solo query:
Cita:

select * from load.db where prensa = 'NA'
Este muestra los valores en el dbgrid segun nuestro amigo mjjj, pero no explica que sentencia usa en la ejecucion del otro query, para mi que debe borrar en la tabla, si trata de borrar con la primera sentencia por mas RequestLive en true le dira que no puede actualizar, por que esta haciendo un filtro, (quien sabe de que datos), sin envargo con dos query se ve la diferencia, es mas yo lo haria con tres asi:
primer query1, selecciono toda la tabla:
Código Delphi [-]
Query1.Close;
Query1.sql.text:= 'select * from load.db';
Query1.open;
Segundo query3, Filtro para el dbgrid:
Código Delphi [-]
Query2.Close;
Query2.sql.text:= 'select * from load.db where prensa = 'NA'';
Query2.open;
Tercer query3, borro o lo que quiera:
Código Delphi [-]
Query3.Close;
Query3.sql.text:= 'Delete * from load.db where prensa = '+Query1prensa.AsString;;
Query3.open;// si se quieren valores de regreso
Query3.ExecSQL;// si nada mas se quiere actualizar
Puede ser que me equivoque, es mas como novato es muy probable, pero cosas como esta ya he hecho y funcionan.
Saludos

egostar 02-05-2007 22:02:06

Cita:

Empezado por Caral
Hola

Para mi sigue radicando en el uso de un solo query:

Este muestra los valores en el dbgrid segun nuestro amigo mjjj, pero no explica que sentencia usa en la ejecucion del otro query, para mi que debe borrar en la tabla, si trata de borrar con la primera sentencia por mas RequestLive en true le dira que no puede actualizar, por que esta haciendo un filtro, (quien sabe de que datos), sin envargo con dos query se ve la diferencia, es mas yo lo haria con tres.......

Pues no amigo Caral, si se puede hacer con un solo query, de hecho lo estoy haciendo yo, mi consulta es esta.

Código SQL [-]
select * from llamadaH
where prefijo = '00'

Pero bueno, esperemos que que nuestro amigo mjjj nos responda.

Salud OS.

Caral 02-05-2007 22:08:46

Hola egostar
No me digas no, asi nada mas, suena muy mal, me estas poniendo mal parado entre mis admiradores.:D
La verdad, se puede de muchas formas, de eso estoy seguro, pero si haces una tabla con pocos campos los que te convengan y haces una prueba, seguro que te sale bien, ya que conoces como y donde metistes los datos de los campos etc.
Cuando hacen por aqui una pregunta tan dificil, y por que dificil, porque se desconoce practicamente todo, pues uno supone de mas.:D
Maestro, definitivamente estoy aprendiendo.:)
Saludos

egostar 02-05-2007 22:18:22

Cita:

Empezado por Caral
Hola egostar
No me digas no, asi nada mas, suena muy mal, me estas poniendo mal parado entre mis admiradores.:D
La verdad, se puede de muchas formas, de eso estoy seguro, pero si haces una tabla con pocos campos los que te convengan y haces una prueba, seguro que te sale bien, ya que conoces como y donde metistes los datos de los campos etc.
Cuando hacen por aqui una pregunta tan dificil, y por que dificil, porque se desconoce practicamente todo, pues uno supone de mas.:D
Maestro, definitivamente estoy aprendiendo.:)
Saludos

:D:D:D,

Bueno, si te parece bien lo pongo de esta manera.

Amigo Caral, yo si pude hacerlo con un solo query......

Vamos, que te invito un buen trago en la Taberna para enmendar mi error:)

Salud OS.

Caral 02-05-2007 22:25:18

Hola
Ves que bien he vuelto a ser respetado en mi grupo de admiradores.:D
Vamos, pero esta ronda la invito yo.:D
Saludos Maestro.

snowlis 11-05-2007 21:49:09

He probado con el requestlive y todo lo que decis y funciona pero con un pero.

Solo funciona si el dbgrid coge los datos de una consulta en la que solo lees datos de una tabla.

El problema viene si intentas modificar los registros de un dbgrid que coge el resultado de una query en la que utilizas varias tablas.

Ahí ya no te deja modificar nada, en cambio si son datos solo de una tabla no hay problema.

Hay solución para esto ?

roman 11-05-2007 22:01:17

Cita:

Empezado por snowlis
Hay solución para esto ?

Desde luego. Para esos casos más complejos es que se usa el objeto UpdateSQL, ya mencionado en este hilo. Básicamente, en ese objeto especificas las sentencias SQL necesarias para modificar, borrar o insertar un registro.

// Saludos

snowlis 11-05-2007 22:13:28

Puedes especificar un poco más o ponerme un código de ejemplo para que vea como sería.

Por ejemplo si mostraras en un dbgrid una consulta de este tipo :

select campo1,campo2,campo3,campo4 from tabla1,tabla2 where campo1=edit1.text

Una vez te sale la consulta en el dbgrid, como harías para que te dejará modificar cualquier registro del resultado y se quedará guardado ?

roman 11-05-2007 23:22:03

Para empezar, difícilmente pondría una consulta así pues no hay ninguna condición que relacione ambas tablas.

Ahora, debes tener en claro qué es lo que quieres hacer. Porque al decir que quieres modificar un registro y guardarlo puede parecer obvio cuál es el objetivo, pero, ¿un registro de dónde? Los datos provienen de dos (o más) tablas y sólamente puedes hacer un UPDATE, DELETE o INSERT de una de ellas.

Vamos a ver un ejemplo concreto. Tengo tablas de alumnos, grupos y las inscripciones de los primeros en los segundos:

alumno = (id, nombre)
grupo = (id, clave, salon, creditos)
inscripcion = (alumno_id, grupo_id, calificacion)

Para presentar una lista de los alumnos de un grupo dado, a fin de que el maestro pueda asentar calificaciones, uso esta consulta SQL

Código SQL [-]
select alumno.id, grupo.id, alumno.nombre, inscripcion.calificacion
from alumno
left join alumno on alumno.id = inscripcion.alumno_id
where inscripcion.grupo_id = :grupo_id
order by alumno.nombre

En este caso, me interesa poder actualizar el campo calificacion, es decir, quiero actualizar la tabla de inscripciones.

Puedes entonce usar la propiedad ModifySQL de un objeto UpdateSQL conectado a tu Query, poniendo la siguiente sentencia:

Código SQL [-]
update inscripcion
set calificacion = :calificacion
where
  alumno_id = :OLD_alumno_id and
  grupo_id = :OLD_grupo_id

En esta consulta hay tres parámetros: calificacion, OLD_alumno_id y OLD_grupo_id.

Si esta fuese una consulta independiente, tendríamos que sustituir el parámetro calificación antes de ejecutar la consulta, y asímismo proporcionar los valores de los otros parámetros para indicar cuál es el registro que deseamos modificar.

El mecanismo de los objetos UpdateSQL nos facilitan esto, rellenando en automático los parámetros que coincidan con nombres de campos en la consulta SELECT (calificacion en este caso), proveyendo los valores que vengan del control de edición. Y otro lado, hacen uso de parámetros especiales OLD_, que contienen los valores de los campos indicados, tal y como venían de la consulta SELECT. En el ejemplo, OLD_alumno_id y OLD_grupo_id serán llenados en automático, por los valores de los campos alumno_id y grupo_id que originalmente venían con los datos.

Esto quiere decir entonces, que tu consulta SELECT debe necesariamente incluir los campos necesarios para identificar al registro que se va a modificar (o borrar en el caso de DeleteSQL), aun y cuando tales campos no los muestres al usuario.

// Saludos

snowlis 13-05-2007 22:23:15

Ok, ahora lo tengo un poquito más claro, pero lo he probado y no funciona.
La consulta sql que yo muestro en el dbgrid exactamente es la siguiente :

Código SQL [-]
Select CONCEPTO,DESCR,UNID,PRECI,BONIF FROM MAEVALO1 INNER JOIN MAEDSCR1 ON MAEVALO1.CONCEPTO=MAEDSCR1.CLAVE WHERE MAEVALO1.OBRA="'+edit1.Text+'"

Lo que quiero es que cualquier regilla del dbgrid una vez que se muestre la consulta sea modificable y que al insertar un nuevo valor este se quede guardado.

He conectado un objeto updatesql a la query y he probado con la propiedad modify tal y como dice roman, pero no consigo que me funcione.

Podrías decirme cual es la consulta que tendría que poner en la propiedad modify para que pudiera editarlo todo ?

Pedro-Juan 14-05-2007 23:37:28

Posible solución
 
Hola a tod@s

Por el comentario que ha hecho mjjj, "pero al hacer un nueva busqueda este vuelve a aparecer", deduzco que lo que quiere es eliminarlo definitivamente, o sea, eliminarlo de la tabla.
Yo he hecho algo parecido a esto en mis aplicaciones, espero que te ayude:
Código Delphi [-]
var cVarCampo: String; //puede ser cualquier otro tipo que esté indexado
 
//El el evento OnClick del button
cVarCampo := Query.FieldByName('cCampo').AsString;
if (TABLE do Locate(cCampo',cVarCampo,[])) then
with TABLE do Delete;
else
ShowMessage('Aviso','No cuela');

Un saludo

Alejandrina 06-07-2007 17:55:11

Modificar Columna TDBGRid
 
Hola a todos...
Creo que estoy intentando hacer algo similar, pero estoy confundida. Tengo un TDBGrid asociado a un Query, y quisiera modificar solo la columna de prioridad utilizo la propiedad ReadOnly pero igual no me deja modificar...Que puedo hacer?:confused:


La franja horaria es GMT +2. Ahora son las 06:23:10.

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