Я працюю з базою даних MySQL, яка містить деякі дані, імпортовані з Excel . Дані містять символи, що не належать до ASCII (em-тире та ін.), А також приховані повернення каретки або канали рядків. Чи є спосіб знайти ці записи за допомогою MySQL?
Я працюю з базою даних MySQL, яка містить деякі дані, імпортовані з Excel . Дані містять символи, що не належать до ASCII (em-тире та ін.), А також приховані повернення каретки або канали рядків. Чи є спосіб знайти ці записи за допомогою MySQL?
Відповіді:
Це саме залежить від того, що ви визначаєте як "ASCII", але я б запропонував спробувати такий варіант запиту, як цей:
SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9]';
Цей запит поверне всі рядки, у яких columnToCheck містить будь-які не буквено-цифрові символи. Якщо у вас є інші прийнятні символи, додайте їх до класу символів у регулярному виразі. Наприклад, якщо періоди, коми і дефіси в порядку, змініть запит на:
SELECT * FROM tableName WHERE columnToCheck NOT REGEXP '[A-Za-z0-9.,-]';
Мабуть, найбільш відповідна сторінка документації на MySQL - це, ймовірно, 12.5.2 регулярні вирази .
SELECT * FROM tbl WHERE colname NOT REGEXP '^[A-Za-z0-9\.,@&\(\) \-]*$';
MySQL забезпечує всебічне управління набором символів, що може допомогти у вирішенні подібних проблем.
SELECT whatever
FROM tableName
WHERE columnToCheck <> CONVERT(columnToCheck USING ASCII)
CONVERT(col USING charset)
Функція перетворює unconvertable символів в заміні символів. Тоді перетворений і неперетворений текст буде нерівним.
Дивіться це для більш детальної дискусії. https://dev.mysql.com/doc/refman/8.0/en/charset-repertoire.html
Ви можете використовувати будь-яке ім'я набору символів замість ASCII. Наприклад, якщо ви хочете дізнатися, які символи неправильно відображатимуться на кодовій сторінці 1257 (литовська, латвійська, естонська), використовуйтеCONVERT(columnToCheck USING cp1257)
Ви можете визначити ASCII як усі символи, які мають десяткове значення 0 - 127 (0x00 - 0x7F) і знайти стовпці з символами, що не належать до ASCII, за допомогою наступного запиту
SELECT * FROM TABLE WHERE NOT HEX(COLUMN) REGEXP '^([0-7][0-9A-F])*$';
Це був найповніший запит, який я міг придумати.
SELECT * FROM table WHERE LENGTH( column ) != CHAR_LENGTH( column )
'ā'
(закодований послідовністю байтів 0x0101
) - це вважатиметься "ASCII" за допомогою цього тесту: хибний негатив ; на самому справі, деякі набори Літери не закодувати символи ASCII в 0x00
в результаті 0x7f
чого це рішення дало б псевдопозитивний. НЕ ВІДПОВІДАЙТЕ НА ЦЕ ВІДПОВІДЬ!
LENGTH(column)
вони будуть постійними кратними CHAR_LENGTH(column)
незалежно від значення.
Це, мабуть, те, що ви шукаєте:
select * from TABLE where COLUMN regexp '[^ -~]';
Він повинен повертати всі рядки, де COLUMN містить символи, що не належать до ASCII (або символи ASCII, які не можна роздрукувати, такі як новий рядок).
REGEXP
RLIKE
Виходячи з правильної відповіді, але враховуючи також ASCII контрольні символи, рішення, яке працювало для мене, таке:
SELECT * FROM `table` WHERE NOT `field` REGEXP "[\\x00-\\xFF]|^$";
Це те ж саме: шукає порушення діапазону ASCII у стовпці, але дозволяє також шукати контрольні символи, оскільки він використовує шістнадцяткову позначення для кодових точок. Оскільки немає порівняння чи перетворення (на відміну від відповіді @ Оллі), це теж повинно бути значно швидшим. (Особливо, якщо MySQL виконує дострокове припинення запиту регулярних виразів, чого він, безумовно, повинен.)
Це також дозволяє уникнути повернення полів нульової довжини. Якщо ви хочете трохи довшу версію, яка може працювати краще, ви можете використовувати її замість цього:
SELECT * FROM `table` WHERE `field` <> "" AND NOT `field` REGEXP "[\\x00-\\xFF]";
Він робить окрему перевірку довжини, щоб уникнути нульових результатів, не враховуючи їх для проходження регулярного виразів. Залежно від кількості записів нульової довжини це може бути значно швидше.
Зауважте, що якщо ваш набір символів за замовчуванням є чимось химерним, коли 0x00-0xFF не відображає ті самі значення, що й ASCII (чи є такий набір символів десь?), Це поверне помилковий позитив. Інакше насолоджуйтесь!
REGEXP
і перевіряє. Отже, це гарантовано завжди збігається. Також ^$
, мабуть, не те, чого ти хотів.
У Oracle ми можемо використовувати нижче.
SELECT * FROM TABLE_A WHERE ASCIISTR(COLUMN_A) <> COLUMN_A;