Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Oracle »

Problema con parámetros y espacios

Estas en el tema de Problema con parámetros y espacios en el foro de Oracle en Foros del Web. Hola a tod@s He descubierto que mi aplicación truena al querer hacer una actualización con parámetros que no tienen los mismos espacios que en la ...
  #1 (permalink)  
Antiguo 30/10/2007, 14:18
 
Fecha de Ingreso: septiembre-2005
Mensajes: 73
Antigüedad: 19 años, 2 meses
Puntos: 0
Problema con parámetros y espacios

Hola a tod@s

He descubierto que mi aplicación truena al querer hacer una actualización con parámetros que no tienen los mismos espacios que en la base de datos.

Si tengo Campo1 char(10)
En mi aplicación lo guardo como Campo1="Hola", pero en la BD lo guarda como "Hola ".
Como hago esta Consulta UPDATE campos WHERE Campo1= :campo1 y campo1 lo toma de mi aplicación, es diferente del que está en la BD, por lo que me regresa un "error" de que no se actualizó ningún campo.

Al hacer la consulta en el SQLPlus y sin parámetros es lo mismo ponerle o no ponerle los espacios.... porque con los parámetros no?
Como puedo solucionar esto?

De antemano gracias.
__________________
Henry :-D
  #2 (permalink)  
Antiguo 30/10/2007, 14:56
Avatar de matanga  
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 17 años
Puntos: 85
Re: Problema con parámetros y espacios

Hola,

Aqui hay un pequeño ejemplo de como funciona esto dentro de la base de datos.

Código:
SQL> create table t10 (id number, name char(10));

Table created.

SQL> insert into t10 values (1,'Hola');

1 row created.

SQL> commit;

Commit complete.

SQL> select * from t10 where name = 'Hola';

        ID NAME
---------- ----------
         1 Hola

SQL> update t10 set id = 2 where name = 'Hola';

1 row updated.

SQL> commit;

Commit complete.

SQL> select * from t10;

        ID NAME
---------- ----------
         2 Hola


SQL> set serveroutput on;
SQL> r
  1  declare
  2  c number;
  3  v char(10);
  4  begin
  5  v:='Hola';
  6  select count(*) into c from t10 where name = v;
  7  dbms_output.put_line(c);
  8* end;
  9  /
1

PL/SQL procedure successfully completed.
Hasta aqui, todo funciona bien, pero hay que prestarle un poco de atencion a llos tipos de datos CHAR, una funcion interesante de Oracle nos dice el contenido del campo name

Código:
SQL> select dump(name) from t10;

DUMP(NAME)
--------------------------------------------------------------------------------
Typ=96 Len=10: 72,111,108,97,32,32,32,32,32,32
Fijate las 6 veces que aparece el 32, esos son los espacios en blanco que utiliza Oracle para completar la longitud hasta llegar a CHAR(10). Es decir que en este tipo de dato siempre se van a completar con espacios en blanco hasta llegar a la longitud del campo.

Desde el SQL*Plus esto no es un problema, pero para tu aplicacion parece ser que lo es, es decir que 'Hola' no es igual a 'Hola '. Intenta ver que sucede si el tipo de dato de la columna es VARCHAR2(10) o bien aplicar la funcion TRIM.

Saludos
  #3 (permalink)  
Antiguo 30/10/2007, 21:54
Avatar de kikolice  
Fecha de Ingreso: marzo-2004
Mensajes: 1.510
Antigüedad: 20 años, 8 meses
Puntos: 7
Re: Problema con parámetros y espacios

en lo personal nunca me ha gustado usar tipos de datos char precisamente por este tipo de problemas, yo recomendaria usar tipos varchar2
__________________
Blogzote.com :-) Mi blog
  #4 (permalink)  
Antiguo 31/10/2007, 08:38
Avatar de Linterns
Colaborador
 
Fecha de Ingreso: diciembre-2001
Mensajes: 2.799
Antigüedad: 22 años, 11 meses
Puntos: 11
Re: Problema con parámetros y espacios

Intenta con esta sentencia


Código PHP:
 UPDATE nombretabla 
SET Campo1
="Hola"
WHERE trim(campo1) = trim(:campo1); 
__________________
Bien se puede recibir una puñalada sin adulación,
pero rara vez se recibe una adulación sin puñalada
** ***
  #5 (permalink)  
Antiguo 31/10/2007, 09:38
 
Fecha de Ingreso: junio-2007
Mensajes: 891
Antigüedad: 17 años, 5 meses
Puntos: 43
Re: Problema con parámetros y espacios

Si la aplicacion es en forms 6i ( es con la que llevo currando los ultimos tiempos y conozco ), el TRIM no funciona.

Debes de utilizar
UPDATE nombretabla
SET Campo1="Hola"
WHERE ltrim(rtrim(campo1)) = ltrim(rtrim(:campo1));
  #6 (permalink)  
Antiguo 01/11/2007, 18:24
Avatar de matanga  
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 17 años
Puntos: 85
Re: Problema con parámetros y espacios

Hola,

Todos los dias se aprende algo nuevo, hoy me entere de como Oracle compara los tipos de datos CHAR, asi que pense en hacer la traduccion y compartirla.

Oracle compara valores CHAR usando comparacion semantica blank-padded

Código:
    
Blank-Padded      Non-Padded 
------------       ---------- 
'ab' > 'aa'        'ab' > 'aa'
'ab' > 'a '        'ab' > 'a '
'ab' > 'a'         'ab' > 'a'
'ab' = 'ab'        'ab' = 'ab'
'a ' = 'a'         'a ' > 'a'

COMPARACION SEMANTICA BLANK-PADDED

Si los dos valores tienen diferentes longitudes, Oracle primero añade espacios en blanco al final del mas corto para que sus longitudes sean iguales. Oracle compara los valores carácter por carácter hasta el primer carácter que sea distinto. El valor con el mayor carácter en la primera posición distinta se considera mayor. Si los dos valores no tienen diferentes caracteres, se los considera iguales. Esta regla significa que dos valores son iguales si sólo difieren en el número de espacios en blanco. Oracle utiliza comparación semántica blank-padded sólo si los dos valores en la comparación son CHAR DataType o son literales de texto.

Prestando mayor atencion a la ultima sentencia pregunto, es posible que el parametro :campo1 no sea del tipo CHAR?

Saludos
  #7 (permalink)  
Antiguo 01/11/2007, 18:33
Avatar de matanga  
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 17 años
Puntos: 85
Re: Problema con parámetros y espacios

Hola,

Me olvide de publicar el caso de prueba :(

Código:
SQL> create table t10 (id number, nombre char(10));

Table created.

SQL> insert into t10 values (1,'Hola      ');

1 row created.

SQL> commit;

Commit complete.

SQL> r
  1  declare
  2  c number;
  3  v varchar2(10);
  4  begin
  5  v:='Hola  ';
  6  select count(*) into c from t10 where nombre = v;
  7  dbms_output.put_line(c);
  8* end;
0

PL/SQL procedure successfully completed.
Es el mismo ejemplo que habia publicado antes, la diferencia es que ahora comparo una columna CHAR con una variable VARCHAR2, y me dice que 'Hola' es diferente de 'Hola ', lo que significa que si unos de los valores a comparar no es CHAR o literal, entonce no utiliza la comparacion semantica blank-padded.

Saludos
  #8 (permalink)  
Antiguo 02/11/2007, 17:52
 
Fecha de Ingreso: septiembre-2005
Mensajes: 73
Antigüedad: 19 años, 2 meses
Puntos: 0
Re: Problema con parámetros y espacios

Ok gracias a todos por sus respuestas.

Les comento, por lo pronto estamos evaluando la posibilidad de cambiar todas las variables de tipo char a tipo varchar2.

La parte que comentan que debo de fijarme que los tipos comparados sean del mismo tipo, en este caso char, me pareció interesante.

Todavía no lo pruebo, pero en cuanto lo haga les comento los resultados, porque si me parece que son de diferente tipo.

Sale gracias.
__________________
Henry :-D
  #9 (permalink)  
Antiguo 02/11/2007, 22:38
Avatar de Linterns
Colaborador
 
Fecha de Ingreso: diciembre-2001
Mensajes: 2.799
Antigüedad: 22 años, 11 meses
Puntos: 11
Re: Problema con parámetros y espacios

Lo que puedes hacer es simplemente crear tu propia funcion de vonvertir a varchar que no existe en oracle

Código:
Create o replace function TO_VARCHAR( mivariable in char) return varchar as
mibandera varcha2(500);
Begin
   mibandera := mivariable;
   return mibandera
End;
Nota: La sintaxis puede estar equivocada que la he creado en el notepad y no en Oracle asi que verificala bien; pero es una vieja funcion que yo ocupaba cuando aun tenia CHAR en mis tablas

Ahora ya podras hacer las comparaciones

Código:
 
select * 
from t10 
where to_varchar(name) = 'Hola';
__________________
Bien se puede recibir una puñalada sin adulación,
pero rara vez se recibe una adulación sin puñalada
** ***
  #10 (permalink)  
Antiguo 05/11/2007, 14:48
Avatar de matanga  
Fecha de Ingreso: octubre-2007
Ubicación: España
Mensajes: 1.091
Antigüedad: 17 años
Puntos: 85
Re: Problema con parámetros y espacios

Hola,

Linterns, mirando un poco el codigo publicado, y si me permites, me gustaria hacer algunas observaciones.

1. Habria que agregar un TRIM en la linea mibandera := mivariable;, esto es porque al hacer un casteo implicito de una variable CHAR a una VARCHAR2 se mantendran los espacios en blanco al final, y esto, en tipos VARCHAR2 genera que 'Hola' sea distinto de 'Hola '.

2. Tambien existe la opcion de utilizar la funcion built-in de Oracle CAST(campo as varchar2(10)), a la que tambien habria que agregarle un TRIM. La logitud 10 es solo de ejemplo.

3. El uso de funciones aplicadas a un campo provoca que no se utilicen los indices que puedan existir para ese campo, dejando de lado los indices basados en funcion, esto generaria un full-scan sobre la tabla, que puede o no ser un problema.

Saludos
  #11 (permalink)  
Antiguo 19/01/2009, 05:46
Avatar de ChiramMFM  
Fecha de Ingreso: enero-2008
Mensajes: 19
Antigüedad: 16 años, 10 meses
Puntos: 0
Respuesta: Problema con parámetros y espacios

Hola,

Mi caso es muy parecido a este, solucionado con un trim, pero aun así el problema se puede volver a presentar y querria arreglarlo definitivamente.
Cuando hago la consulta:

Código:
Select Campo1, Campo2, 'PALABRA' as user_mod from Tabla1 where....
realizo esta consulta desde JAVA, y cuando recupero el ResultSet el campo user_mod
la respuesta es 'PALABRA ', que hacen 32 caracteres. Deduzco que esto es debido al Blank-padded. Se puede desactivar, o usar otro metodo de comparación?

Puesto que este thread es bastante viejo, abro otro, haber si alguien mas lo ve.

Gracias
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:34.