Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Oracle 2 tanda hubung di kolom angka?

Itu tidak berarti apa-apa, dan itu bukan 'untuk' apa pun; data Anda rusak, saya khawatir. -- adalah nilai aktual dari tabel Anda, tetapi itu bukan angka. Representasi internal Oracle untuk angka tercakup dalam catatan 1031902.6 jika Anda memiliki akses ke sana, atau ini jelaskan jika tidak . Jika itu benar-benar angka negatif maka byte heksadesimal terakhir harus 66. Membuang angka yang terlihat - dengan satu tanda minus, bukan dua, yang tidak berarti - memberikan:

select dump(-1331013400000000000000000000, 1016) from dual;

DUMP(-1331013400000000000000000000,1016)
----------------------------------------
Typ=2 Len=6: 31,58,46,64,43,66           

Membuat nomor yang tidak valid di Oracle tidak mudah (saya kira Anda tidak akan mengharapkannya), tetapi ini adalah metode yang pernah saya gunakan sebelumnya. Salah satu petunjuknya, selain tanda minus ganda dan panjangnya sama, adalah bahwa mengubah nilai yang dibuang kembali menjadi angka tidak memberikan hasil yang sama:

create table t42(value number);

declare
  n number;
begin
  dbms_stats.convert_raw_value('32ea004366', n);
  insert into t42 (value) values (n);
end;
/

select value from t42;

                                 VALUE
--------------------------------------
           -<3:13400000000000000000000

Ini dari Oracle 9i, penutupan yang saya miliki sekarang ke database 8i, jadi hasilnya mungkin sedikit berbeda.

Tidak dapat melakukan to_number(value) adalah petunjuk besar juga tentu saja; ada to_char() implicit implisit ketika Anda melakukannya, ia mencoba mengubah representasi teks menjadi angka, yang menjelaskan kesalahannya. to_char() value juga tidak cocok dengan apa yang dilakukan oleh pilihan sederhana, yang menarik. Anda akan melihat kesalahan yang sama jika melakukannya dengan data Anda.

select to_number(value) from t42;
select to_number(value) from t42
                 *
ERROR at line 1:
ORA-01722: invalid number

select to_char(value) from t42;

TO_CHAR(VALUE)
----------------------------------------
-`003400000000000000000000

Kecuali Anda tahu dari mana data buruk itu berasal dan masih memiliki aslinya, Anda mungkin tidak dapat menyelamatkan nilai-nilai ini. Saya pikir yang terbaik yang dapat Anda lakukan adalah mengabaikannya, atau menggantinya dengan sesuatu yang akan bermigrasi - jika bidangnya nullable maka null akan menjadi pilihan yang aman, jika tidak, saya rasa Anda harus memilih nilai ajaib.

Mengidentifikasi dan memodifikasi baris yang terpengaruh dapat dilakukan melalui suatu fungsi; mungkin seperti:

create or replace function null_bad_number(value number)
return number deterministic as
  tmp_value number;
  invalid_number exception;
  pragma exception_init(invalid_number, -1722);
begin
  select to_number(value) into tmp_value from dual;
  return value;
exception
  when invalid_number then
    return null;
end;
/

Dengan nilai tidak valid yang sama yang dibuat sebelumnya dan satu nilai valid:

insert into t42 (value) values (0.9574875526618150);

select * from t42;

     VALUE
----------
-`.003E+24
.957487553

update t42 set value = null
where value is not null
and null_bad_number(value) is null;

1 row updated.

select * from t42;

     VALUE
----------

.957487553

Tidak ideal dengan cara apa pun, tetapi pada titik ini saya pikir Anda hanya menyelamatkan apa yang Anda bisa. Anda dapat menghapus baris daripada memperbaruinya, atau menyetel nilainya ke yang lain, tergantung bagaimana Anda ingin melanjutkan.

Anda dapat mencoba melibatkan Oracle untuk melihat apakah mereka dapat mengetahui apa yang terjadi dan melihat apakah mereka memiliki trik untuk kembali ke nilai aslinya - yang tampaknya tidak mungkin - tetapi saya tidak yakin Anda akan mendapatkan banyak dukungan untuk database versi lama.

Tentu saja, tanpa mengetahui bagaimana dan kapan korupsi itu terjadi (mungkin melalui impor cerdik, atau melalui program OCI kereta), Anda harus mempertanyakan validitas semua data lain, baik di kolom itu maupun di tempat lain. Dalam hal ini korupsi terlihat sangat seragam - semua nilai yang tidak valid tampaknya dibangun dengan cara yang sama - jadi Anda mungkin baik-baik saja. Namun, secara umum, sesuatu yang memasukkan byte yang salah ke dalam nilai internal dapat menghasilkan nilai yang salah, tetapi masih valid. Itu bisa terlihat benar, atau bisa jadi jauh dari nilai awal yang diharapkan, dan benar-benar tidak ada cara untuk mengetahuinya.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. bagaimana cara mendapatkan PL/SQL di SQLFiddle?

  2. konversi unix_timestamp ke stempel waktu di Oracle

  3. Cara tercepat untuk menghitung hash dari seluruh tabel

  4. Memahami perilaku fungsi sisa () di Oracle

  5. Fungsi Oracle untuk membandingkan string dengan cara yang tidak berurutan