Ir al contenido



Foto

Mensaje Conflicto entre tablas, Migración Query a ADOQuery

adoquery mysql delphi

  • Por favor identifícate para responder
47 respuestas en este tema

#41 Koalasoft

Koalasoft

    Advanced Member

  • Miembros
  • PipPipPip
  • 78 mensajes
  • LocationMéxico

Escrito 01 febrero 2017 - 10:19

 
Pues así de fácil amigo
 

 


delphi
  1.    Close;
  2.    SQL.Clear;
  3.    SQL.Add('SELECT * FROM CTRLONT CTRL ');
  4.    SQL.Add('join CLIENTES CL on CTRL.FOLIO = CL.FOLIO ');
  5.    SQL.Add('join ONTs ONT on CTRL.FOLIO = ONT.Folio ');
  6.    SQL.Add('WHERE CTRL.BOARD_ONT = ' + Edit1.Text);
  7.    SQL.Add(' AND CTRL.FRAME_ID = ' + Edit2.Text);
  8.    SQL.Add(' AND CTRL.SLOT_ID = ' + Edit3.Text);
  9.    SQL.Add(' AND CTRL.PORT_ID = ' + Edit4.Text);
  10.    SQL.Add(' AND CTRL.ONT_ID = ' + Edit1.Text);
  11.    Open;

 
Saludos

 

 

 

hooo!!.. ok ok bueno al menos asi se ahorra una lineas mas de código, muchas gracias por la aclaración !! .. lo que si veo que si hay diferencias entre los componentes Qeury y ADOQuery significativos al menos para esto de los parámetros.


  • 0

#42 Koalasoft

Koalasoft

    Advanced Member

  • Miembros
  • PipPipPip
  • 78 mensajes
  • LocationMéxico

Escrito 01 febrero 2017 - 10:22

Pregunta: ¿Agregaste campos persistentes en el componente?

 

 

Duda: Si ya tienes en el componente la consulta, porque no la usas completa con los parámetros que requiere y en "runtime" solo asignas los parámetros. (Sigo insistiendo)

 

 

Reto: Como dice nuestro buen amigo Agustín, ya me dió curiosidad porque no funciona, pero para ello necesitamos contar con tu ambiente de trabajo, de otra forma todo queda en especulaciones. :(

 

 

Saludos

 

 

 

Pregunta: ¿Agregaste campos persistentes en el componente?

 

Si al decir persistente te refieres a los que se colocan en el parámetro SQL en tiempo de diseño, solo tengo lo siguiente:


sql
  1. SELECT * FROM CTRLONT

 

 

Duda: Si ya tienes en el componente la consulta, porque no la usas completa con los parámetros que requiere y en "runtime" solo asignas los parámetros. (Sigo insistiendo)

 

Me podrías dar un ejemplo y lo checamos, pues de esa forma no lo he hecho antes.

 

 

 

Reto: Como dice nuestro buen amigo Agustín, ya me dió curiosidad porque no funciona, pero para ello necesitamos contar con tu ambiente de trabajo, de otra forma todo queda en especulaciones.

 

Con todo gusto asi todos nos sacamos de duda!! .. gracias . 


  • 0

#43 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.890 mensajes
  • LocationArgentina

Escrito 01 febrero 2017 - 12:17

Explico sobre los campos persistentes.

 

Se obtienen en tiempo de diseño:

 

1. Agregas un ADOQuery a tu form o DataModule.

2. Configuras la conexión.

3. haces clic en la propiedad SQL y se la escribes.

4. Luego en el inspector de objetos (también puede hacerse desde el menú contextual del ADOQuery al hacer clic en él con el botón secundario) les agregas los campos persistentes. El "asistente" solito te detecta los campos disponibles, seleccionalos de la lista y los agregas.

 

Te van a aparecer en el inspector de objetos los campos. Luego cuando deseas invocarlos, por código, simplemente los llamas por su nombre. Por defecto Delphi les pone el nombre así:

NombreDelDataSet + NombreDelCampo

 

Este mismo principio se puede aplicar para los parámetros.

 

Como su nombre lo indica, al ser persistentes están disponibles en todo momento. A ese Query ya no se lo puede reutilizar. Un Close no va a eliminar los campos (ni parámetros) que ya tenía. Por ello yo decía que no hay que hacer esa mezcla.

 

De lo que he leído no me claro si realmente al ADOQuery en cuestión lo tienes en el form (lo que es definirlo en tiempo de diseño) o si efectivamente TU lo CREAS en tiempo de ejecución. Esto es una creación en runtime o tiempo de ejecución:


delphi
  1. MiQuery := TADOQuery.Create;
  2. MiQuery.Database := '...'; // No recuerdo bien si era así la propiedad.
  3. MiQuery.UserName := '...';
  4. MiQuery.Password := '...';
  5. // Otras propiedades de interés...
  6.  
  7. MiQuery.SQL := 'SELECT ... ';
  8. MiQuery.Open;

De lo contrario, si tu lo pones en el form o en el módulo de datos lo que estás haciendo es crearlo en tiempo de diseño.

 

Otra cosa es que uno puede definir la SQL en tiempo de diseño o en ejecución. Es legal poner el componente en tiempo de diseño y en tiempo de ejecución "configurarlo" para cada caso; eso nos permite reutilización. Yo aplico esta última.

Si se la hace en diseño, hay que tener recaudos al momento de abrir y cerrar la consulta. Sobre todo si uno va a reusar al componente para ejecutar varias instrucciones, ya que no siempre el Close liberará los parámetros y los campos.

 

Lo que puedes probar, es invocar al método Prepare después de hacer la asignación de la consulta SQL y antes pasarle los datos a los parámetros.

 

Ya somos varios los que tenemos curiosidad de porqué no te funciona. Tiene que andar... hay alguna metida de dedo seguro.

 

Saludos,


  • 1

#44 Koalasoft

Koalasoft

    Advanced Member

  • Miembros
  • PipPipPip
  • 78 mensajes
  • LocationMéxico

Escrito 01 febrero 2017 - 12:42

Explico sobre los campos persistentes.

 

Se obtienen en tiempo de diseño:

 

1. Agregas un ADOQuery a tu form o DataModule.

2. Configuras la conexión.

3. haces clic en la propiedad SQL y se la escribes.

4. Luego en el inspector de objetos (también puede hacerse desde el menú contextual del ADOQuery al hacer clic en él con el botón secundario) les agregas los campos persistentes. El "asistente" solito te detecta los campos disponibles, seleccionalos de la lista y los agregas.

 

Te van a aparecer en el inspector de objetos los campos. Luego cuando deseas invocarlos, por código, simplemente los llamas por su nombre. Por defecto Delphi les pone el nombre así:

NombreDelDataSet + NombreDelCampo

 

Este mismo principio se puede aplicar para los parámetros.

 

Como su nombre lo indica, al ser persistentes están disponibles en todo momento. A ese Query ya no se lo puede reutilizar. Un Close no va a eliminar los campos (ni parámetros) que ya tenía. Por ello yo decía que no hay que hacer esa mezcla.

 

De lo que he leído no me claro si realmente al ADOQuery en cuestión lo tienes en el form (lo que es definirlo en tiempo de diseño) o si efectivamente TU lo CREAS en tiempo de ejecución. Esto es una creación en runtime o tiempo de ejecución:


delphi
  1. MiQuery := TADOQuery.Create;
  2. MiQuery.Database := '...'; // No recuerdo bien si era así la propiedad.
  3. MiQuery.UserName := '...';
  4. MiQuery.Password := '...';
  5. // Otras propiedades de interés...
  6.  
  7. MiQuery.SQL := 'SELECT ... ';
  8. MiQuery.Open;

De lo contrario, si tu lo pones en el form o en el módulo de datos lo que estás haciendo es crearlo en tiempo de diseño.

 

Otra cosa es que uno puede definir la SQL en tiempo de diseño o en ejecución. Es legal poner el componente en tiempo de diseño y en tiempo de ejecución "configurarlo" para cada caso; eso nos permite reutilización. Yo aplico esta última.

Si se la hace en diseño, hay que tener recaudos al momento de abrir y cerrar la consulta. Sobre todo si uno va a reusar al componente para ejecutar varias instrucciones, ya que no siempre el Close liberará los parámetros y los campos.

 

Lo que puedes probar, es invocar al método Prepare después de hacer la asignación de la consulta SQL y antes pasarle los datos a los parámetros.

 

Ya somos varios los que tenemos curiosidad de porqué no te funciona. Tiene que andar... hay alguna metida de dedo seguro.

 

Saludos,

 

Gracias por tu explicación .. te comento ... 

 

En ese caso yo uso el componente en varios casos (reutilizo) me gusta ese detalle de "reciclar" jeje .. por eso une un DataModule y de alli tengo los componentes ADOQuery cada uno con sus respectivas tablas ... la hacerle llamado las uso para dar de alta, baja, etc, y claro consultas, por eso en tiempo de ejecución lo que hago es rescribir la sentencia SQL nada mas, no uso campos persistentes por lo mismo, ya que el componente lo uso en diferentes formularios. En resumen las consultas y el componente es usado en tiempo de diseño, no los creo. (no domino bien esa parte todavia).

 

Saludos !! 


  • 0

#45 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 744 mensajes
  • LocationArgentina

Escrito 01 febrero 2017 - 04:25

Yo soy de la otra escuela. Prefiero hacer TODO por codigo, por el sencillo motivo de que no podes hacer todo en tiempo de diseño; siempre habra algo de codigo. Eso crea confusion (tenes que controlar por un lado codigo y por otro lado la configuracion de componentes) Y ademas, para no tener que andar preocupandome con "como estaba el query antes" siempre prefiero crear un query nuevo. El costo de crear un objeto query es minimo. El verdadero costo esta en la invocacion a Open que de todos modos va a estar siempre

 

El unico caso en el que reutilizo queries es porque ejecuto una y otra ves la misma consulta cambiando parametros. Eso se conoce como "sentencias preparadas". Pero una vez que asigno el SQL no lo toco mas y lo unico que cambio son valores de parametros

 

En realidad esta forma de trabajo la empleo para todo, no solo query. Es mucho mas facil porque si varios modulos utilizan el mismo objeto, varios modulos pueden cambiarlo y dejarlo en un estado que no te esperas. Si lo creas, al momento de la creacion ya se sabe cual es el estado, y si ademas explicitamente estas diciendo lo que va a hacer el query, mejor. Explicito es mejor que implicito


  • 0

#46 Delphius

Delphius

    Advanced Member

  • Administrador
  • 5.890 mensajes
  • LocationArgentina

Escrito 01 febrero 2017 - 05:17

Bueno. Vamos a tratar de ir a por el problema.

Tu nos dijiste el texto del error en español. Te agradecería que nos pases el texto de todo el error textual. Puedes copiarlo con el Ctrl+C de siempre. Cuando aparezca el cartel de la excepción lo copias.

 

Saber la excepción, nos puede ayudar a determinar el problema desde otra perspectiva. Ya sabemos que te lo da al momento de invocar a parámetros en en WHERE. Yo tengo la teoría de algún conflicto con parámetros "sucios", y Agustín también piensa lo mismo.

 

Según recuerdo haber leído dices que Paramaters no tiene la propiedad Count, que no te la reconoce, me cuesta creer que no tenga eso. Revisa porque seguro que la tiene.

Hasta donde yo recuerdo, tanto TParams (la clase que tienen las otras suites de componentes de conexión de base de datos) como TParameters (la clase propia de ADO) heredan de TColletion. Y esta clase tiene la propiedad Count que devuelve la cantidad de TColletionItem que lo componen.

 

De última, si es que estoy equivocado, y si no se llama Count se llamará ParamatersCount o similar. Pero de que deberías poder saber la cantidad es seguro. Fíjate entre la lista de propiedades y métodos.

 

El código de Agustin de hace unos cuantos post te tiene que mostrar la lista. De última, comenta la línea que lee la propiedad DataType... El access violation se debe seguramente a algo que difiere en la implementación RTTI entre las versiones de Delphi que usas y la que tiene Agustín.

 

Básicamente su propuesta es explorar la lista de parámetros para ver si hay algo "sucio" ahí. Haz esa prueba. No sólo copia el código, entiéndelo y si es necesario cambialo para adaptarlo a la versión de Delphi que tu usas (Aunque es mur raro que debas cambiar algo)

 

Deberás publicar todo el código que afecte justamente a ese Query. Brinda detalles más específicos. Es muy importante saber si en algún evento del Query haces algo que pudiera afectarlo. En algún lado esta el gato encerrado y necesitamos liberarlo.

 

Saludos,


  • 0

#47 Koalasoft

Koalasoft

    Advanced Member

  • Miembros
  • PipPipPip
  • 78 mensajes
  • LocationMéxico

Escrito 01 febrero 2017 - 05:25

Yo soy de la otra escuela. Prefiero hacer TODO por codigo, por el sencillo motivo de que no podes hacer todo en tiempo de diseño; siempre habra algo de codigo. Eso crea confusion (tenes que controlar por un lado codigo y por otro lado la configuracion de componentes) Y ademas, para no tener que andar preocupandome con "como estaba el query antes" siempre prefiero crear un query nuevo. El costo de crear un objeto query es minimo. El verdadero costo esta en la invocacion a Open que de todos modos va a estar siempre

 

El unico caso en el que reutilizo queries es porque ejecuto una y otra ves la misma consulta cambiando parametros. Eso se conoce como "sentencias preparadas". Pero una vez que asigno el SQL no lo toco mas y lo unico que cambio son valores de parametros

 

En realidad esta forma de trabajo la empleo para todo, no solo query. Es mucho mas facil porque si varios modulos utilizan el mismo objeto, varios modulos pueden cambiarlo y dejarlo en un estado que no te esperas. Si lo creas, al momento de la creacion ya se sabe cual es el estado, y si ademas explicitamente estas diciendo lo que va a hacer el query, mejor. Explicito es mejor que implicito

 

Es correcto estimado nada coma la vieja escuela, todo por código asi uno puede como bien mencionó el otro compañero reutilizar el componente para varias cosas. agradezco tu acertado comentario. 

Saludos!! .. 


  • 0

#48 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 744 mensajes
  • LocationArgentina

Escrito 02 febrero 2017 - 01:22

El codigo yo lo escribi desde delphi y compila bien. ADO fue practicamente dado por obsoleto en Delphi desde hace rato y no ha recibido cambios o actualizaciones, y mucho menos que rompan la compatibilidad. Es correcto lo que comenta Marcelo, esa coleccion de parametros hereda su propiedad Count de la clase TColleciton.

 

Ademas, el codigo de abajo que realiza el for y te genera una excepcion hace uso de la misma propiedad.. asi que existe. Seguramente tengas otro error de sintaxis (cambiaste el nombre de la variable? yo le puse "qry" al TADOQuery)

 

Como siempre, cuando hay excepciones, debes copiar el codigo, la excepcion y la linea que te marca el depurador

 

Un Access Violation significa que estas usando un objeto que no fue inicializado

 

Me parece que al haber hecho copia y pega te copiaste tambien la parte del "var" con los objetos TADOQuery y TMemo que utiliza el procedimiento. Como ya demostras cierto conocimiento programando asumi que te ibas a dar cuenta que esos eran componentes ya creados y listos para usar

 

En realidad, las declaracion de las variables "qry" y "Memo1" estan de mas en ese pequeño proceso: qry se refiere como en el caso de arriba, al componente query que estas usando para ejecutar y que queremos inspeccionar su lista de parametros para ver si hay algo sucio; y Memo1 es un componente TMemo que deberia estar en el Form en donde ejecutas ese codigo. 


Editado por Agustin Ortu, 02 febrero 2017 - 01:23 .

  • 0





Etiquetado también con una o más de estas palabras: adoquery, mysql, delphi