Сервер MySQL версии 10.3.9-MariaDB не может запрашивать текст имеет одинарные кавычки
У меня есть база данных MySQL, в которой есть поле TagName со значением ~!@#$%^&*()_+|}{":?> <./ '; [] \ = -` Я пытаюсь выполнить запрос выбора TagName из taginfo где TagName наподобие '% @ # $%';
Показывает данные с тэгами, содержащими кавычки. Но я делаю запрос с оператором = и подобным оператором и добавляю дополнительную цитату '', чтобы принять одинарную кавычку, но она показывает пустой результат
Я также пытаюсь добавить COLLATE UTF8_GENERAL_CI или изменить CHARACTER SET, но все они не увенчались успехом.
SELECT * from taginfo where tagname like '%~!@#$%^&*()_+|}{":?><./'';[]\=-`%';
SELECT * from taginfo where tagname like '%~!@#$%^&*()_+|}{":?><./'';[]\=-`%' COLLATE UTF8_GENERAL_CI;
SELECT * from taginfo where tagname COLLATE UTF8_GENERAL_CI like '%~!@#$%^&*()_+|}{":?><./'';[]\=-`%';
ALTER TABLE mytable CONVERT TO CHARACTER SET UTF8_GENERAL_CI
Error 2/19/2019 10:03:24 AM 0:00:00.039 <link> - MySQL Database Error: Unknown character set: 'UTF8_GENERAL_CI' 5 0
Версия сервера БД: MySQL 5.5.5 MariaDB Информация о таблице:
Вот результат запроса без одинарных кавычек:
Обновлено: я обнаружил проблему, что если я запрашиваю без символа \, он показывает результат:
select TagName from taginfo where TagName like '%~!@#$%^&*()_+|}{":?><./'';[]%';
Но я добавил символ \, в конце он ничего не показывает:
select TagName from taginfo where TagName like '%~!@#$%^&*()_+|}{":?><./'';[]\%';
добавить больше всплеск еще не работает
select TagName from taginfo where TagName like '%~!@#$%^&*()_+|}{":?><./'';[]\\%';
Обновлено: проблема в том, что подобный запрос возвращает результат, но запрос = не возвращает ничего.
SELECT * from taginfo where tagname like '%~!@#$%^&*()_+|}{":?><./'';[]\\=-`%';
select * from taginfo where TagName = '~!@#$%^&*()_+|}{":?><./'';[]\\=-`'
Обновлено: когда я пытаюсь создать БД в MySQL 8.0.13, этот запрос работает хорошо и возвращает 1 строку
select * from taginfo1 where TagName = '~!@#$%^&*()_+|}{":?><./'';[]\\=-`';
Но в 10.3.9-MariaDB, запрос
select * from taginfo1 where TagName = '~!@#$%^&*()_+|}{":?><./'';[]\\=-`';
не может вернуть результат.
SELECT VERSION();
10.3.9-MariaDB
3 ответа
Наконец я нашел проблему, потому что я установил этот режим.
SET @@SQL_MODE = CONCAT(@@SQL_MODE, ',NO_BACKSLASH_ESCAPES');
и этот запрос возвращает пустой
select * from taginfo where tagname = '~!@#$%^&*()_+|}{":?><./'';[]\\=-`'
Когда я удаляю NO_BACKSLASH_ESCAPES по SET @@SQL_MODE = 'NO_ENGINE_SUBSTITUTION';
select * from taginfo where tagname = '~!@#$%^&*()_+|}{":?><./'';[]\\=-`'
возвращает строку с тэгом = ~!@#$%^&*()_+|}{":?><./ '; [] \ = -`
DROP TABLE IF EXISTS `taginfo`;
CREATE TABLE `taginfo` (
`tagname` VARCHAR(50) NULL DEFAULT NULL
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
-- Notice single quote and backslash are escaped:
INSERT INTO `taginfo` (`tagname`) VALUES ('~!@#$%^&*()_+|}{":?><./'';[]\\=-`');
SELECT * FROM `taginfo` WHERE tagname = '~!@#$%^&*()_+|}{":?><./'';[]\\=-`';
-- Notice single quote, percent and underscore are escaped and backslash escaped twice
SELECT * FROM `taginfo` WHERE tagname LIKE '~!@#$\%^&*()\_+|}{":?><./'';[]\\\\=-`';
SELECT * FROM `taginfo` WHERE tagname LIKE '%~!@#$\%^&*()\_+|}{":?><./'';[]\\\\=-`%';
Я пытаюсь установить
SET @@SQL_MODE = CONCAT(@@SQL_MODE, ',NO_BACKSLASH_ESCAPES');
И обновить запрос добавить двойной \
SELECT * from taginfo where tagname like '%~!@#$%^&*()_+|}{":?><./'';[]\\=-`%';
Этот запрос возвращает правильный результат, но не работает с оператором =.
Обратная косая черта - это экранирующий символ в MySQL. Вам нужно было бы дважды убежать от него, как \\
, Также при использовании LIKE
Условие, знак процента и подчеркивание также должны быть экранированы (в противном случае вы переместите совпадение на нерелевантные значения).
Вы можете увидеть, что происходит, просто выбрав значение, которое вы передаете:
SELECT '%~!@#$\%^&*()_+|}{":?><./'';[]\=-`%' test1;
| test1 |
| -------------------------------- |
| %~!@#$%^&*()_+|}{":?><./';[]=-`% |
Единственная обратная косая черта просто исчезает. MySQL думает, что это что-то, чтобы избежать, но так как следующий символ (=
) на самом деле не специальный символ, больше ничего не происходит.
Теперь давайте дважды избежим обратного слэша, и он появится в выводе:
SELECT '%~!@#$\%^&*()\_+|}{":?><./'';[]\\=-`%' test2;
| test2 |
| --------------------------------- |
| %~!@#$%^&*()_+|}{":?><./';[]\=-`% |