Полученные данные неверного типа

Однажды один из моих друзей обратился ко мне за помощью. Он поведал мне, что столкнулся с проблемой при копировании изображений на свой USB-драйв. После копирования более 200 фотографий неожиданно возникла ошибка, после которой стало невозможным скопировать изображение и стало появляться следующее сообщение:


К сожалению, сообщение “Невозможно создать файл или папку” никоим образом не указывало на причину проблемы и не сообщало, где следует искать решение. Мой знакомый был весьма сообразительным, поэтому, прежде чем обратиться ко мне, проверил, что места на диске было предостаточно, но все-таки запустил утилиту Chkdsk для проверки памяти на повреждения. Однако, результатов это не дало, хотя ошибка продолжала неустанно появляться при попытке копирования изображений на флэш-драйв.

Я, со своей стороны, я попросил его запустить Process Monitor, утилиту, которая в реальном времени регистрирует все обращения к файловой системе и реестру, что теоретически позволяет определить причину различных сбоев и ошибок ОС. Затем он отправил мне отчет утилиты в формате PML и я открыл его. После установки фильтра по букве диска, а затем фильтра операций, относящихся непосредственно к копированию информации, я стал прочесывать отчет на наличие ошибок. Собственно, мне не потребовалось много времени, поскольку в последней строке отчета и была ошибка, вызывающая диалог системы:

С целью экономии пространства на рабочем столе компьютера Process Monitor добавляет к отображаемым ошибкам префикс “STATUS”, поэтому действительной системной ошибкой в данном случае являлась STATUS_CANNOT_MAKE. Лично я никогда не слышал и, тем более, не видел подобную ошибку. Кроме того, вместо имени ошибки Process Monitor показывал ее код — 0xc00002ea, поэтому пришлось поискать в файле Ntstatus.h из Windows Device Driver Kit, а затем добавить в Process Monitor функцию, конвертирующую коды ошибок в текст.

Тогда мне удалось отыскать ошибку в исходном коде Windows, но что насчет тех, кто не имеет возможности покопаться в исходном коде ОС. Как им решить данную проблему? Поиск привел меня к старой ветке в новостной группе для разработчиков файловой системы Windows:

Читайте также  Сколько надо проветривать комнату после разбитого градусника

Безусловно, раздел был отформатирован под файловую систему FAT и множество файлов, включая файлы с длиными именами, вполне могли использовать все доступные 512 корневых папок.

Проблему удалось-таки решить. Я посоветовал моему приятелю два варианта: 1) создать в корневой директории подпапку и скопировать оставшиеся файлы туда или 2) отформатировать флэш-драйв под файловую систему FAT32, что уберет ограничения по числу файлов/папок в корневой директории диска.

Тем не менее, один вопрос остался нерешенным. Почему диск был форматирован под FAT вместо FAT32? Причина кроется и в производителе USB-драйва и в диалоге форматирования, используемом в Windows. Я не уверен, но по-моему большинство производителей форматируют выпускаемые накопители под FAT, поскольку данная система гарантированно работает там, где другие файловые системы, как FAT32, не поддерживаются. Например в DOS 6 и Windows 95.

Что до Windows, то я всегда думал, что по умолчанию предлагается форматировать диск под FAT32, но диалог форматирования для одного из моих устройств показал, что это не так:

Здесь легко и интересно общаться. Присоединяйся!

позови специалиста. Я не телепат.

С начала угадать модель телефона.
Потом угадать что за файлы.
А потом .

Качать файлы с расширением, которое способен открывать плеер . Читай описание плеера .

Мы научились находить проблемный запрос.

Мы уже рассмотрели 2 примера синтаксической ошибки и один пример логической. Охватывают ли эти примеры все возможности, предоставляемые нам анализом проблемного запроса? Конечно, нет! Хотя строго говоря все ошибки в запросе можно свести к этим двум подтипам. В этой главе мы рассмотрим что ещё можно сделать с проблемным запросом.

Синтаксические ошибки тривиальны, поэтому мы далее не будем на них останавливаться.

Одна из часто встречающихся проблем — запрос SELECT возвращает неверные данные. Это может происходить по ряду причин.

Рассмотрим простейший — с точки зрения устранения — пример.

mysql> select count(*) as b from t3 order by b,a;
+—+
| b |
+—+
| 2 |
| 2 |
+—+

Читайте также  Программа для просмотра нагрузки процессора

mysql> select count(*) as b from t3;
+—+
| b |
+—+
| 2 |
+—+
1 row in set (0.01 sec)

mysql> show create table t3G
************ 1. row ************
Table: t3
Create Table: CREATE TABLE `t3` (
`a` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

Несмотря на необычность запроса поведение явно неверное: count(*) не может возвращать более одной строчки, если не использован GROUP BY. Запрос тривиален и упрощать его некуда. В этом случае ваш путь по адресу http://bugs.mysql.com, в поиск, где мы и находим соответствующий баг: http://bugs.mysql.com/bug.php? >

Само собой разумеется, если бага, подобного обнаруженного вами, нет, нужно его послать по тому же адресу http://bugs.mysql.com

Но что делать, если вы не можете в данный момент обновить MySQL сервер? В данном случае убрать order by. Данный пример демонстрирует не только то, что MySQL Server тоже содержит баги в коде, но и ещё один метод работы с проблемным запросом.

Приём №3: после того как вы выявили запрос, вызывающий проблемы, запустите его в командной строке и проанализируйте полученный результат.

Но существуют и баги с workaround, не требующими модификации SQL. Как правило если workaround не очевиден он описан в bug report.

Возьмём следующий пример:

mysql> create table `a` (
-> `id` bigint(20) not null auto_increment,
-> primary key (`id`)
-> ) engine=myisam;
Query OK, 0 rows affected (0.04 sec)

mysql> create table `b` (
-> `id` bigint(20) not null auto_increment,
-> `a_id` bigint(20) default null,
-> primary key (`id`)
-> ) engine=myisam;
Query OK, 0 rows affected (0.04 sec)

mysql> insert into `a` values (1),(2),(3),(4),(5),(6),(7),(8);
Query OK, 8 rows affected (0.00 sec)
Records: 8 Duplicates: 0 Warnings: 0
mysql> insert into `b` values (1,1),(2,1),(3,1),(4,2),(5,2),(6,2),(7,3),(8,3);
Query OK, 8 rows affected (0.01 sec)
Records: 8 Duplicates: 0 Warnings: 0

mysql> select a. > -> where a. > +——+——+
| a_id | cnt |
+——+——+
| 1 | 8 |
| NULL | 8 |
+——+——+
2 rows in set (0.01 sec)

Откуда у нас 8 строк в a_ >

Что и подтвержает последующий запрос уже без группировок.

Читайте также  Самсунг интернет браузер история

Но здесь имеется workaround:

mysql> alter table b add index(a_id);
Query OK, 8 rows affected (0.05 sec)
Records: 8 Duplicates: 0 Warnings: 0

mysql> select a. > -> where a. > +——+——+
| a_id | cnt |
+——+——+
| 1 | 3 |
| NULL | 3 |
+——+——+
2 rows in set (0.02 sec)

Как вы могли убедиться результат теперь правильный.

Приём №4: пробуйте изменить SQL таким образом, чтобы результат был правильным. Пользуйтесь поисковыми системами для нахождения workaround.

Случаи с багами в коде MySQL хоть и легки для устранения, всё-таки встречаются гораздо реже, чем баги в SQL коде пользователя.

Что же делать, чтобы определить почему запрос SELECT работает не так как ожидается?

mysql> create table t1(f1 int);
Query OK, 0 rows affected (0.01 sec)
mysql> create table t2(f2 int);
Query OK, 0 rows affected (0.08 sec)
mysql> insert into t1 values(1);
Query OK, 1 row affected (0.01 sec)

mysql> select * from t1;
+——+
| f1 |
+——+
| 1 |
+——+
1 row in set (0.00 sec)

Почему SELECT из двух таблиц возвращает пустой набор, хотя строки в таблице t1 существуют?

На помощь на приходит EXPLAIN EXTENDED:

mysql> W
Show warnings enabled.

Note (Code 1003): select ‘1’ AS `f1`,’0′ AS `f2` from `test`.`t1` join `test`.`t2`

Как вы видите, запрос преобразован в запрос с JOIN, который является синонимом INNER JOIN и который не может вернуть строки из табицы t1, если в таблице t2 нет соответствующих строк. Так как таблица t2 не содержит записей, запрос ничего и не возвращает.

Для более сложных (длинных) запросов алгоритм подобный: запустить EXPLAIN EXTENDED, если ошибка не выявлена, то разбить или упростить запрос, повторить.

EXPLAIN также поможет, если ваш запрос выполняется очень долго, хотя и возвращает верные данные. Мы не будем здесь подробно на этом останавливаться, поскольку данная возможность хорошо описана в официальном MySQL User Manual. Смотрите соответствующие главы.

Приём №5: используйте EXPLAIN EXTENDED для того, чтобы понять каким образом оптимизируется (а значит и выполняется) SQL запрос.

Ссылка на основную публикацию
Adblock
detector