Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment se débarrasser des caractères NUL dans la base de données Oracle ?

Personnellement, j'utiliserais CHR() pour identifier les valeurs nulles. Un nul est un ASCII 0 et CHR() renverra la représentation en caractères du nombre que vous transmettez.

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

Comme vous pouvez le voir en concaténant les signes de pourcentage autour de CHR(0) (ce qui équivaut à nul), vous pouvez renvoyer des lignes contenant le nul.

DUMP() renvoie le type de données (1 signifie VARCHAR2 ) la longueur de la chaîne en octets et la représentation interne des données ; la valeur par défaut est binaire.

Cependant, vous devez être prudent avec les données multioctets comme CHR() renvoie le caractère équivalent du module de 256 du nombre :

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

Comme vous pouvez le voir, vous identifieriez par erreur un nul ici, en utilisant soit CHR() ou DUMP()

En d'autres termes, si vous n'avez pas de données multi-octets, la chose la plus simple à faire est simplement remplacer il :

update <table>
   set <column> = replace(<column>, chr(0));

Utilisation de RAWTOHEX() a des problèmes similaires ; bien que vous puissiez trouver le 00 il n'y a aucune garantie qu'il s'agisse réellement d'un nul :

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

Il a en fait un autre problème également; imaginez que vous aviez deux caractères 10 et 06 la valeur renvoyée est alors 1006 et vous trouverez 00 . Si vous deviez utiliser cette méthode, vous devez vous assurer que vous n'avez regardé que deux groupes de caractères, à partir du début de la chaîne.

Comme la représentation interne d'un caractère nul est utilisée pour représenter des parties d'autres caractères multioctets, vous ne pouvez pas simplement les remplacer car vous ne savez pas s'il s'agit d'un caractère ou d'un demi-caractère. Donc, si vous utilisez un jeu de caractères multi-octets, pour autant que je sache, vous ne pourrez pas le faire.