[Dica] IN pode concatenar espaços em branco

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5018
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

PessoALL... Isso é um pouco intrigante. O famoso IN usado nos SQL concatena os espaços em branco no fim das strings! Veja abaixo:

Selecionar tudo

SQL> SELECT 'SQL IN contatena espaços em branco!' CAMPO
  2  FROM DUAL 
  3  WHERE 'SP ' IN ( 'SP', 'RJ' )
  4  /

CAMPO
-----------------------------------
SQL IN contatena espaços em branco!

SQL> 

Selecionar tudo

SQL> SELECT 'SQL IN contatena TAB!' CAMPO
  2  FROM DUAL 
  3  WHERE 'SP ' IN ( 'SP', 'RJ' )
  4  /

CAMPO
---------------------
SQL IN contatena TAB!

SQL> 

Selecionar tudo

SQL> SELECT 'SQL IN não concatena espaços na esquerda!' CAMPO
  2  FROM DUAL 
  3  WHERE ' SP' IN ( 'SP', 'RJ' )
  4  /

no rows selected

SQL> 
Agora, dentro de um bloco PL/SQL

Selecionar tudo

SQL> DECLARE
  2    VTEMP VARCHAR2(100);
  3  BEGIN
  4    SELECT 'SQL IN contatena espaços em branco!' CAMPO
  5    INTO VTEMP
  6    FROM DUAL 
  7    WHERE 'SP ' IN ( 'SP', 'RJ' );
  8  
  9    DBMS_OUTPUT.PUT_LINE('Concatenou');
 10    
 11  EXCEPTION WHEN NO_DATA_FOUND THEN 
 12    DBMS_OUTPUT.PUT_LINE('não concatenou');
 13  END;
 14  /
Concatenou

PL/SQL procedure successfully completed.

SQL> 
Usando variável, ele não faz isso!

Selecionar tudo

SQL> DECLARE
  2    VTEMP VARCHAR2(100);
  3    VALOR VARCHAR2(10) :='SP ';
  4  BEGIN
  5    SELECT 'SQL IN contatena espaços em branco!' CAMPO
  6    INTO VTEMP
  7    FROM DUAL 
  8    WHERE valor IN ( 'SP', 'RJ' );
  9  
 10    DBMS_OUTPUT.PUT_LINE('Concatenou');
 11    
 12  EXCEPTION WHEN NO_DATA_FOUND THEN 
 13    DBMS_OUTPUT.PUT_LINE('não concatenou');
 14  END;
 15  /
não concatenou

PL/SQL procedure successfully completed.

SQL> 
CONCLUSÃO
Mais uma prova que usar BINDS é sempre uma boa. "Montar" comandos SQL dinamicamente pode acarretar essa concatenação acima.
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5018
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Achei algo que Chip Dawes escreveu sobre o assunto:
Blank-Padded and Nonpadded Comparison Semantics

With blank-padded semantics, if the two values have different lengths, then Oracle first adds blanks to the end of the shorter one so their lengths are equal. Oracle then compares the values character by character up to the first character that differs. The value with the greater character in the first differing position is considered greater. If two values have no differing characters, then they are considered equal. This rule means that two values are equal if they differ only in the number of trailing blanks. Oracle uses blank-padded comparison semantics only when both values in the comparison are either expressions of datatype CHAR, NCHAR, text literals, or values returned by the USER function.
OU seja, o Oracle concatena espaços em branco na string menor para que tenham o mesmo tamanho. Após isso, ele faz a comparação das strings. Se nenhuma letra é diferente, então são iguais.

Caso encerrado :-D
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 4 visitantes