Perl DBI 中的更新不起作用,为什么? (完整的源代码发布,包括在 MySQL 中创建数据库的 DDL)
为什么“示例 2”中的更新不起作用?
# 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;
Why is the UPDATE in "Example 2" not working?
# 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;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您正在尝试更新 id=2 的记录,该记录似乎不存在。
You're trying to update a record with id=2, which doesn't seem to exist.
您在 $DBI::errstr 中遇到错误吗?除了 DBI 可能提供的任何输出之外,我看到的最初潜在问题是您插入了 id=1 的行,但您的更新试图更新 id=2 的行。不会有任何 id=2 的行需要更新。
您可能还想了解其他一些事情。像这样将变量直接插入到查询中是不好的做法,并且会导致 SQL 注入攻击。您应该查看有关使用占位符的 DBI 文档。当您需要在循环中对不同值执行相同查询时,占位符还可以让您最有效地使用prepare()。如果您这样做只是因为这只是一个快速测试,并且您不会在“真实”代码中这样做,那么很抱歉为此骚扰您。
您也不需要在 do() 之前调用prepare()。 do() 处理对prepare() 本身的调用。
Are you getting an error in $DBI::errstr? Aside from any output DBI might be giving you, the initial potential problem I see is that you insert a row with id=1, but your update is trying to update rows with id=2. There won't be any rows where id=2 to update.
A couple of other things you may also want to be aware of. Interpolating your variables right into your queries like that is bad practice and is what leads to SQL injection attacks. You should look at the DBI documentation on using placeholders for this. Placeholders also let you make the most effective use of prepare() when you need to do the same query on different values in a loop. If you just did that because it's just a quick test and you wouldn't do that in "real" code, then sorry for harassing you about it.
You also don't need to call prepare() before do(). do() handles the call to prepare() itself.