Perl DBI中的更新不起作用,为什么? (完整的帖子发布,包括在MySQL中创建数据库的DDL)

时间:2011-03-24 18:58:23

标签: perl dbi

为什么“示例2”中的UPDATE不起作用?

#   MySQL DDL to create database used by code 
#
#   CREATE DATABASE sampledb;
#
#   USE sampledb;
#   
#   CREATE TABLE `dbtable` (
#     `id`  int(11) NOT NULL AUTO_INCREMENT,
#     `demo` longtext,
#     PRIMARY KEY  (`id`)
#   ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

# PERL MODULES WE WILL BE USING
use strict;
use warnings;
use DBI;

# CONFIG VARIABLES
my $platform = "mysql";
my $database = "sampledb";
my $host = "localhost";
my $port = "3306";
my $username = "root";
my $password = "password";

# DATA SOURCE NAME
my $dsn = "dbi:$platform:$database:$host:$port";

# PERL DBI CONNECT
my $connect = DBI->connect($dsn, $username, $password);

# VARS for Examples
my $query;
my $query_handle;
my $id;
my $demo;

# Example 1 using prepare() and execute() INSERT

    # SAMPLE VARIABLE AND VALUES TO PASS INTO SQL STATEMENT
    $id = 1;
    $demo = "test";

    # prepare() and execute() INSERT
    $query = "INSERT INTO dbtable (id, demo) VALUES ('$id', '$demo')";
    $query_handle = $connect->prepare($query);

    # EXECUTE THE INSERT
    $query_handle->execute();

    print STDERR "ERROR: $DBI::errstr";
    print STDERR "INFO: $query_handle rows updated";

    undef $query;

# Example 2 using do() UPDATE   

    # SAMPLE VARIABLE AND VALUES TO PASS INTO SQL STATEMENT
    $id = 2;
    $demo = "test 2";

    # do() THE UPDATE
    $query = "UPDATE dbtable SET demo = '$demo' WHERE id = $id;";
    $query_handle = $connect->prepare($query);

    # EXECUTE THE UPDATE
    $query_handle = $connect->do($query);

    print STDERR "ERROR: $DBI::errstr";
    print STDERR "INFO: $query_handle rows updated";

    undef $query;

2 个答案:

答案 0 :(得分:2)

您正在尝试更新id = 2的记录,该记录似乎不存在。

答案 1 :(得分:2)

您在$ DBI :: errstr中收到错误吗?除了DBI可能给你的任何输出之外,我看到的最初的潜在问题是你插入一个id = 1的行,但是你的更新试图更新id = 2的行。不会有任何要更新id = 2的行。

您可能还想了解其他一些事情。将变量直接插入到查询中是不好的做法,也是导致SQL注入攻击的原因。您应该查看有关使用占位符的DBI文档。当您需要对循环中的不同值执行相同的查询时,占位符还允许您最有效地使用prepare()。如果你刚刚这样做,因为它只是一个快速测试而你不会在“真实”代码中这样做,那么很抱歉骚扰你。

你也不需要在do()之前调用prepare()。 do()处理对prepare()本身的调用。