Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Desarrollo en Delphi para Android (https://www.clubdelphi.com/foros/forumdisplay.php?f=57)
-   -   Exception Class Segmentation fault(11) en App Android (https://www.clubdelphi.com/foros/showthread.php?t=92962)

Diego E. 28-03-2018 23:04:34

Exception Class Segmentation fault(11) en App Android
 
Hola, soy nuevo en el foro. Me gustaría saber si alguien sabe como resolver la excepción mencionada anteriormente, el problema es algo específico:
Estoy intentando llenar un ComboBox con datos obtenidos a través de un query desde una BD SQL Server. Estoy probando la Aplicación tanto en Windows como en Android, en Windows todo corre de maravilla, no me sale ningún error ni nada, sin embargo al probar con Android me aparecen varios errores, el primero a resolver es el de éste ComboBox. Para hacer las transacciones con la BD estoy usando SDAC de Devart y el componente TMSQuery, el código es el siguiente.

Código Delphi [-]
Procedure CargarCombo(combo:TComboBox;Where:String);
begin

  DtmClientes.MSConnectionClientes.Connected := True;

  if DtmClientes.MSConnectionClientes.Connected = True then
  begin
    DtmClientes.MSQueryCmbPedido.SQL.Text :=  'SELECT Clientes.ID_Cliente, Clientes.Clie_Nombre, '
            +'Clientes.Clie_Apellidos FROM Clientes WHERE Clientes.[Activado]= :param1 '
            +'AND Clientes.Eliminado= :param2 '+ Where +' ORDER BY Clientes.Clie_Nombre, Clientes.Clie_Apellidos;';

    DtmClientes.MSQueryCmbPedido.Params[0].Value := True;
    DtmClientes.MSQueryCmbPedido.Params[1].Value := False;
    DtmClientes.MSQueryCmbPedido.Execute;
    DtmClientes.MSQueryCmbPedido.First;

    (combo as TComboBox).Items.Add('-Seleccione un Cliente o Agregalo');
    while not DtmClientes.MSQueryCmbPedido.Eof do
    begin
      (combo as TComboBox).Items.AddObject(DtmClientes.MSQueryCmbPedido.Fields[1].AsString + ' ' +  DtmClientes.MSQueryCmbPedido.Fields[2].AsString,
                                    TObject(DtmClientes.MSQueryCmbPedido.Fields[0].AsInteger));
      DtmClientes.MSQueryCmbPedido.Next;
    end;
  end;

  DtmClientes.MSConnectionClientes.Connected := False;

end;

Para éste caso los parámetros que recibe son:
-combo: MiForm.ComboBox;
-Where: ' ';

Este código es el mismo que uso para llenar los ListBox, ya llené dos ListBox para llegar a ese punto y ninguno lanzó error.
Para no hacerlo más largo, corre bien hasta llegar a la linea del Execute que es donde truena y aparece el error.

P.D. Al ejecutar el Query en SQL Server si me regresa los datos que necesito.

Casimiro Notevi 29-03-2018 00:48:23

Esa sentencia sql está mal.

En todo caso sobra el where de abajo:

Código Delphi [-]
    DtmClientes.MSQueryCmbPedido.SQL.Text :=  'SELECT Clientes.ID_Cliente, Clientes.Clie_Nombre, '
            +'Clientes.Clie_Apellidos FROM Clientes WHERE Clientes.[Activado]=  :param1 '
            +'AND Clientes.Eliminado= :param2 '+ Where +' ORDER BY Clientes.Clie_Nombre, Clientes.Clie_Apellidos;';
Código Delphi [-]
    DtmClientes.MSQueryCmbPedido.SQL.Text :=  'SELECT Clientes.ID_Cliente, Clientes.Clie_Nombre, '
            +'Clientes.Clie_Apellidos FROM Clientes WHERE Clientes.[Activado]= :param1 '
            +'AND Clientes.Eliminado= :param2 '+ ' ORDER BY Clientes.Clie_Nombre, Clientes.Clie_Apellidos;';

Diego E. 29-03-2018 01:39:07

Más detalles del problema
 
Hola Casimiro gracias por responder. El Where de ahi está por que ese Procedure lo utilizo para varias partes del código, en algunas de ellas debo agregar una condición adicional a la busqueda, sin embargo como para éste caso no necesito agregar una condición, le mando un espacio en blanco que no le afecta nada al Query, te comento que al correr el Query (Reemplazando los :param por el booleano indicado en el código y en lugar del where (variable) sólo un espacio) funciona a la perfección, el problema viene cuando se ejecuta dicho Procedure en Android, ya que en Windows funciona como debe, y al depurar el código es justo en la línea del Execute donde falla para Android:

Código:

DtmClientes.MSQueryCmbPedido.Execute;
La verdad no me explico de donde y cuál es el error, ya que como comento uso prácticamente el mismo código para llenar ListBox antes y no me arroja ningún error:

Código:

Procedure LlenarPlantillasMetaLB();
var
  strSQL:String;
  ID_PMeta: String;

begin

  DtmListaPedidos.MSConnectionListaPedidos.Connected:=True;

  if DtmListaPedidos.MSConnectionListaPedidos.Connected = True then
  begin
    strSQL:= 'SELECT ID FROM NtaMeta WHERE (Plataforma = :param1) AND (ID_Status = :param2)'
              +'ORDER BY NtaMeta_ID';

    DtmListaPedidos.MSQueryMetas.SQL.Text := strSQL;
    DtmListaPedidos.MSQueryMetas.Params[0].Value := 'Ambas';
    DtmListaPedidos.MSQueryMetas.Params[1].Value := 2;
    DtmListaPedidos.MSQueryMetas.Execute;
    DtmListaPedidos.MSQueryMetas.First;


    while not DtmListaPedidos.MSQueryMetas.Eof do
    begin

    ID_PMeta := DtmListaPedidos.MSQueryMetas.Fields[0].Text;

    FrmLPedidos.ListBoxTipo.Items.Add(ID_PMeta);

    DtmListaPedidos.MSQueryMetas.Next;
    end;
  end;

  DtmListaPedidos.MSConnectionListaPedidos.Connected := False;

end;

P.D. Uso Delphi Seattle y los componentes para hacer las consultas de SDAC de Devart.

Casimiro Notevi 29-03-2018 01:48:38

¿Quieres decir que ese 'where' es una variable?
Cámbiale el nombre, por ejemplo cWhere, y prueba.

Diego E. 29-03-2018 02:56:35

Cita:

Empezado por Casimiro Notevi (Mensaje 525424)
¿Quieres decir que ese 'where' es una variable?
Cámbiale el nombre, por ejemplo cWhere, y prueba.

Si, ese where es una variable.
Ya intenté cambiarle el nombre y sigue el mismo error, reemplacé el componente en el módulo, agregué directamente los parámetros y sigue sin funcionar. ¿Por cierto saben por que al correrlo en Android me convierte una variable de String a Short?

jhonny 29-03-2018 06:26:02

Hola,

Esto parece un caso típico de referencia débil hacia una instancia, hay que buscar dentro del código (haciendo debug) ¿Cuál es el objeto que Android está liberando automáticamente? y convertir dicha instancia en una referencia fuerte.

Para entender esto, recomiendo el libro de DALIJA PRASNIKAR llamado Memory Management For Classic And ARC, el cual trata precisamente este tipo de temas. Si queremos evitar este tipo de sorpresas (Ya sea que usemos Delphi o cualquier otro lenguaje) en dispositivos móviles debemos comprender dicho tema... pues los sistemas operativos móviles como Android o iOS trabajan de ese modo.

Diego E. 29-03-2018 23:54:31

Cita:

Empezado por jhonny (Mensaje 525427)
Hola,

Esto parece un caso típico de referencia débil hacia una instancia, hay que buscar dentro del código (haciendo debug) ¿Cuál es el objeto que Android está liberando automáticamente? y convertir dicha instancia en una referencia fuerte.

Gracias por la información, tengo que checar bien ese asunto por que me podría traer conflictos en el futuro. Por el momento ya logré hacerlo funcionar agregando una instrucción active antes de la de Execute, no estoy muy seguro de por que resolvió el problema pero lo hizo.

Código:

DtmClientes.MSQueryCmbPedido.Active := True;
    DtmClientes.MSQueryCmbPedido.Execute;


Neftali [Germán.Estévez] 03-04-2018 09:05:01

No he usado SDAC (los componentes que comentas), pero normalmente para una consulta tipo SELECT utilizamos un OPEN o un ACTIVE y para otro tipo de SQL's (INSERT(/DELETE/UPDATE) utilizamos un Execute.

Casimiro Notevi 03-04-2018 11:05:15

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 525454)
No he usado SDAC (los componentes que comentas), pero normalmente para una consulta tipo SELECT utilizamos un OPEN o un ACTIVE y para otro tipo de SQL's (INSERT(/DELETE/UPDATE) utilizamos un Execute.

Yo tuve que usarlo en cierta ocasión puntual y el funcionamiento era tal y como describes.

Diego E. 07-04-2018 20:47:14

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 525454)
No he usado SDAC (los componentes que comentas), pero normalmente para una consulta tipo SELECT utilizamos un OPEN o un ACTIVE y para otro tipo de SQL's (INSERT(/DELETE/UPDATE) utilizamos un Execute.

No estoy muy seguro, pero creo que active por lo que entendí es para mantener el componente activo después de que se cierra la conexión a la BD, pero en el error me funcionó, voy a intentar usar el componente ahora de ésta forma que me comentas. Gracias.


La franja horaria es GMT +2. Ahora son las 02:08:16.

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