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)
-   -   Consultas con TRIM (https://www.clubdelphi.com/foros/showthread.php?t=54452)

marilinspi 19-03-2008 12:52:56

Consultas con TRIM
 
hola a todos, les cuento tengo una base de datos Firebird y lenguaje Delphi 7, tengo una tabla camiones y otra acoplados cada una con un campo Patente, lo que necesito es que al cargar un nuevo camion o acoplado no me deje repetir la patente, pero el tema es que la patente entre las letras y los numeros hay un espacio por lo que necesito quitarlo para poder comparar, no se si me explique, pero eso lo tengo que hacer mediante una consulta SQL y creeria que se puede hacer mediante el TRIM pero e probado y no me funciona. Espero su ayuda y desde ya muchas gracias.

RolphyReyes 19-03-2008 13:40:21

Saludos.

No dices que versión de FB tienes, pero FB 2.x tiene la función TRIM de forma nativa y funciona a la perfección; para evitar duplicidad pon el (o los) campo(s) UNIQUE o PK y así te FB te mandara una excepción en caso de que se trate de duplicar.

Si TRIM no funciona piensa entonces en hacer una UDF.

Hasta luego.

marilinspi 19-03-2008 15:29:41

hola, utilizo la version 1.5 de Firebird, y quisiera que me ejemplifiques como lo haces vos, para poder comparar. Gracias desde ya

duilioisola 19-03-2008 17:27:31

Yo que vos lo haría la comprobación de que la patente tenga el formato correcto (sin espacios) antes de grabarlo en la base de datos. Esto se hace desde Delphi en el BeforePost.

Ejemplo:

Código Delphi [-]
procedure TDataModule.TCamionBeforePost(DataSet: TDataSet);
var 
   i : integer;
   s : string;
begin
  {Inicializo s. La utilizo como temporal para quitar espacios}
  s := '';
  {solo compruebo si estoy insertando}
  if (DataSet.State = dsInsert) then 
     {si hay un espacio dentro de PATENTE entonces pos > 0}
     if (pos(' ',TCamionPATENTE.AsString)>0) then
     begin
        {Recorro PATENTE caracter a caracter}
        for i := 1 to Length(TCamionPATENTE.AsString) do 
           {Si no es espacio agrego el caracter a s, por lo tanto los espacios no pasan}
           if (TCamionPATENTE.AsString[i]<>' ') then
              s := s + TCamionPATENTE.AsString[i];
           {Ahora que s no tiene espacios la utilizo como PATENTE}
           TCamionPATENTE.AsString := s;
     end;
end;

duilioisola 19-03-2008 17:32:55

Tembién podrías pasar toda la patente a mayúsculas, para evitar duplicados
B1234567 no es igual a b1234567

Código Delphi [-]
procedure TDataModule.TCamionBeforePost(DataSet: TDataSet);
var 
   i : integer;
   s : string;
begin
  {Inicializo s. La utilizo como temporal para quitar espacios}
  s := '';
  {solo compruebo si estoy insertando}
  if (DataSet.State = dsInsert) then 
     {si hay un espacio dentro de PATENTE entonces pos > 0}
     if (pos(' ',TCamionPATENTE.AsString)>0) then
     begin
        {Recorro PATENTE caracter a caracter}
        for i := 1 to Length(TCamionPATENTE.AsString) do 
           {Si no es espacio agrego el caracter a s, por lo tanto los espacios no pasan}
           if (TCamionPATENTE.AsString[i]<>' ') then
              s := s + TCamionPATENTE.AsString[i];
           {Ahora que s no tiene espacios la utilizo como PATENTE}
           TCamionPATENTE.AsString := UpperCase(s);
     end;
end;

RONPABLO 19-03-2008 18:50:58

Firebird 1.5 no tiene el trim de forma nativa, para usarlo se tiene que definir una udf (o dos creo yo) que son


Código SQL [-]
DECLARE EXTERNAL FUNCTION ltrim 
    CSTRING(80)
    RETURNS CSTRING(80) FREE_IT
    ENTRY_POINT 'IB_UDF_ltrim' MODULE_NAME 'ib_udf';

DECLARE EXTERNAL FUNCTION rtrim 
    CSTRING(80)
    RETURNS CSTRING(80) FREE_IT
    ENTRY_POINT 'IB_UDF_rtrim' MODULE_NAME 'ib_udf';


despues de declarar las anteriores udfs puede hacer un query similar a:
Código SQL [-]

select ltrim(rtrim(campoConEspacios)) as CampoSinEspacios from LaTabla

gluglu 19-03-2008 19:19:42

Cita:

... la patente entre las letras y los numeros hay un espacio ...
Sinceramente no sé exactamente si todo lo que se está comentando sobre el Trim es correcto.

Para mi Trim (o lTrim / rTrim) quita los espacios al principio y/o al final de la cadena de caracteres. Pero no los de enmedio. A lo mejor me estoy equivocando.

Por lo que la única manera que veo de solucionar el problema que plantea marilinspi es manipulando el String antes y/o después de grabarlo en la base de datos. Algo así como está exponiendo duilioisola.

En cualquier caso, propongo una solución adicional y alternativa. Yo grabo los datos en mi base de datos tanto con los espacios (y posibles caracteres especiales que puedan ser necesarios o que indique el usuario), así como en otro campo adicional de la tabla donde se hayan eliminado previamente todos esos caracteres especiales.

Y siempre realizaré la búsqueda por ese campo adicional que no contiene ningún carater especial (y teniendo en cuenta el tema del UpperCase), y por otro lado tendré siempre disponible el string original que haya introducido el usuario.

;) ;)

RONPABLO 19-03-2008 20:04:38

ups, si, el trim, ltrim o rtrim no quita espacios al interior, solo en los extremos, en Firebird se me ocurre haciendo un procedimiento almacenado con una variable Input TextoEntrada de tipo Varchar(xxx), una Auput TextoSalida de tipo Varchar(xxx) otra variable c de tipo Varchar(1)y dos variables de tipo Entero "i" "j"

Código SQL [-]
     j=1;
     i = strlen(:textoEntrada);
     while(j<=i) do
        begin
          c = substr(:textoEntrada,j,j);
          if (c <> ' ') then
             begin
                TextoSalida = TextoSalida || c;
             end
          j=j+1;
        end
     suspend;

y la puede consultar algo así como:
Código SQL [-]
select c.id, (select p.TextoSalida From Procedimiento(c.patente) p) as Pantente from Camiones


La franja horaria es GMT +2. Ahora son las 07:33:38.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi