Почему оператор DELETE не работает с MySQL Connector / net, когда он работает в MySql Workbench и PHP / PDO? - PullRequest
0 голосов
/ 09 ноября 2018

У меня есть база данных MariaDB, содержащая таблицу с информацией о мобильных устройствах (android и ios), работающих на сервере CentOS 7 с компилятором Mono JIT версии 5.4.0.201 и MySql Connector / NET (последняя версия 8.0.13).

Все работает отлично, за исключением того, что я не могу удалить устройства на основе push-токенов из таблицы Devices через Connector / NET. Таблица определена следующим образом:

CREATE TABLE `Devices` (
  `idDevices` int(11) NOT NULL AUTO_INCREMENT,
  `notificationId` varchar(160) DEFAULT NULL,
  `deviceId` varchar(64) NOT NULL,
  `isAndroid` tinyint(1) NOT NULL,
  `deviceModel` varchar(64) DEFAULT NULL,
  `appMajor` tinyint(4) DEFAULT NULL,
  `appMinor` tinyint(4) DEFAULT NULL,
  PRIMARY KEY (`idDevices`),
  UNIQUE KEY `isAndroid` (`isAndroid`,`deviceId`),
  UNIQUE KEY `notificationId_UNIQUE` (`isAndroid`,`notificationId`),
  KEY `appVersion` (`appMajor`,`appMinor`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Когда я запускаю инструкцию DELETE из моего приложения Mono, исключений не возникает, но значение int, возвращаемое из ExecuteNonQuery (), всегда равно 0, и строки не были удалены из таблицы. Ошибки и предупреждения не регистрируются в файле mariadb.log (log_warning = 4). Если я копирую точно такой же оператор SQL в MySql Workbench и выполняю там оператор, строки удаляются, как и ожидалось. Если я создаю PHP-скрипт и использую PDO-соединение с той же БД, он также работает как положено. Во всех трех тестовых случаях используется один и тот же пользователь (root). Так что, похоже, проблема специфична для Connector / NET

            var tokenCount = 0;
            var sql = new StringBuilder ("DELETE FROM Devices WHERE isAndroid = 0 AND notificationId IN ('");

            while (...) {
                sql.Append (token);
                sql.Append ("','");
                tokenCount++;
            }

            sql.Length -= 2;
            sql.Append (')');

            using (var connection = new MySqlConnection (connectionString)) {
                connection.Open ();
                using (var command = new MySqlCommand (sql.ToString (), connection)) {
                    var affectedRows = command.ExecuteNonQuery ();
                    if (affectedRows != tokenCount) {
                        //Always logs affectedRows(0)
                        log.Warn ($"Remove tokenCount({tokenCount}) != affectedRows({affectedRows}). sql={sql}");
                    }
                }
            }

ОБНОВЛЕНИЕ: Я включил general_log и вижу, что правильная БД инициализирована И оператор выполняется - но таблица не изменилась! Вывод из журнала:

        3 Init DB   mydb
        3 Query DELETE FROM Devices WHERE isAndroid = 0 AND notificationId IN ('002B1C477DB4F20868D157A806DF70E05D61D3950562C03E092707CA9C5CCF23')

UPDATE # 2: Я попытался изменить инструкцию DELETE на инструкцию SELECT, используя то же предложение WHERE, и вот, строки не возвращаются. Таким образом, кажется, что сопоставление уведомлений по какой-то причине не работает. Может ли это быть проблема кодирования? Почему это работает на других клиентах, а не на моем клиенте Connector / NET?

1 Ответ

0 голосов
/ 10 ноября 2018

ОК, поэтому я обнаружил проблему после нескольких часов отладки. Оказывается, это не имеет ничего общего с Connector / NET. Проблема заключалась в том, как я создавал токены, я случайно добавил некоторые символы, которые не будут печататься в моем журнале log4net, так что SQL на клиентской стороне выглядел нормально, но фактическая строка SQL, отправленная на сервер базы данных, содержала недопустимые значения. жетоны!

...