Saya bekerja dengan database MySQL yang beberapa datanya diimpor dari Excel . Data berisi karakter non- ASCII (tanda pisah em, dll.) Serta carriage return atau baris feed yang tersembunyi. Apakah ada cara untuk menemukan record ini menggunakan MySQL?
mysql
character-encoding
Ed Mays
sumber
sumber
Jawaban:
Itu tergantung persis apa yang Anda definisikan sebagai "ASCII", tetapi saya menyarankan untuk mencoba varian kueri seperti ini:
Kueri tersebut akan mengembalikan semua baris di mana columnToCheck berisi karakter non-alfanumerik. Jika Anda memiliki karakter lain yang dapat diterima, tambahkan ke kelas karakter dalam ekspresi reguler. Misalnya, jika titik, koma, dan tanda hubung OK, ubah kueri menjadi:
Halaman paling relevan dari dokumentasi MySQL mungkin adalah 12.5.2 Regular Expressions .
sumber
SELECT * FROM tbl WHERE colname NOT REGEXP '^[A-Za-z0-9\.,@&\(\) \-]*$';
MySQL menyediakan manajemen rangkaian karakter komprehensif yang dapat membantu mengatasi masalah semacam ini.
The
CONVERT(col USING charset)
Fungsi mengubah karakter unconvertable menjadi karakter pengganti. Kemudian, teks yang dikonversi dan teks yang belum dikonversi akan menjadi tidak sama.Lihat ini untuk diskusi lebih lanjut. https://dev.mysql.com/doc/refman/8.0/en/charset-repertoire.html
Anda dapat menggunakan nama set karakter apa pun yang Anda inginkan sebagai pengganti ASCII. Misalnya, jika Anda ingin mengetahui karakter mana yang tidak ditampilkan dengan benar di halaman kode 1257 (Lituavi, Latvia, Estonia) gunakan
CONVERT(columnToCheck USING cp1257)
sumber
Anda dapat menentukan ASCII sebagai semua karakter yang memiliki nilai desimal 0 - 127 (0x00 - 0x7F) dan menemukan kolom dengan karakter non-ASCII menggunakan kueri berikut
Ini adalah pertanyaan paling komprehensif yang dapat saya temukan.
sumber
SELECT * FROM table WHERE LENGTH( column ) != CHAR_LENGTH( column )
'ā'
(dikodekan oleh urutan byte0x0101
) - itu akan dianggap "ASCII" menggunakan tes ini: negatif palsu ; memang, beberapa rangkaian karakter tidak karakter ASCII encode dalam0x00
ke0x7f
dimana solusi ini akan menghasilkan positif palsu. JANGAN MENGANDALKAN JAWABAN INI!LENGTH(column)
akan menjadi kelipatan konstanCHAR_LENGTH(column)
terlepas dari nilainya.Ini mungkin yang Anda cari:
Ini harus mengembalikan semua baris di mana COLUMN berisi karakter non-ASCII (atau karakter ASCII yang tidak dapat dicetak seperti baris baru).
sumber
REGEXP
danRLIKE
. Operator bekerja dalam mode byte-bijaksana, sehingga mereka tidak multi-byte aman dan dapat menghasilkan hasil yang tidak diharapkan dengan karakter set multi-byte Selain itu, operator ini membandingkan karakter dengan nilai-nilai byte dan karakter beraksen mungkin tidak dapat dibandingkan sebagai sama meskipunSatu karakter yang hilang dari contoh semua orang di atas adalah karakter terminasi (\ 0). Ini tidak terlihat oleh keluaran konsol MySQL dan tidak dapat ditemukan oleh salah satu kueri yang disebutkan sebelumnya. Kueri untuk menemukannya adalah:
sumber
Berdasarkan jawaban yang benar, tetapi dengan mempertimbangkan karakter kontrol ASCII juga, solusi yang berhasil untuk saya adalah ini:
Itu melakukan hal yang sama: mencari pelanggaran rentang ASCII di kolom, tetapi memungkinkan Anda mencari karakter kontrol juga, karena menggunakan notasi heksadesimal untuk poin kode. Karena tidak ada perbandingan atau konversi (tidak seperti jawaban @ Ollie), ini seharusnya jauh lebih cepat juga. (Terutama jika MySQL melakukan penghentian awal pada kueri regex, yang memang seharusnya dilakukan.)
Ini juga menghindari kembali bidang yang panjangnya nol. Jika Anda menginginkan versi yang sedikit lebih panjang yang mungkin berkinerja lebih baik, Anda dapat menggunakan ini sebagai gantinya:
Itu melakukan pemeriksaan terpisah untuk panjang untuk menghindari hasil panjang-nol, tanpa mempertimbangkannya untuk regex pass. Bergantung pada jumlah entri panjang-nol yang Anda miliki, ini bisa jauh lebih cepat.
Perhatikan bahwa jika kumpulan karakter default Anda adalah sesuatu yang aneh di mana 0x00-0xFF tidak dipetakan ke nilai yang sama seperti ASCII (apakah ada kumpulan karakter seperti itu di mana saja?), Ini akan mengembalikan positif palsu. Jika tidak, selamat menikmati!
sumber
REGEXP
diperiksa. Makanya di jamin selalu cocok. Juga^$
mungkin bukan apa yang Anda inginkan.Coba gunakan kueri ini untuk mencari rekaman karakter khusus
sumber
Jawaban @zende adalah satu-satunya jawaban yang menutupi kolom dengan campuran karakter ascii dan non ascii, tetapi juga memiliki hex yang bermasalah. Saya menggunakan ini:
sumber
Di Oracle kita bisa gunakan di bawah ini.
sumber
untuk pertanyaan ini kita juga bisa menggunakan metode ini:
Pertanyaan dari sql zoo:
Temukan semua detail hadiah yang dimenangkan oleh PETER GRÜNBERG
Karakter non-ASCII
ans: pilih * dari nobel dimana pemenangnya menyukai'P% GR% _% berg ';
sumber