Osobiście użyłbym CHR()
do identyfikacji wartości nul. Nul to ASCII 0 i CHR()
zwróci reprezentację znakową liczby, którą przekazujesz.
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
Jak widać, łącząc znaki procentowe wokół CHR(0)
(co jest równoważne nul) możesz zwracać wiersze z wartością nul w środku.
DUMP()
zwraca typ danych (1 oznacza VARCHAR2 ) długość ciągu w bajtach i wewnętrzna reprezentacja danych; domyślna jest binarna.
Jednak musisz uważać na dane wielobajtowe jako CHR()
zwraca znakowy odpowiednik modułu 256 liczby:
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
Jak widać, błędnie zidentyfikowałbyś tutaj nul, używając albo CHR()
lub DUMP()
Innymi słowy, jeśli nie masz danych wielobajtowych, najłatwiej jest po prostu zamień to:
update <table>
set <column> = replace(<column>, chr(0));
Korzystanie z RAWTOHEX()
ma podobne problemy; chociaż możesz znaleźć 00
nie ma gwarancji, że faktycznie jest to 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
W rzeczywistości ma też inny problem; wyobraź sobie, że masz dwa znaki 10
i 06
zwracana wartość to 1006
a znajdziesz 00
. Jeśli miałbyś użyć tej metody, musisz upewnić się, że patrzysz tylko na dwie grupy znaków, od początku ciągu.
Ponieważ wewnętrzna reprezentacja znaku nul jest używana do reprezentowania części innych, wielobajtowych znaków, nie można ich po prostu zastąpić, ponieważ nie wiadomo, czy jest to jeden znak, czy połowa znaku. Tak więc, jeśli używasz wielobajtowego zestawu znaków, o ile wiem, nie będziesz w stanie tego zrobić.