【问题标题】:Script gives database error on just one system脚本仅在一个系统上给出数据库错误
【发布时间】:2018-04-01 09:15:17
【问题描述】:

我是一名 VOIP 管理员,我有用于在 Perl 中更新目录数据库的脚本,该脚本是在我受雇之前从供应商处购买的。

脚本在所有服务器上都运行良好,除了一个。

#!/usr/bin/perl
use lib "/opt/asterisk/lib/";
use DBI;
use Asterisk::config;
sub trim($);
# database information
$db="kesc";
$host="sip-ho.kesc.com.pk";
$userid="foo";
$passwd="bar";
$connectionInfo="dbi:mysql:$db;$host";
$hubname = "";

# make connection to database
$dbh = DBI->connect($connectionInfo,$userid,$passwd);
# Perl trim function to remove whitespace from the start and end of the string
sub trim($)
{
    my $string = shift;
    $string =~ s/^\s+//;
    $string =~ s/\s+$//;
    return $string;
}

my $rc = new Asterisk::config  (file=>'/etc/asterisk/sip.conf',keep_resource_array=>0);
@list = $rc->fetch_sections_list();
$n = 1;
foreach (@list)
{
    if ($_ ne "general") {

        $entry = $rc->fetch_keys_hashref(section=>$_);
        while ( my ($key, @value) = each(%$entry) )
        {
            if ($key eq "callerid") {
                @vars = split('<',$value[0][0]);
                $query = "insert into directory (extension,name,hub) values (" . trim($_) . ", '" . trim($vars[0]) . "', '$hubname') ON DUPLICATE KEY UPDATE hub='$hubname'";
                $sth = $dbh->prepare($query);
                $sth->execute();
            }
        }
    }
    $n++;
}

现在我在执行时遇到下面提到的错误。

DBD::mysql::st 执行失败:您的 SQL 语法有错误; 查看与您的 MySQL 服务器版本相对应的手册,以了解在 ./directory 第 39 行的第 1 行的 's Office', '') ON DUPLICATE KEY UPDATE hub=''' 附近使用的正确语法。

我还用相同的 MySQL 版本替换了其他服务器,它可以完美运行。

请指导我。

【问题讨论】:

  • 听起来你有语法错误。请edit您的问题并显示执行数据库查询的 Perl 代码。它可能不使用占位符,而是将输入直接插入到 SQL 字符串中。如果输入包含未转义的字符,或者可能完全丢失,因为在此过程中出现了其他问题,这可能就是原因。见xkcd.com/327。另一个原因可能是表 DDL 缺少查询所引用的唯一/主键。
  • 已完成,但相同的代码可在所有其他服务器上运行。
  • 请编辑您的问题以显示 ./directory 的前 80 行。猜测一下,代码将变量插入到 SQL 语句中,而不是按应有的方式使用占位符,并且其中一个变量中的字符串包含一个单引号,它会抛出 SQL 中的引号。理想情况下,您应该更改代码以使用占位符,但您可以在插入字符串之前转义字符串中的任何引号字符。
  • @Sherjeel:我已经修复了您代码中的缩进。不客气,但请以后自己做。良好的缩进是理解代码的重要工具,如果您希望一大群陌生人阅读和理解您的代码,那么让他们尽可能简单是礼貌的。

标签: mysql database perl centos


【解决方案1】:

感谢您提供代码。正如我所怀疑的那样;你真的不应该将值直接插入到 SQL 语句中

将第 37、38 和 39 行更改为此,它应该适合你

$query = 'INSERT INTO directory (extension, name, hub) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE hub = ?';
$sth   = $dbh->prepare($query);
$sth->execute( trim($_), trim($vars[0]), $hubname, $hubname );

请注意,代码库中的其他地方可能存在相同的问题,因此确实应该对其进行全面审查

【讨论】:

  • 感谢错误消失了,尽管出现错误,旧代码仍在插入。 :) 谢谢你@Borodin
猜你喜欢
  • 1970-01-01
  • 2018-02-17
  • 2019-07-13
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 2018-09-12
  • 1970-01-01
相关资源
最近更新 更多