Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Conexión con bases de datos (https://www.clubdelphi.com/foros/forumdisplay.php?f=2)
-   -   sqlquery con parametros no me funciona (https://www.clubdelphi.com/foros/showthread.php?t=91286)

identsoft 20-12-2016 14:32:18

sqlquery con parametros no me funciona
 
Este query
Código Delphi [-]
    SQLVarios.SQL.Clear;
    SQLVarios.SQL.Text := 'select count(*) as cuentas from CLIENTES ' +
                          ' where CLIENTE between :IDESDECLI and :IHASTACLI ' +
                          ' and AGENTE between :IDESDEAGEN and :IHASTAAGEN ';
    SQLVarios.ParamByName('IDESDECLI').AsInteger := StrToInt(edtDesdeCli.Text);
    SQLVarios.ParamByName('IHASTACLI').AsInteger := StrToInt(EdtHastaCli.Text);
    SQLVarios.ParamByName('IDESDEAGEN').AsInteger := StrToInt(EdtDesdeCor.Text);
    SQLVarios.ParamByName('IHASTAAGEN').AsInteger := StrToInt(edtHastaCor.Text);
    SQLVARIOS.Open;

Da resultado 0

La misma sin parametros
Código Delphi [-]
    SQLVarios.SQL.Clear;
    SQLVarios.SQL.Text := 'select count(*) as cuentas from CLIENTES ' +
                         ' where CLIENTE between ' + edtDesdecli.Text + '  and ' + edtHastaCli.Text  +
                          ' and AGENTE between ' + edtDesdeCor.Text + ' and ' + edtHastaCor.Text;
    SQLVARIOS.Open;
da resultado 1630.
Utilizo
DBExpress, BD es FireBird 2.5 entorno Delphi XE2.
¿porqué?.¿Alguien sabe que me falta, que estoy haciendo mal...?
Gracias

aposi 20-12-2016 14:39:30

Hola
Los campos cliente y agente son numeros o letras?
En el primero lo estas pasando como numeros i en el segundo como texto

Prueba de esta manera:
Código Delphi [-]
 SQLVarios.SQL.Clear;
     SQLVarios.SQL.Text := 'select count(*) as cuentas from CLIENTES ' +
                           ' where CLIENTE between :IDESDECLI and :IHASTACLI ' +
                           ' and AGENTE between :IDESDEAGEN and :IHASTAAGEN ';
     SQLVarios.ParamByName('IDESDECLI').AsString := edtDesdeCli.Text;
     SQLVarios.ParamByName('IHASTACLI').AsString := EdtHastaCli.Text;
     SQLVarios.ParamByName('IDESDEAGEN').AsString := EdtDesdeCor.Text;
     SQLVarios.ParamByName('IHASTAAGEN').AsString := edtHastaCor.Text;
     SQLVARIOS.Open;

identsoft 20-12-2016 14:51:39

los campos de la base de datos son numeros(integer), por tanto los parametros tienen que ser integer.

Casimiro Notevi 20-12-2016 18:10:39

Cita:

Empezado por identsoft (Mensaje 511901)
los campos de la base de datos son numeros(integer), por tanto los parametros tienen que ser integer.

Entonces en el caso que te funciona, no debería funcionar. Y viceversa :)

identsoft 20-12-2016 18:31:31

Cita:

Empezado por Casimiro Notevi (Mensaje 511904)
Entonces en el caso que te funciona, no debería funcionar. Y viceversa :)

Porqué?.
Si los campos son numericos, el parametro debe ser numérico (por eso parambyname().asInteger) y le asigno el valor que viene de un editText reconvertido a integer(strtoint(editText)).
En el segundo caso, a un query.text le asigno los mismos valores de un editText sin entrecomillar(sin QuotedStr, que seria el caso de asignar un string ).
Creo que es así como se hace, pero puedo estar equivocado.

Casimiro Notevi 20-12-2016 19:22:32

¿Seguro que son integer en la base de datos?

identsoft 20-12-2016 19:38:20

Cita:

Empezado por Casimiro Notevi (Mensaje 511907)
¿Seguro que son integer en la base de datos?

En el primer caso (CLIENTE) si, en el segundo caso (AGENTE) es un smallint( lo he visto ahora). Pero he corregido el primer query
Código Delphi [-]
    SQLVarios.SQL.Text := 'select count(*) as cuentas from CLIENTES ' +
                          ' where CLIENTE between :IDESDECLI and :IHASTACLI ' +
                          ' and AGENTE between :IDESDEAGEN and :IHASTAAGEN ';
    SQLVarios.ParamByName('IDESDECLI').AsInteger := StrToInt(edtDesdeCli.Text);
    SQLVarios.ParamByName('IHASTACLI').AsInteger := StrToInt(EdtHastaCli.Text);
    SQLVarios.ParamByName('IDESDEAGEN').AsSmallInt := StrToInt(EdtDesdeCor.Text);
    SQLVarios.ParamByName('IHASTAAGEN').AsSmallInt := StrToInt(edtHastaCor.Text)
y sigue saliendo 0

AgustinOrtu 20-12-2016 22:17:48

Proba poniendole literales directamente en los parametros. Para descartar problemas de conversion por configuracion regional por ejemplo

Código Delphi [-]
    SQLVarios.ParamByName('IDESDECLI').AsInteger := 1;
    SQLVarios.ParamByName('IHASTACLI').AsInteger := 50;
    SQLVarios.ParamByName('IDESDEAGEN').AsSmallInt := 1;
    SQLVarios.ParamByName('IHASTAAGEN').AsSmallInt := 100;

Obviamente con valores relevantes al dominio

fjcg02 21-12-2016 10:19:30

Hay una cosa que no entiendo.

si creas la consulta "al vuelo", porqué utilizas parámetros?

Creala en tiempo de diseño y carga los parámetros en tiempo de ejecución.

Creo que también puedes o debes hacer Query.Prepare para que los parámetros los tome correctamente. Creo que van por ahí los tiros, pero no puedo mirarlo ahora.

Saludos

identsoft 21-12-2016 10:29:25

Gracias a todos.
Ya está solucionado.
Os explico: el campo AGENTE es un smallint. A los parámetros les cargo el valor que vienen de un TEDIT. El problema viene porque desde el TEDIT HASTAGEN venía un valor mayor que el máximo valor de un smallint(32767).El valor del TEDIT se asigna al parámetro correspondiente, el cual no da ningun tipo de error, pero no hace nada. Por eso salia 0. Controlando el máximo valor del tedit HASTAAGEN, problema solucionado.
De nuevo gracias a todos.

Casimiro Notevi 21-12-2016 11:53:32

Entonces no podía funcionar ni con parámetros ni sin parámetros :confused:

identsoft 21-12-2016 12:09:53

Cita:

Empezado por Casimiro Notevi (Mensaje 511934)
Entonces no podía funcionar ni con parámetros ni sin parámetros :confused:

pues sin parámetros funcionaba, por lo menos en mi caso.

roman 21-12-2016 16:11:25

Cita:

Empezado por Casimiro Notevi (Mensaje 511934)
Entonces no podía funcionar ni con parámetros ni sin parámetros :confused:

No necesariamente. El parámetro en cuestión no se asignaba a un campo (el motor de datos habría indicado el error) sino al límite superior de un between. Una consulta del tipo

Código SQL [-]
select * from tabla where campo between 1 and 32000

al menos en MySQL, funciona bien aunque campo sea de un tipo entero pequeño, y es lógico que funcione pues no hay ninguna infracción al rango del campo. Habría que ver qué es lo que hace Delphi con el valor del parámetro cuando excede el rango. (Quizá lo ajusta a -1)

LineComment Saludos

Casimiro Notevi 21-12-2016 17:16:29

Entonces ese era el problema con parámetros lo convertía en -1 y sin parámetros le asignaba correctamente el número mayor de 32000

olbeup 22-12-2016 10:03:09

Cuando un SmallInt excede del valor que puede almacenar, puede tener dos estados (Positivo o Nevativo)

SmallInt = Valor que se le pasa originalmente - (32767 * 2) - 2

eje:
Código Delphi [-]
var
  a: Integer;
  b: SmallInt;
begin
  a := 86000;
  b := a;
  ShowMessage(Format('a = %d, b = %d', [a, b]));
end;
Resultado es: a = 36000, b = -29536
Resultado es: a = 86000, b = -20464

Un saludo.

olbeup 22-12-2016 11:22:48

Perdón, esto de copiar y pegar, pasa lo que pasa.

Resultado es: a = 86000, b = 20464

Un saludo.


La franja horaria es GMT +2. Ahora son las 16:31:55.

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