【问题标题】:Update db row with perl cgi使用 perl cgi 更新 db 行
【发布时间】:2019-05-14 03:08:25
【问题描述】:

我正在尝试使用输入到用户中的一些新值来更新我的 sql 表。由于某种原因,sql 命令没有更新我的数据库。我得到了我验证的正确值。这是我的代码

#!/usr/bin/perl 
#This is going to be the user login check and will set a cookie

use DBI;
use CGI qw(:standard);

use strict;

#Connection error 
sub showErrorMsgAndExit {
    print header(), start_html(-title=>shift);
    print (shift);
    print end_html();
    exit;
}

#Connecting to the database
my $dbUsername = "root";
my $dbPassword = "password";

my $dsn = "DBI:mysql:f18final:localhost";
my $dbh = DBI->connect($dsn, $dbUsername, $dbPassword, {PrintError => 0});

#error checking
if(!$dbh) {
    print header(), start_html(-title=>"Error connecting to DB");
    print ("Unable to connec to the database");
    print end_html();
    exit;
}

print header;
print start_html(-title=>'Add Classes');

#Get the information the user entered
my $id = param('classid');
my $className = param('classname');
my $department = param('department');
my $classnum = param('classnum');
my $grade = param('grade');
my $credits = param('credit');
print "$id $className, $department, $classnum, $grade, $credits";
#first sql check to see if username is already taken
my $check = "UPDATE tblclasses(classname, department, classnum, grade, credits) VALUES (?, ?, ?, ?, ?) WHERE classID = $id";
my $sth = $dbh->prepare($check);
$sth->execute($className, $department, $classnum, $grade,$credits);
print "<h1>Success</h1>";
print "<form action=http://localhost/cgi-bin/edit.pl method = 'post'>";
print "<input type = 'submit' name = 'submit' value = 'Update Another'>";
print "</form>";
print "<form action=http://localhost/cgi-bin/actions.pl method = 'post'>";
print "<input type = 'submit' name = 'submit' value = 'Back to actions'>";
print "</form>";


print end_html();
exit;

当我尝试在 mysql 工作台中运行 sql 命令时,它成功地更新了行。我的问题是什么?

【问题讨论】:

  • 您需要在 DBI 构造函数中设置 RaiseError => 1 以便将错误作为您可以在日志中看到的异常抛出(简单选项),或者自己检查每个 connect 的错误和 prepareexecute 以及 DBI 文档中描述的其他 DBI 调用。
  • 以防万一这是一个新项目而您不知道,much better alternatives to CGI.pm 甚至仅用于 CGI 脚本。否则请随意忽略此评论。

标签: mysql sql perl cgi dbi


【解决方案1】:

您的 SQL 语句的语法有错误:

UPDATE tblclasses(classname, department, classnum, grade, credits) 
VALUES (?, ?, ?, ?, ?)
WHERE classID = $id

应该写成:

UPDATE tblclasses
SET classname = ?, 
       department = ?,
       classnum = ?,
       grade = ?,
       credits = ?
WHERE classID = ?

the mysql docs

旁注(@Grinnz 也评论过):

  • 您应该始终«使用严格»

  • 您应该在您的数据库或语句句柄上将 DBI 属性 « RaiseError » 设置为 1;因此所有 DBI 错误都变得致命;同时禁用 «RaiseError» 和 «PrintError» 会导致 DBI 既不会死于错误也不会报告错误,因此您必须手动检查每个 DBI 调用的返回码以确保其正常工作 - 请参阅 the DBI docs

  • 你应该在你的 SQL 语句中绑定所有变量以使 SQL 注入无效(你没有绑定 $id,我在上面的查询中更改了它)

【讨论】:

    【解决方案2】:

    在不知道 DBMS 的情况下,我不能 100% 确定,但看起来好像您混合了插入和更新命令的语法。更新的正确语法应该是:

    UPDATE tblclasses
    set
      classname = ?,
      department = ?,
      classum = ?,
      grade = ?,
      credits = ?
    WHERE classID = $id
    

    此外,对于它的价值,您还应该能够将$id 变量也作为参数传递,而不是对其进行插值。从理论上讲,这将对数据库更友好,因为它将编译一次并一遍又一遍地执行相同的 SQL 语句,只是使用不同的绑定变量值:

    my $check = qq{
      UPDATE tblclasses
      set
        classname = ?,
        department = ?,
        classum = ?,
        grade = ?,
        credits = ?
      WHERE classID = ?
    };
    
    my $sth = $dbh->prepare($check);
    $sth->execute($className, $department, $classnum, $grade,$credits, $id);
    

    【讨论】:

      猜你喜欢
      • 2019-05-14
      • 1970-01-01
      • 2017-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-22
      • 2013-05-02
      • 2015-06-26
      相关资源
      最近更新 更多