简体   繁体   English

Perl,SQL,DBI:为什么我的UPDATE函数不起作用? 代码和我尝试过的东西

[英]Perl, SQL, DBI: Why doesn't my UPDATE function work? Code and things I've tried inside

UPDATE 2: I never found the solution to this. 更新2:我从来没有找到解决方案。 Since the instructor's code is readily available for us to use and hack together with our own, and I'd already wasted weeks trying to debug, I just created a new table and started from his code, made changes and tested as I went, until I ended up with that I wanted in functionality. 由于教师的代码可供我们使用并与我们自己的代码一起使用,并且我已经浪费了数周的时间进行调试,因此我只是创建了一个新表并从他的代码开始,进行了更改和测试,直到我最终得到了我想要的功能。 If anyone every comes across a reason for the odd behavior, I'd sincerely appreciate knowing what caused this. 如果每个人遇到异常行为的原因,我都非常感谢知道是什么原因造成的。

Almost everyone who suggested anything offered up ideas I had already tried, and listed as already tried, in my original post. 几乎所有提出建议的人都在我的原始帖子中提出了我已经尝试过的想法,并列为已经尝试过的想法。 Thank you to everyone offering their insight, but please do read posts completely before making suggestions. 感谢所有提供他们的见解的人,但是在提出建议之前,请务必完整阅读文章。

UPDATE: to present my main question more clearly. 更新:更清楚地提出我的主要问题。 The original post is below that with all code, as well as what I've tried. 原始帖子位于下面,包含所有代码以及我尝试过的内容。

I designed my updateData() function to update a record. 我设计了updateData()函数来更新记录。 Instead, it returns its error code. 而是,它返回其错误代码。

sub updateData {
    # and this returns "Update Failed!" for me. I can't figure out why.

    $sql = "UPDATE friendface SET first_name = '$first_name',
        last_name = '$last_name',
        email_address = '$email_address',
        password = '$password'
        WHERE user_id = $user_id;";

    $rc = $dbh->do($sql);
    if ($rc != 1) {
        print "Update Failed!";
    }
}

Ninja editing as I reread through this mess 3: 当我重新阅读这个烂摊子3时,忍者编辑:

Code at the bottom. 底部的代码。 Sorry if the formatting is awful or I'm not descriptive enough. 很抱歉,如果格式太糟糕或描述性不够。 I really tried. 我真的尝试过 Ask if I can provide anything else that is helpful. 询问我是否可以提供其他有用的信息。

Hi everyone, 嗨,大家好,

School assignment here, print a table with records you can edit and delete. 在这里进行学校作业,打印一张表格,其中包含您可以编辑和删除的记录。

I've got an HTML page with forms for inserting data, then a perl script that displays the table with buttons to update and delete. 我有一个HTML页,其中包含用于插入数据的表单,然后是一个Perl脚本,用于显示带有要更新和删除的按钮的表。 Delete works fine. 删除工作正常。 The whole script works fine (EXCEPT the link from the block of text you get when you access the .pl directly, but I don't care about that at the moment) without the contents of my UPDATE function. 如果没有我的UPDATE函数的内容,则整个脚本可以很好地工作(除了直接访问.pl时获得的文本块中的链接,但我现在不在乎)。 The code for the UPDATE function works fine line by line in MySQL. UPDATE函数的代码在MySQL中逐行正常工作。 But I can't get the updateData function with the UPDATE query to work in my .pl file. 但是我无法通过UPDATE查询获得updateData函数以在我的.pl文件中工作。

We're allowed full access to the instructor's example code. 我们被允许完全访问教师的示例代码。 I COULD start with his page, then modify it into my own page. 我可以从他的页面开始,然后将其修改为我自己的页面。 I'd rather be able to write my own page without relying on that crutch. 我宁愿不用依靠那个拐杖就能写自己的页面。 I am, however, comparing my code to his and I don't see where I'm going wrong. 但是,我正在将我的代码与他的代码进行比较,但我看不出我要去哪里。 Syntax looks good, as far as I know / can find docs for. 据我所知/可以找到文档,语法看起来不错。

  • I played with varying syntax anyway just in case. 无论如何,我都使用了多种语法,以防万一。 Put a comma after the final record before my WHERE clause because it looked wrong without, but apparently without is the way to go. 在我的WHERE子句之前的最终记录后加一个逗号,因为如果没有它看起来很错误,但是显然没有路要走。 Everything I read says the current syntax is correct. 我阅读的所有内容均表明当前语法正确。

  • I thought maybe it was trying to edit a user_id that didn't exist, but printing the user_id showed it was using the correct one. 我想,也许这是试图编辑user_id不存在的,但打印user_id表明,它用的是正确的。

  • I think my DBI->connect is working because it doesn't return Connection Failed. 我认为我的DBI->connect正在工作,因为它没有返回Connection Failed。

  • The correct function, updateData() , is running because the final output is the Update Failed return code, unique to that function. 正确的函数updateData()正在运行,因为最终输出是该函数唯一的更新失败返回码。

  • I can trace the code through Edit button > Edit form > Confirm Edit function > updateData function > $dbh authenticates successfully, do($sql) , which is my UPDATE query, which looks syntactically correct. 我可以通过“编辑”按钮>编辑表单>确认编辑功能> updateData函数> $ dbh成功验证do($sql)来跟踪代码,这是我的UPDATE查询,在语法上看起来是正确的。 But for some reason, $dbh->do($sql); 但是由于某种原因, $dbh->do($sql); doesn't come out true. 不正确。

  • In the updateData function, I thought I'd make sure the problem wasn't that I was only updating 4 of the 6 fields. updateData函数中,我以为可以确保问题不是我只更新了6个字段中的4个。 Well, 5, since the key isn't ever going to be updated. 好吧,5,因为密钥永远不会更新。 Anyway, I thought that might be tripping it up somehow, but adding a line to update username didn't help, so I took it out again. 无论如何,我认为这可能会使其跳闸,但是添加一行以更新用户名无济于事,所以我再次将其取出。

I've really been trying to figure this out on my own and I'm pulling my hair out. 我真的一直在尝试自己解决这个问题,并且正在拔头发。 It's always some dumb little thing. 总是有些愚蠢的小事。 Is it spacing? 是间距吗? It usually doesn't matter, but I know ENDFORM had to be the first, and only, thing on the line in order to work for me. 通常,这并不重要,但是我知道ENDFORM必须是第一个也是唯一的东西,才能为我工作。 But I don't know of any spacing rules for this particular code. 但我不知道此特定代码的间距规则。 Please. 请。 Point me in the right direction. 为我指明正确的方向。

Just to be explicit, printEditButton() and printDeleteButton() are the code for the edit and delete buttons... 明确地说, printEditButton()printDeleteButton()是编辑和删除按钮的代码...

DESC table, code for the html page, and the pl script follows: DESC表,html页面的代码和pl脚本如下:

*********************
*********************
***DESC friendface***
*********************
*********************

Field   Type    Null    Key Default Extra
user_id int(11) NO  PRI NULL    auto_increment
username    char(50)    YES     NULL    
first_name  char(20)    YES     NULL    
last_name   char(20)    YES     NULL    
email_address   char(50)    YES     NULL    
password    char(50)    YES     NULL    




*********************
*********************
*friendFaceForm.html*
*********************
*********************

<table bgcolor='antiquewhite' align=center cellpadding=2>
<form action='friendFaceForm.pl' method=GET>

<tr>
    <td align=right>Username</td>
    <td><input type=text name=username></td>
</tr>

    <tr>
        <td align=right>First Name</td>
        <td><input type=text name=first_name></td>
    </tr>

    <tr>
        <td align=right>Last Name</td>
        <td><input type=text name=last_name></td>
    </tr>


    <tr>
        <td align=right>Email Address</td>
        <td><input type=text name=email_address></td>
    </tr>

    <tr>
        <td align=right>Password</td>
        <td><input type=text name=password></td>
    </tr>

    <tr>
        <td align=center colspan=2> <input type=submit name=action value='Insert Data'></td>
    </tr>


</form>
</table>


*********************
*********************
**friendFaceForm.pl**
*********************
*********************

#!/usr/bin/perl

use CGI qw(:standard);
use DBI;
use warnings;

print "Content-type: text/html\n\n";

$dbh = DBI->connect("DBI:mysql:jwiard1:localhost", "jwiard1", "jwiard1")
    or endProgram("Connection Failed!");

$action = param('action');
$user_id = param('user_id');
$username = param('username');
$first_name = param('first_name');
$last_name = param('last_name');
$email_address = param('email_address');
$password = param('password');

if ($action eq 'Insert Data') {
#$action holds this value coming from the html page
#this happens first

    insertData();
    printTable();

}
elsif ($action eq 'Edit') {
#prints the edit form

    printEditForm();

}
elsif ($action eq 'Confirm Edit') {
#then updateData() runs

    updateData();
    printTable();

}
elsif ($action eq 'Delete') {

    deleteData();
    printTable();

}
elsif ($action eq 'Print Table') {

    printTable();

}
else {

    print "Either you are accessing this file directly or \$action has an unaccounted         for value.<br><br>

    If it's the former, get out of here!<br><br>

    If it's the latter... you're getting sleepy. You're getting verrrry sleepy. When     you reach the end of this sentence, you'll wake up with no memory of this page and a strong     feeling that Joe Wiard's code is perfect.<br><br>

    ...or did you just want to see the table?";

    print "<input type=submit name=action value='Print Table'>";

}







####
#Functions! Yay!
####

sub endProgram {
    my ($msg) = @_;
    print $msg;
    die();
}

sub insertData {
#after inserting data, the user is left to click Edit or Delete
#making $action hold the value of 'Edit' or 'Delete' Go to elsif($action eq 'Edit'

    print "Your data has been saved.";

    $sql = "INSERT INTO friendface SET user_id='$user_id',
        username='$username',
        first_name='$first_name',
        last_name='$last_name',
        email_address='$email_address',
        password='$password'  ;";

        $rc = $dbh->do($sql);
        if ($rc != 1) {
            print "Insert failed!";
        }
}

sub printEditButton {

print "<form>";
print "<input type=hidden name=user_id value='$href->{user_id}'>";
print "<input type=submit name=action value='Edit'>";
print "</form>";

}

sub printDeleteButton {

print "<form>";
print "<input type=hidden name=user_id value='$href->{user_id}'>";
print "<input type=submit name=action value='Delete'>";
print "</form>";

}

sub confirmEdit {



}

sub lookUpRow {

    $sql = "SELECT * FROM friendface WHERE user_id=$user_id;";

    $sth = $dbh->prepare($sql);

    $rc = $sth->execute();

    $href = $sth->fetchrow_hashref();

}

sub printEditForm {
#prints fields for 4 of the values in a record. I don't want the user to be able to
#change their username. They can only edit first and last names, email and password.
#after this, $action either holds 'Confirm Edit' or 'Cancel'. Go to elsif
#($action'Confirm Edit')

    lookUpRow();

    print <<ENDOFFORM;
    <form>
    First Name: <input type=text name=first_name value='$href->{first_name}'> <br>
    Last Name:  <input type=text name=last_name value='$href->{last_name}'> <br>
    Email Address:  <input type=text name=email_address value='$href->{email_address}'>         <br>
    Password:  <input type=text name=password value='$href->{password}'> <br>
    <input type=hidden name=user_id value=$href->{user_id}'> <br>
    <input type=submit value="Confirm Edit" name=action>
    <input type=submit value="Cancel" name=action>
    </form>
ENDOFFORM
#It seems that ENDOFFORM *MUST* be at the beginning of the line. No TABS or SPACES
#preceeding, and NOTHING after. Half an hour of debugging lead me to discovery this
#tidbit that I should have just remembered from class. Or Googled. :P
}

sub updateData {
#and this returns "Update Failed!" for me. I can't figure out why.


    $sql = "UPDATE friendface SET first_name = '$first_name',
        last_name = '$last_name',
        email_address = '$email_address',
        password = '$password'
        WHERE user_id = $user_id   ;";

    $rc = $dbh->do($sql);
    if ($rc != 1) {
        print "Update Failed!";
    }

}

sub deleteData {

    $sql = "DELETE FROM friendface WHERE user_id = $user_id;";

    $rc = $dbh->do($sql);

}

sub printTable {

    $sql = "SELECT * FROM friendface;";
    $sth = $dbh->prepare($sql);
    $rc = $sth->execute();

    $count = 0;

    print "<table>";

    #print header

    while ($href = $sth->fetchrow_hashref() ) {

        $count ++;
        if ($count % 2 == 0) {
            print "<tr bgcolor=lightblue>";
        }
        else {
            print "<tr bgcolor=lightgray>";
        }

        print "<td>";
        print $href->{'user_id'};
        print "</td>";
        print "<td>";
        print $href->{'username'};
        print "</td>";
        print "<td>";
        print $href->{'first_name'};
        print "</td>";
        print "<td>";
        print $href->{'last_name'};
        print "</td>";
        print "<td>";
        print $href->{'email_address'};
        print "</td>";
        print "<td>";
        print $href->{'password'};
        print "</td>";
        print "<td>";
        printEditButton();
        print "</td>";
        print "<td>";
        printDeleteButton();
        print "</td>";

        print "</tr>";
    }

    print "</table>";

From the DBI documentation , it seems that the "do" method does some magic with the return value: DBI文档中 ,似乎“ do”方法对返回值做了一些魔术:

do

If you're doing an UPDATE, INSERT, or DELETE there is no data that comes back from the database, so there is a short cut. 如果您正在执行UPDATE,INSERT或DELETE,则没有从数据库返回的数据,因此是捷径。 You can say 你可以说

$dbh->do('DELETE FROM people WHERE age > 65'); $ dbh-> do('从年龄大于65岁的人处删除); for example, and DBI will prepare the statement, execute it, and finish it. 例如,DBI将准备该语句,执行它并完成它。 do returns a true value if it succeeded, and a false value if it failed. 如果成功,则返回true值;如果失败,则返回false值。 Actually, if it succeeds it returns the number of affected rows. 实际上,如果成功,它将返回受影响的行数。 In the example it would return the number of rows that were actually deleted. 在该示例中,它将返回实际删除的行数。 (DBI plays a magic trick so that the value it turns is true even when it is 0. This is bizarre, because 0 is usually false in Perl. But it's convenient because you can use it either as a number or as a true-or-false success code, and it works both ways.) (DBI起到了魔术的作用,即使它是0,它也会变成真实的值。这很奇怪,因为在Perl中,0通常是false。但是它很方便,因为您可以将其用作数字或true-or -错误的成功代码,并且它可以双向运行。)

Are you sure the update didn't work? 您确定更新无效吗? Perform a select afterward to double-check. 之后执行选择以仔细检查。 It could just be that you're misinterpreting the return code. 可能只是您误解了返回码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM