ฉันกำลังทำงานกับฐานข้อมูล MySQL ที่มีข้อมูลบางส่วนที่นำเข้าจากExcel ข้อมูลประกอบด้วยอักขระที่ไม่ใช่ASCII (เช่นเครื่องหมายขีดกลาง ฯลฯ ) รวมทั้งการส่งคืนค่าขนส่งที่ซ่อนอยู่หรือฟีดบรรทัด มีวิธีค้นหาบันทึกเหล่านี้โดยใช้ MySQL หรือไม่?
ฉันกำลังทำงานกับฐานข้อมูล MySQL ที่มีข้อมูลบางส่วนที่นำเข้าจากExcel ข้อมูลประกอบด้วยอักขระที่ไม่ใช่ASCII (เช่นเครื่องหมายขีดกลาง ฯลฯ ) รวมทั้งการส่งคืนค่าขนส่งที่ซ่อนอยู่หรือฟีดบรรทัด มีวิธีค้นหาบันทึกเหล่านี้โดยใช้ 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 ที่ไม่สามารถพิมพ์ได้เช่น newline)
REGEXP
และRLIKE
ตัวดำเนินการทำงานแบบไบต์ที่ชาญฉลาดดังนั้นจึงไม่ปลอดภัยแบบหลายไบต์และอาจให้ผลลัพธ์ที่ไม่คาดคิดกับชุดอักขระแบบหลายไบต์นอกจากนี้ตัวดำเนินการเหล่านี้จะเปรียบเทียบอักขระตามค่าไบต์และ อักขระที่เน้นเสียงไม่สามารถเปรียบเทียบได้ว่าเท่ากันแม้ว่าการจัดเรียงจะถือว่าเท่ากันก็ตาม "
อักขระหนึ่งตัวที่ขาดหายไปจากตัวอย่างของทุกคนด้านบนคืออักขระการยุติ (\ 0) สิ่งนี้มองไม่เห็นกับเอาต์พุตคอนโซล MySQL และไม่สามารถค้นพบได้จากการสืบค้นใด ๆ ที่กล่าวถึงในที่นี้ แบบสอบถามที่จะค้นหามีเพียง:
select * from TABLE where COLUMN like '%\0%';
จากคำตอบที่ถูกต้อง แต่คำนึงถึงอักขระควบคุม ASCII ด้วยเช่นกันวิธีแก้ปัญหาที่เหมาะกับฉันคือ:
SELECT * FROM `table` WHERE NOT `field` REGEXP "[\\x00-\\xFF]|^$";
มันทำสิ่งเดียวกัน: ค้นหาการละเมิดช่วง ASCII ในคอลัมน์ แต่ช่วยให้คุณค้นหาอักขระควบคุมได้เช่นกันเนื่องจากใช้สัญกรณ์ฐานสิบหกสำหรับจุดรหัส เนื่องจากไม่มีการเปรียบเทียบหรือการแปลง (ไม่เหมือนคำตอบของ @ Ollie) สิ่งนี้จึงควรเร็วกว่ามากเช่นกัน (โดยเฉพาะอย่างยิ่งถ้า MySQL ทำการยกเลิกก่อนกำหนดในแบบสอบถาม regex ซึ่งควรจะเป็นอย่างแน่นอน)
นอกจากนี้ยังหลีกเลี่ยงการส่งคืนฟิลด์ที่มีความยาวเป็นศูนย์ หากคุณต้องการเวอร์ชันที่ยาวขึ้นเล็กน้อยซึ่งอาจทำงานได้ดีขึ้นคุณสามารถใช้สิ่งนี้แทน:
SELECT * FROM `table` WHERE `field` <> "" AND NOT `field` REGEXP "[\\x00-\\xFF]";
จะทำการตรวจสอบความยาวแยกต่างหากเพื่อหลีกเลี่ยงผลลัพธ์ที่มีความยาวเป็นศูนย์โดยไม่ต้องพิจารณาว่าเป็น regex pass ขึ้นอยู่กับจำนวนรายการที่มีความยาวเป็นศูนย์ซึ่งอาจเร็วกว่ามาก
โปรดทราบว่าหากชุดอักขระเริ่มต้นของคุณเป็นสิ่งที่แปลกประหลาดโดยที่ 0x00-0xFF ไม่ได้จับคู่กับค่าเดียวกันกับ ASCII (มีชุดอักขระเช่นนี้อยู่ที่ใดหรือไม่) สิ่งนี้จะส่งคืนค่าบวกเท็จ มิฉะนั้นสนุก!
REGEXP
ตรวจสอบ ดังนั้นจึงรับประกันได้ว่าจะตรงกันเสมอ นอกจากนี้^$
อาจไม่ใช่สิ่งที่คุณต้องการ
ลองใช้แบบสอบถามนี้เพื่อค้นหาระเบียนอักขระพิเศษ
SELECT *
FROM tableName
WHERE fieldName REGEXP '[^a-zA-Z0-9@:. \'\-`,\&]'
คำตอบของ @ zende เป็นคำตอบเดียวที่ครอบคลุมคอลัมน์ที่มีอักขระ ascii และไม่ใช่ ascii ผสมกัน แต่ก็มีสิ่งที่เป็นฐานสิบหกที่มีปัญหาเช่นกัน ฉันใช้สิ่งนี้:
SELECT * FROM `table` WHERE NOT `column` REGEXP '^[ -~]+$' AND `column` !=''
ใน Oracle เราสามารถใช้ด้านล่าง
SELECT * FROM TABLE_A WHERE ASCIISTR(COLUMN_A) <> COLUMN_A;
สำหรับคำถามนี้เราสามารถใช้วิธีนี้:
คำถามจากสวนสัตว์ sql:
ค้นหารายละเอียดทั้งหมดของรางวัลที่ PETER GRÜNBERGได้รับ
อักขระที่ไม่ใช่ ASCII
ans: เลือก * จากโนเบลที่ผู้ชนะเช่น 'P% GR% _% berg';