Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como se livrar de caracteres NUL no banco de dados Oracle?


Pessoalmente, eu usaria CHR() para identificar os valores nulos. Um nulo é um ASCII 0 e CHR() retornará a representação de caracteres do número que você passar.
SQL> with the_data as (
  2  select 'a' || chr(0) || 'b' as str from dual
  3   union all
  4  select 'a' || 'c' from dual
  5         )
  6  select dump(str)
  7    from the_data
  8   where str like '%' || chr(0) || '%'
  9         ;

DUMP(STR)
----------------------------------------------------    
Typ=1 Len=3: 97,0,98

Como você pode ver concatenando sinais de porcentagem em torno de CHR(0) (que é equivalente a nul) você pode retornar linhas com o nul.

DUMP() retorna o tipo de dados (1 significa VARCHAR2 ) o comprimento da string em bytes e a representação interna dos dados; o padrão é binário.

No entanto, você precisa ter cuidado com dados multibyte como CHR() retorna o caractere equivalente do módulo de 256 do número:
SQL> with the_data as (
  2  select 'a' || chr(0) || 'b' as str from dual
  3   union all
  4  select 'a' || chr(256) || 'c' from dual
  5         )
  6  select dump(str)
  7    from the_data
  8   where str like '%' || chr(0) || '%'
  9         ;

DUMP(STR)
-------------------------------------------------
Typ=1 Len=3: 97,0,98
Typ=1 Len=4: 97,1,0,99

Como você pode ver, você identificaria erroneamente um nul aqui, usando CHR() ou DUMP()

Em outras palavras, se você não tiver dados multibyte, a coisa mais fácil a fazer é simplesmente substituir isto:
update <table>
   set <column> = replace(<column>, chr(0));

Utilizando RAWTOHEX() tem problemas semelhantes; embora você possa encontrar o 00 não há garantia de que seja realmente um nulo:
SQL> with the_data as (
  2  select 'a' || chr(0) || 'b' as str from dual
  3   union all
  4  select 'a' || chr(256) || 'c' from dual
  5         )
  6  select rawtohex(str)
  7    from the_data
  8   where str like '%' || chr(0) || '%'
  9         ;

RAWTOHEX
--------
610062
61010063

Na verdade, ele também tem um problema adicional; imagine que você tenha dois caracteres 10 e 06 o valor retornado é então 1006 e você encontrará 00 . Se você for usar esse método, deverá garantir que apenas olhou para dois grupos de caracteres, desde o início da string.

Como a representação interna de um caractere nulo é usada para representar partes de outros caracteres multibyte, você não pode simplesmente substituí-los, pois não sabe se é um caractere ou meio caractere. Portanto, se você estiver usando um conjunto de caracteres multibyte, até onde eu saiba, não será capaz de fazer isso.