Pracuję z bazą danych MySQL, która zawiera dane zaimportowane z programu Excel . Dane zawierają znaki spoza zestawu ASCII (kreski em, itp.), A także ukryte znaki końca karetki lub nowe wiersze. Czy istnieje sposób na znalezienie tych rekordów za pomocą MySQL?
mysql
character-encoding
Ed Mays
źródło
źródło
Odpowiedzi:
Zależy to dokładnie od tego, co definiujesz jako „ASCII”, ale sugerowałbym wypróbowanie wariantu zapytania takiego:
To zapytanie zwróci wszystkie wiersze, w których columnToCheck zawiera znaki inne niż alfanumeryczne. Jeśli masz inne dopuszczalne znaki, dodaj je do klasy znaków w wyrażeniu regularnym. Na przykład, jeśli kropki, przecinki i łączniki są w porządku, zmień zapytanie na:
Najbardziej odpowiednią stroną dokumentacji MySQL jest prawdopodobnie 12.5.2 Wyrażenia regularne .
źródło
SELECT * FROM tbl WHERE colname NOT REGEXP '^[A-Za-z0-9\.,@&\(\) \-]*$';
MySQL zapewnia kompleksowe zarządzanie zestawem znaków, które może pomóc w tego rodzaju problemach.
CONVERT(col USING charset)
Funkcja zamienia unconvertable znaki do znaków zastępczych. Wtedy przekonwertowany i nieprzekonwertowany tekst będzie nierówny.Zobacz to, aby uzyskać więcej dyskusji. https://dev.mysql.com/doc/refman/8.0/en/charset-repertoire.html
Możesz użyć dowolnej nazwy zestawu znaków zamiast ASCII. Na przykład, jeśli chcesz dowiedzieć się, które znaki nie będą renderowane poprawnie na stronie kodowej 1257 (litewski, łotewski, estoński), użyj
CONVERT(columnToCheck USING cp1257)
źródło
Możesz zdefiniować ASCII jako wszystkie znaki, które mają wartość dziesiętną od 0 do 127 (0x00 - 0x7F) i znaleźć kolumny ze znakami spoza zestawu ASCII za pomocą następującego zapytania
To było najbardziej wszechstronne zapytanie, jakie mogłem wymyślić.
źródło
SELECT * FROM table WHERE LENGTH( column ) != CHAR_LENGTH( column )
'ā'
(zakodowaną przez sekwencję bajtów0x0101
) - przy użyciu tego testu zostanie to uznane za „ASCII”: fałszywie ujemny ; Rzeczywiście, niektóre zestawy znaków nie kodują ciągu znaków ASCII0x00
, aby0x7f
czym to rozwiązanie przyniesie fałszywy alarm. NIE POLEGAJ NA TEJ ODPOWIEDZI!LENGTH(column)
będzie to stała wielokrotnośćCHAR_LENGTH(column)
niezależnie od wartości.To jest prawdopodobnie to, czego szukasz:
Powinien zwrócić wszystkie wiersze, w których KOLUMNA zawiera znaki inne niż ASCII (lub niedrukowalne znaki ASCII, takie jak nowa linia).
źródło
REGEXP
RLIKE
Jednym brakującym znakiem z wszystkich powyższych przykładów jest znak zakończenia (\ 0). Jest to niewidoczne dla danych wyjściowych konsoli MySQL i nie jest wykrywalne przez żadne z wyżej wymienionych zapytań. Zapytanie, aby go znaleźć, jest proste:
źródło
Opierając się na poprawnej odpowiedzi, ale biorąc pod uwagę również znaki sterujące ASCII, rozwiązanie, które zadziałało dla mnie to:
Robi to samo: wyszukuje naruszenia zakresu ASCII w kolumnie, ale umożliwia również wyszukiwanie znaków sterujących, ponieważ używa notacji szesnastkowej dla punktów kodowych. Ponieważ nie ma porównania ani konwersji (w przeciwieństwie do odpowiedzi @ Ollie), to również powinno być znacznie szybsze. (Zwłaszcza jeśli MySQL wykonuje wczesne zakończenie zapytania regex, co zdecydowanie powinno.)
Unika również zwracania pól o zerowej długości. Jeśli potrzebujesz nieco dłuższej wersji, która może działać lepiej, możesz użyć tego:
Wykonuje oddzielne sprawdzenie długości, aby uniknąć wyników o zerowej długości, bez uwzględniania ich jako przebiegu wyrażenia regularnego. W zależności od liczby posiadanych wpisów o zerowej długości może to być znacznie szybsze.
Zauważ, że jeśli twój domyślny zestaw znaków jest czymś dziwnym, gdzie 0x00-0xFF nie jest mapowane na te same wartości co ASCII (czy istnieje taki zestaw znaków gdziekolwiek istnieje?), Zwróci to fałszywie dodatni wynik. W przeciwnym razie baw się dobrze!
źródło
REGEXP
jest sprawdzane. W związku z tym gwarantuje, że zawsze będzie pasować. Również^$
nie jest chyba to, czego chciał.Spróbuj użyć tego zapytania do wyszukiwania rekordów znaków specjalnych
źródło
Odpowiedź @ zende była jedyną, która obejmowała kolumny mieszaniną znaków ascii i non-ascii, ale zawierała również problematyczne szesnastkowe. Użyłem tego:
źródło
W Oracle możemy użyć poniżej.
źródło
do tego pytania możemy również użyć tej metody:
Pytanie od sql zoo:
Znajdź wszystkie szczegóły nagrody zdobytej przez PETERA GRÜNBERGA
Znaki spoza ASCII
ans: wybierz * z nobla, gdzie zwycięzca jak „P% GR% _% berg”;
źródło