Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无法使用DBI将记录插入MySQL数据库_Mysql_Perl_Cgi_Dbi - Fatal编程技术网

无法使用DBI将记录插入MySQL数据库

无法使用DBI将记录插入MySQL数据库,mysql,perl,cgi,dbi,Mysql,Perl,Cgi,Dbi,我正在尝试使用Perl DBI将记录插入MySQL数据库。我没有收到任何错误,但插入不起作用。但是,我能够使用DBI成功地从数据库中获取记录 以下是执行插入操作的代码: #!"C:\xampp\perl\bin\perl.exe" use diagnostics; use DBI; use strict; use warnings; my $driver = "mysql"; my $database = "mysql"; my $dsn = "DBI:$driver:database=$

我正在尝试使用Perl DBI将记录插入MySQL数据库。我没有收到任何错误,但插入不起作用。但是,我能够使用DBI成功地从数据库中获取记录

以下是执行插入操作的代码:

#!"C:\xampp\perl\bin\perl.exe"

use diagnostics;
use DBI;
use strict;
use warnings;

my $driver = "mysql"; 
my $database = "mysql";
my $dsn = "DBI:$driver:database=$database";
my $userid = "root";
my $password = "password";

my $buffer;
my @pairs;
my $pair;
my $name;
my $value;
my %FORM;

# Read in text
my $ENV;
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
if ($ENV{'REQUEST_METHOD'} eq "GET")
{
    $buffer = $ENV{'QUERY_STRING'};
}

# Split information into name/value pairs
@pairs = split(/&/, $buffer);
foreach $pair (@pairs)
{
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%(..)/pack("C", hex($1))/eg;
    $FORM{$name} = $value;
}

my $first_name= $FORM{name};
my $address = $FORM{address};
my $city  = $FORM{city};
my $occupation  = $FORM{occupation};
my $age  = $FORM{age};

my $dbh = DBI->connect("dbi:mysql:dbname=mysql", "root", "password",{ AutoCommit =>  0,RaiseError => 1}, ) or die ("Couldn't connect to database: ") , $DBI::errstr;

# my $sth = $dbh->prepare("INSERT INTO persons
                        # (FirstName, LastName,Address,City)
                        # values
                        # ($first_name, $last_name,$address,$city)");
my $query = "insert into userrecords(Address,Age,City,Name,Occupation)
             values (?, ?, ?, ?, ?) ";

my $statement = $dbh->prepare($query) or die ("Couldn't connect to database: "), $DBI::errstr;
$statement->execute($address,$age,$city,$name,$occupation) or die ("Couldn't connect to database: "), $DBI::errstr;

$dbh->disconnect();

my $URL = "http://.....:81/cgi-bin/showdata.cgi";
print "Location: $URL\n\n";

exit(0);
在Padre IDE中运行代码时,出现以下错误:

****Error*********
Useless use of a variable in void context at InsertRecord.cgi line 50 (#1)
    (W void) You did something without a side effect in a context that does
    nothing with the return value, such as a statement that doesn't return a
    value from a block, or the left side of a scalar comma operator.  Very
    often this points not to stupidity on your part, but a failure of Perl
    to parse your program the way you thought it would.  For example, you'd
    get this if you mixed up your C precedence with Python precedence and
    said

        $one, $two = 1, 2;

    when you meant to say

        ($one, $two) = (1, 2);

    Another common error is to use ordinary parentheses to construct a list
    reference when you should be using square or curly brackets, for
    example, if you say

        $array = (1,2);

    when you should have said

        $array = [1,2];

    The square brackets explicitly turn a list value into a scalar value,
    while parentheses do not.  So when a parenthesized list is evaluated in
    a scalar context, the comma is treated like C's comma operator, which
    throws away the left argument, which is not what you want.  See
    perlref for more on this.

    This warning will not be issued for numerical constants equal to 0 or 1
    since they are often used in statements like

        1 while sub_with_side_effects();

    String constants that would normally evaluate to 0 or 1 are warned
    about.

Useless use of a variable in void context at InsertRecord.cgi line 59 (#1)
Useless use of a variable in void context at InsertRecord.cgi line 60 (#1)

Use of uninitialized value in transliteration (tr///) at InsertRecord.cgi line
        23 (#2)
    (W uninitialized) An undefined value was used as if it were already
    defined.  It was interpreted as a "" or a 0, but maybe it was a mistake.
    To suppress this warning assign a defined value to your variables.

    To help you figure out what was undefined, perl will try to tell you the
    name of the variable (if any) that was undefined. In some cases it cannot
    do this, so it also tells you what operation you used the undefined value
    in.  Note, however, that perl optimizes your program and the operation
    displayed in the warning may not necessarily appear literally in your
    program.  For example, "that $foo" is usually optimized into "that "
    . $foo, and the warning will refer to the concatenation (.) operator,
    even though there is no . in your program.

Use of uninitialized value $ENV{"REQUEST_METHOD"} in string eq at
        InsertRecord.cgi line 24 (#2)
Use of uninitialized value $buffer in split at InsertRecord.cgi line 29 (#2)
Location: http://.......:81/cgi-bin/showdata.cgi

Press any key to continue . . .

***********END***********************

问题是什么?

当我编辑您的代码以使其更具可读性时,我偶然发现了我认为的解决方案:

插入数据库时使用的是
$name
,但获取值
$FORM{name}
时使用的是
$first\u name
。因此,由于您在上面使用了
$name
,因此它具有所使用的姓氏的值,不管是什么。相关代码片段:

($name, $value) = split(/=/, $pair);
...
$FORM{$name} = $value;
...
my $first_name = $FORM{name};
...
$statement->execute($address,$age,$city,$name,$occupation)
#                                       ^^^^^--- should be $first_name
如果您对变量使用了适当的作用域,您的问题就会得到解决,即:

 foreach my $pair (@pairs) {
     my ($name, $value) = split(/=/, $pair);
     $value =~ tr/+/ /;
     $value =~ s/%(..)/pack("C", hex($1))/eg;
     $FORM{$name} = $value;
 }
or die ("Couldn't connect to database:  $DBI::errstr");
然后,当您稍后尝试使用
$name
时,您将得到错误

Global variable "$name" requires explicit package name ...
这将提醒您注意错误并节省您数小时的调试时间。当您在脚本顶部而不是在尽可能小的范围内声明变量时,您将有效地禁用
使用严格的“vars”
提供的保护。所以不要那样做

此外,您可能应该使用该模块,而不是尝试手动处理它。这将使事情变得更容易、更安全。不要忘记对数据执行健全性检查以防止数据库注入攻击


您的脚本在清理并正确格式化后看起来像

当我编辑您的代码以使其更具可读性时,我偶然发现了我认为的解决方案:

插入数据库时使用的是
$name
,但获取值
$FORM{name}
时使用的是
$first\u name
。因此,由于您在上面使用了
$name
,因此它具有所使用的姓氏的值,不管是什么。相关代码片段:

($name, $value) = split(/=/, $pair);
...
$FORM{$name} = $value;
...
my $first_name = $FORM{name};
...
$statement->execute($address,$age,$city,$name,$occupation)
#                                       ^^^^^--- should be $first_name
如果您对变量使用了适当的作用域,您的问题就会得到解决,即:

 foreach my $pair (@pairs) {
     my ($name, $value) = split(/=/, $pair);
     $value =~ tr/+/ /;
     $value =~ s/%(..)/pack("C", hex($1))/eg;
     $FORM{$name} = $value;
 }
or die ("Couldn't connect to database:  $DBI::errstr");
然后,当您稍后尝试使用
$name
时,您将得到错误

Global variable "$name" requires explicit package name ...
这将提醒您注意错误并节省您数小时的调试时间。当您在脚本顶部而不是在尽可能小的范围内声明变量时,您将有效地禁用
使用严格的“vars”
提供的保护。所以不要那样做

此外,您可能应该使用该模块,而不是尝试手动处理它。这将使事情变得更容易、更安全。不要忘记对数据执行健全性检查以防止数据库注入攻击


当清理并正确格式化脚本时,脚本看起来就像用以下代码替换代码时发生的情况:

#!"C:\xampp\perl\bin\perl.exe"
use strict;
use warnings;

use diagnostics;
use DBI;
use CGI qw[param redirect];    

my $driver   = "mysql"; 
my $database = "mysql";
my $dsn      = "DBI:$driver:database=$database";
my $userid   = "root";
my $password = "password";

my $dbh = DBI->connect("dbi:mysql:dbname=mysql", "root", "password",
    { AutoCommit =>  0,RaiseError => 1}, )
    or die "Couldn't connect to database: ", $DBI::errstr;

my $query = "insert into userrecords(Address,Age,City,Name,Occupation)
values (?, ?, ?, ?, ?) ";

my $statement = $dbh->prepare($query)
    or die "Couldn't connect to database: " , $DBI::errstr;
$statement->execute(param('address'), param('age'), param('city'),
                    param('name'), param('occupation'))
    or die "Couldn't connect to database: " , $DBI::errstr;    
$dbh->disconnect();

my $URL = "http://.....:81/cgi-bin/showdata.cgi";
print redirect($URL);
我基本上做了两个改变:

  • 使用CGI.pm模块处理CGI交互(获取参数并打印重定向头)
  • 通过删除对
    die
    的所有调用中放错的括号,修复了“void context”错误
  • 我没有对代码做任何实质性的更改,但至少我们现在有了一个干净的版本


    更新:D'oh。很明显,现在代码已经清理了一点。如果关闭了“自动提交”,则需要提交更改。在对
    execute()
    disconnect()
    的调用之间添加
    $dbh->commit

    用以下代码替换代码时会发生什么:

    #!"C:\xampp\perl\bin\perl.exe"
    use strict;
    use warnings;
    
    use diagnostics;
    use DBI;
    use CGI qw[param redirect];    
    
    my $driver   = "mysql"; 
    my $database = "mysql";
    my $dsn      = "DBI:$driver:database=$database";
    my $userid   = "root";
    my $password = "password";
    
    my $dbh = DBI->connect("dbi:mysql:dbname=mysql", "root", "password",
        { AutoCommit =>  0,RaiseError => 1}, )
        or die "Couldn't connect to database: ", $DBI::errstr;
    
    my $query = "insert into userrecords(Address,Age,City,Name,Occupation)
    values (?, ?, ?, ?, ?) ";
    
    my $statement = $dbh->prepare($query)
        or die "Couldn't connect to database: " , $DBI::errstr;
    $statement->execute(param('address'), param('age'), param('city'),
                        param('name'), param('occupation'))
        or die "Couldn't connect to database: " , $DBI::errstr;    
    $dbh->disconnect();
    
    my $URL = "http://.....:81/cgi-bin/showdata.cgi";
    print redirect($URL);
    
    我基本上做了两个改变:

  • 使用CGI.pm模块处理CGI交互(获取参数并打印重定向头)
  • 通过删除对
    die
    的所有调用中放错的括号,修复了“void context”错误
  • 我没有对代码做任何实质性的更改,但至少我们现在有了一个干净的版本


    更新:D'oh。很明显,现在代码已经清理了一点。如果关闭了“自动提交”,则需要提交更改。在对
    execute()
    disconnect()
    的调用之间添加
    $dbh->commit
    ,警告来自:

    or die ("Couldn't connect to database: ") , $DBI::errstr;
    
    ,$DBI::errstr
    在die之外,不做任何处理,因此处于void上下文中。你想要这样的东西:

     foreach my $pair (@pairs) {
         my ($name, $value) = split(/=/, $pair);
         $value =~ tr/+/ /;
         $value =~ s/%(..)/pack("C", hex($1))/eg;
         $FORM{$name} = $value;
     }
    
    or die ("Couldn't connect to database:  $DBI::errstr");
    
    此外,表单处理代码也存在一些问题。如果您正在编写CGI脚本,那么也可以使用
    CGI
    模块。下面是对代码的快速清理:

    #!"C:\xampp\perl\bin\perl.exe"
    use diagnostics;
    use CGI ':standard';
    use DBI;
    use strict;
    use warnings;
    
    my $driver   = "mysql";
    my $database = "mysql";
    my $dsn      = "DBI:$driver:database=$database";
    my $userid   = "root";
    my $password = "password";
    
    my $name       = param('name');
    my $address    = param('address');
    my $city       = param('city');
    my $occupation = param('occupation');
    my $age        = param('age');
    
    my $dbh = DBI->connect( $dsn, $userid, $password,
        { AutoCommit => 1, RaiseError => 1 },
    ) or die("Couldn't connect to database: $DBI::errstr");
    
    my $query = <<'END';
    INSERT INTO userrecords(Address,Age,City,Name,Occupation)
                    VALUES (      ?,   ?,  ?,    ?,        ?)
    END
    
    my $statement = $dbh->prepare($query);
    $statement->execute( $address, $age, $city, $name, $occupation );
    $dbh->disconnect();
    
    my $URL = "http://.....:81/cgi-bin/showdata.cgi";
    print "Location: $URL\n\n";
    
    #!“C:\xampp\perl\bin\perl.exe”
    使用诊断;
    使用CGI“:标准”;
    使用DBI;
    严格使用;
    使用警告;
    my$driver=“mysql”;
    my$database=“mysql”;
    my$dsn=“DBI:$driver:database=$database”;
    我的$userid=“root”;
    我的$password=“password”;
    我的$name=param('name');
    我的$address=param(“地址”);
    my$city=param(“城市”);
    我的$occupation=param(“职业”);
    我的$age=param('age');
    my$dbh=DBI->connect($dsn、$userid、$password、,
    {AutoCommit=>1,RaiseError=>1},
    )或者死亡(“无法连接到数据库:$DBI::errstr”);
    my$query=execute($address、$age、$city、$name、$occupation);
    $dbh->disconnect();
    我的$URL=”http://.....:81/cgi-bin/showdata.cgi”;
    打印“位置:$URL\n\n”;
    
    请注意,我删除了许多
    或die
    语句,因为您已经将
    RaiseError
    设置为真值


    为了简单起见,我还(不情愿地)打开了
    自动提交

    警告如下:

    or die ("Couldn't connect to database: ") , $DBI::errstr;
    
    ,$DBI::errstr
    在die之外,不做任何处理,因此处于void上下文中。你想要这样的东西:

     foreach my $pair (@pairs) {
         my ($name, $value) = split(/=/, $pair);
         $value =~ tr/+/ /;
         $value =~ s/%(..)/pack("C", hex($1))/eg;
         $FORM{$name} = $value;
     }
    
    or die ("Couldn't connect to database:  $DBI::errstr");
    
    此外,表单处理代码也存在一些问题。如果您正在编写CGI脚本,那么也可以使用
    CGI
    模块。下面是对代码的快速清理:

    #!"C:\xampp\perl\bin\perl.exe"
    use diagnostics;
    use CGI ':standard';
    use DBI;
    use strict;
    use warnings;
    
    my $driver   = "mysql";
    my $database = "mysql";
    my $dsn      = "DBI:$driver:database=$database";
    my $userid   = "root";
    my $password = "password";
    
    my $name       = param('name');
    my $address    = param('address');
    my $city       = param('city');
    my $occupation = param('occupation');
    my $age        = param('age');
    
    my $dbh = DBI->connect( $dsn, $userid, $password,
        { AutoCommit => 1, RaiseError => 1 },
    ) or die("Couldn't connect to database: $DBI::errstr");
    
    my $query = <<'END';
    INSERT INTO userrecords(Address,Age,City,Name,Occupation)
                    VALUES (      ?,   ?,  ?,    ?,        ?)
    END
    
    my $statement = $dbh->prepare($query);
    $statement->execute( $address, $age, $city, $name, $occupation );
    $dbh->disconnect();
    
    my $URL = "http://.....:81/cgi-bin/showdata.cgi";
    print "Location: $URL\n\n";
    
    #!“C:\xampp\perl\bin\perl.exe”
    使用诊断;
    使用CGI“:标准”;
    使用DBI;
    严格使用;
    使用警告;
    我的$dri