Комментарии MySQL, вызывающие путаницу в подсчете параметров связывания с Perl DBI

У меня есть следующий код Perl, который выполняет вызов DBI:

my $artsql = q{ *** SNIP A BUNCH OF SQL ***
                where a.article_id != ?
                      and at.type_name != 'List Element'   -- don't get list children
                      and aw.flowstate = 'Published'
                      and a.visible_as_article = 1 }
      . ( $filter ? q{and ch.channel_id = ?
                      and cat.category_id = ? }
                  : '' ) 
         . q{order by a.publish_date desc
                limit 5};

my @bind = ( $article );
push @bind, ( $channel_id, $category_id ) if $filter;

my $articles = $dbh->selectall_arrayref( $artsql, { Slice => { } }, @bind );

Когда $filter включен, этот код умирал с ошибкой:

DBD::mysql::db selectall_arrayref failed: called with 3 bind variables when 1 are needed

Сначала я подумал, что это проблема с троичным условным выражением в середине строки (эта ошибка меня кусала несколько раз), но это было правильно. Сброс некоторых значений отладки показывает, что запрос и массив @bind были построены правильно.

Затем я заметил, что в запросе есть комментарий SQL сразу после переменной связывания first, поэтому по прихоти я удалил его. Пуф, это сработало!

Согласно документации по комментариям MySQL,

Сервер MySQL поддерживает три стиля комментариев: от символа «#» до конца строки. От последовательности «-» до конца строки. В MySQL стиль комментария> «-» (двойное тире) требует, чтобы за вторым тире следовал по крайней мере один пробел или управляющий символ (например, пробел, табуляция, новая строка и т. Д.).

Поскольку в комментарии был --, за которым следует пробел и (предположительно) он заканчивался концом строки, почему MySQL захлебнулся? DBI делает что-то странное с символами новой строки или пробелами за кулисами?


person friedo    schedule 08.01.2010    source источник


Ответы (3)


Кажется, что с вашим кодом SQL или Perl что-то не так.

Это может быть ошибка в DBI, DBD :: mysql или в самом MySQL. Первым шагом в отладке этой проблемы было бы выяснить, какой бит неисправен. Итак, начнем с исключения переменных.

Начните с исключения связываемых переменных, жестко запрограммируйте некоторые значения и посмотрите, правильно ли выполняется процесс. Если нет, то, вероятно, это ошибка в DBD :: mysql или DBI. Сначала попробуйте обновить их оба и посмотрите, решена ли проблема. Если это не сработает, сообщите об ошибке. Обратите внимание, что есть аналогичная ошибка синтаксического анализа комментариев, так что это вполне может быть DBD :: mysql. (Вы уверены, что это do not get list children, а не don't get list children?)

Затем удалите Perl из уравнения. Запустите запрос в оболочке mysql (используйте \ e, чтобы открыть редактор). У него такая же проблема? Если так, то виноват MySQL. Опять попробуйте обновить.

person Schwern    schedule 08.01.2010
comment
Я думаю, что вы правы насчет ' в комментарии; Я проверил журнал ревизий, и в оригинале было написано don't, которое было пропущено между копированием и вставкой и форматированием на моем OP. Я протестирую это, чтобы быть уверенным. - person friedo; 09.01.2010

Я видел подобное в других местах. Скорее всего, произошло то, что где-то на разных уровнях (Шверн прав, вам придется покопаться, чтобы увидеть, какой из них) какой-то фрагмент кода преобразует символы новой строки в пробелы, что в то время должно было казаться законной причиной, и так что ваш комментарий занимает всю остальную часть запроса.

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

person Dan    schedule 09.01.2010

Одиночные кавычки внутри комментария все портят. Не знаю, что вызывает эту ошибку. Измените «не заводить последнего ребенка» на «не заводить последнего ребенка», и ваша проблема исчезнет.

person Anna Graham    schedule 16.03.2010