powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как обойти баг при вставке с конвертацией?
21 сообщений из 21, страница 1 из 1
Как обойти баг при вставке с конвертацией?
    #39163443
Dron007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Требуется приводить строковые значения к числовым, чтобы без ошибок вставлялись в колонки числового типа. Если это невозможно, забивать NULL или 99999. Столкнулся с тем, что в SELECT всё работает, при INSERT выдаётся ошибка.

Код: sql
1.
CREATE TABLE test (val INT(5));



Код: sql
1.
SELECT CAST('1111111' AS DECIMAL(5,0));


99999

Код: sql
1.
2.
INSERT INTO test (val) 
SELECT CAST('1111111' AS DECIMAL(5,0));


Error Code: 1264
Out of range value for column 'CAST('1111111' AS DECIMAL(5,0))' at row 1

Код: sql
1.
SELECT CAST('a' AS DECIMAL(5,0));


0

Код: sql
1.
2.
INSERT INTO test (val) 
SELECT CAST('a' AS DECIMAL(5,0));


Error Code: 1292
Truncated incorrect DECIMAL value: 'a'

Если в первом случае ещё можно обойти, добавив LEFT('a', 5), то во втором это, ясное дело, не помогает. Здесь везде конкретные значения только для примера, так берутся значения из текстового поля другой таблицы.

Баг связан с параметром sql_mode. У меня "SELECT @@sql_mode" выдаёт
STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

Если сделать
Код: sql
1.
SET sql_mode='';


записи вставляет, хотя и выдаёт предупреждения. Но убирать ничего не хочется, если и обходить, то в коде конкретного запроса. Подскажите, может кто-то сталкивался и есть способ обойти? Ну не регулярным выражением же делать конвертацию - совсем тормоза будут.
Находил похожие баги, но там несколько другие сценарии и тоже нет воркэраудов:
http://bugs.mysql.com/bug.php?id=43437
http://bugs.mysql.com/bug.php?id=76353

Похожее вылазило с STR_TO_DATE(), тоже SELECT нормально показывал, а вставка его же уже не работала, но там получилось через LEFT() обойти.

Версия MySQL: 5.5.37, Win7 x64.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39163445
Dron007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Поправка:
"Если в первом случае ещё можно обойти, добавив LEFT('1111111', 5)"...
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39163447
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
least(MyValue+0, 99999)
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39163481
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dron007,


а почему бы и не регулярным выражением, с чего ты взял, что они такие медленные?
ты СУБД программируешь, она на диск пишет, по сравнению с этим многие операции очень быстры.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39163504
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dron007Баг
Знаешь, попытка всунуть в таблицу данные, которые не могут быть помещены в заданный тип - это никак не баг сервера, это баг либо разработчика структуры, либо источника данных для импорта.
Dron007Если в первом случае ещё можно обойти
Трындец подход... если данные не соответствуют типу поля, засунем туда что-нибудь...
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164201
Dron007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
tanglirleast(MyValue+0, 99999)

Не работает
Код: sql
1.
2.
INSERT INTO test (val) 
SELECT LEAST('a'+0, 99999);



Error Code: 1292
Truncated incorrect DOUBLE value: 'a'
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164203
Dron007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivа почему бы и не регулярным выражением, с чего ты взял, что они такие медленные?
ты СУБД программируешь, она на диск пишет, по сравнению с этим многие операции очень быстры.

На крайний случай придётся ими, но там тысячи записей, не хотелось вносить лишние накладные расходы.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164208
Dron007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AkinaЗнаешь, попытка всунуть в таблицу данные, которые не могут быть помещены в заданный тип - это никак не баг сервера, это баг либо разработчика структуры, либо источника данных для импорта.

Внимательно прочитали написанное? Не похоже. В таблицу как раз пытаюсь вставить уже данные приведенные к нужному типу и SELECT это показывает, так что это именно баг сервера.

Dron007Если в первом случае ещё можно обойти
Трындец подход... если данные не соответствуют типу поля, засунем туда что-нибудь...[/quot]
Вот зачем такую ерунду писать?
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164217
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dron007Ну не регулярным выражением же делать конвертацию - совсем тормоза будут.В MySQL нет регулярных выражений для модификации строк. Есть только для проверки.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164220
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dron007В таблицу как раз пытаюсь вставить уже данные приведенные к нужному типу и SELECT это показывает, так что это именно баг сервера.
То есть значение 1111111 ты наивно считаешь приведённым к типу DECIMAL(5,0)? Знаешь, мне жаль тебя огорчать...
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164225
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dron007Баг связан с параметром sql_mode. У меня "SELECT @@sql_mode" выдаёт
STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

Если сделать
Код: sql
1.
SET sql_mode='';



записи вставляет, хотя и выдаёт предупреждения. Но убирать ничего не хочется, если и обходить, то в коде конкретного запроса.Существует не только глобальная, но и сессионная переменная sql_mode. Используйте ее.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164500
Dron007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
miksoftВ MySQL нет регулярных выражений для модификации строк. Есть только для проверки.

Да, раньше не возникало надобности, мельком видел, что регэкспы есть, оказалось, есть да не те. А для замены просят уже чуть ли не 10 лет, а их так и не добавили. Но сделал пока так:
Код: sql
1.
IF(ne.season_number REGEXP '[a-zA-Z]', NULL, LEFT(ne.season_number, 5)),



Конечно, скорость от этого не повысится, но более-менее удовлетворительна.

miksoftСуществует не только глобальная, но и сессионная переменная sql_mode. Используйте ее.
Тоже вариант. Спасибо, подумаю.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164505
Dron007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AkinaТо есть значение 1111111 ты наивно считаешь приведённым к типу DECIMAL(5,0)? Знаешь, мне жаль тебя огорчать...
Вообще-то так считают разработчики, раз уж реализовали такое поведение в функции CAST. И меня оно бы вполне устраивало, если бы работало нормально и одинаково как в SELECT, так и в INSERT.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164512
Dron007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dron007AkinaТо есть значение 1111111 ты наивно считаешь приведённым к типу DECIMAL(5,0)? Знаешь, мне жаль тебя огорчать...
Вообще-то так считают разработчики, раз уж реализовали такое поведение в функции CAST. И меня оно бы вполне устраивало, если бы работало нормально и одинаково как в SELECT, так и в INSERT.

Вернее, из 1111111 получается 99999, которое и соответствует указанному типу.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164513
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dron007Вообще-то так считают разработчики, раз уж реализовали такое поведение в функции CAST. И меня оно бы вполне устраивало, если бы работало нормально и одинаково как в SELECT, так и в INSERT.
Включите вывод предупреждений. Повторите запросы из первого поста. Обдумайте результат.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164540
Dron007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AkinaВключите вывод предупреждений. Повторите запросы из первого поста. Обдумайте результат.

Ещё раз. Никаких предупреждений не выводится при селектах с указанными CAST. При этом во время INSERT уже идут ошибки. Не считаю такое поведение логичным. Не знаю, может в MySQL есть какие-то свои особенности использования преобразования типов. Обычно если уж преобразование справилось без ошибок и предупреждений, то это значение можно смело использовать где угодно.

Может вместо хамовитых назиданий предложите своё решение данной задачи?
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164732
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dron007,

да ладно вам ругаться....

уменьшим размер ненужной информации...вот что у меня:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
CREATE TABLE test.test01 (
  val int(5) DEFAULT NULL,
  val_int decimal(5, 0) DEFAULT NULL
)
ENGINE = INNODB
CHARACTER SET utf8
COLLATE utf8_general_ci;

INSERT INTO test01 (val_int) 
SELECT CAST('1111111' AS DECIMAL(5,0));

INSERT INTO test01 (val) 
SELECT CAST('1111111' AS DECIMAL(5,0));

D:\DB\mariadb\bin>mysql -uroot -p
Enter password: *****
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 5
Server version: 10.1.8-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> use test;
Database changed
MariaDB [test]> select version();
+----------------+
| version()      |
+----------------+
| 10.1.8-MariaDB |
+----------------+
1 row in set (0.00 sec)

MariaDB [test]> select * from test01;
+-------+---------+
| val   | val_int |
+-------+---------+
| 99999 |    NULL |
|  NULL |   99999 |
+-------+---------+
2 rows in set (0.00 sec);
MariaDB [test]> select @@sql_mode;
+--------------------------------------------+
| @@sql_mode                                 |
+--------------------------------------------+
| NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+--------------------------------------------+
1 row in set (0.00 sec)

MariaDB [test]>


уберите STRICT_TRANS_TABLES, оно вам не надо и все.
Наоборот, если надо STRICT_TRANS_TABLES для чего то - будете добавлять в сессии, а для работы это не надо.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164747
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex_Ustinov,

поле у вас INT вставка DECIMAL, попробуйте вставлять соответствующий тип,
может этот параметр STRICT_TRANS_TABLES и контролирует соответствие типов.
Мне проверять лень.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39164803
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dron007Никаких предупреждений не выводится при селектах с указанными CAST.
Это потому, что у кого-то отключен вывод предупреждений.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39165937
Dron007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alex_Ustinov,

Понял. STRICT_TRANS_TABLES выставлен в конфиге my.ini по умолчанию. Не хочется вводить требования к конфигурации и даже менять этот флаг на сессионном уровне, смешивая код и администрирование. Пока оставлю регэкспы, поправил их только слегка, чтобы на любые не-цифры срабатывало.
Код: sql
1.
          IF(TRIM(ne.season_number) REGEXP '^[0-9]{0,5}$', TRIM(ne.season_number), NULL),



Ворнинги выдавались, оказывается, просто SQL клиент (SQLYog) их в отдельной вкладке выводил, никак не сообщая про них. Мне всё-таки кажется крайне странным подобный подход, когда селект и инсерт работают по-разному при одних и тех же настройках. Логичнее по-моему или валиться с ошибкой на селекте уже или позволять и выборку и вставку. А то это как ты записал текст в переменную, проверяешь, всё ок, а хочешь сохранить в файл, пишет, не, не могу. Бред какой-то. Ну да ладно, решение найдено.
...
Рейтинг: 0 / 0
Как обойти баг при вставке с конвертацией?
    #39166209
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dron007Мне всё-таки кажется крайне странным подобный подход, когда селект и инсерт работают по-разному при одних и тех же настройках.
Да одинаково они работают! В случае SELECT даётся предупреждение, и этого достаточно - в выводе его МОЖНО игнорировать, т.к. вывод данных не влияет на хранимые данные. Но в случае INSERT игнорирование предупреждения невозможно, т.к. есть потенция неверного изменения данных - а посему предупреждение эквивалентно ошибке.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Как обойти баг при вставке с конвертацией?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]