Ошибка выполнения DBD::mysql::st: неизвестный столбец

Когда я выполняю приведенный ниже запрос из консоли mysql, он работает нормально, но когда я перехожу в perl/DBI, я получаю:

DBD::mysql::st execute failed: Unknown column 'AR_email' in 'field list'

Вот запрос:

my $q = "SELECT SUBSTRING(AR_email, LOCATE('@', AR_email) + 1) AS domain  
         FROM carrier 
         WHERE AR_email IS NOT NULL 
         AND SUBSTRING(AR_email, LOCATE('@', AR_email) + 1) =?"; 
my $sth=$dbh->prepare($q);
$sth->execute($domain);

Любая идея, как я могу это исправить?


person gatorreina    schedule 17.02.2020    source источник


Ответы (1)


Проблема заключается в непреднамеренной интерполяции строк.

Вы используете двойные кавычки (") при назначении строки запроса для $q, но она содержит аробас (@), который интерполируется.

Таким образом, $q на самом деле содержит:

SELECT SUBSTRING(AR_email, LOCATE(', AR_email) + 1) AS domain
FROM carrier
WHERE AR_email IS NOT NULL
AND SUBSTRING(AR_email, LOCATE(', AR_email) + 1) =?

Если бы вы запускали это под use warnings, вы бы получили это сообщение:

Possible unintended interpolation of @' in string

Один из способов решить эту проблему — определить запрос как литеральную строку, например:

my $q = q/SELECT SUBSTRING(AR_email, LOCATE('@', AR_email) + 1) AS domain  
         FROM carrier 
         WHERE AR_email IS NOT NULL 
         AND SUBSTRING(AR_email, LOCATE('@', AR_email) + 1) =?/; 

Мораль истории:

  • используйте двойные кавычки, только если вы делаете интерполяцию строк

  • всегда use strict; use warnings;

person GMB    schedule 17.02.2020
comment
Большое спасибо за не только правильный, но и очень поучительный ответ. Объяснение, вероятно, поможет мне не допустить подобной ошибки в будущем. - person gatorreina; 17.02.2020
comment
Другой вариант (или в сочетании с одинарными кавычками/одинарными q) — указать строку @ в качестве параметра, подобного вашему $domain. LOCATE(?, AR_email) в обоих случаях, затем передайте параметры '@', '@', $domain для выполнения. - person Grinnz; 18.02.2020