Perl 和 MySQL - 使用 DBI 从表的最后一行返回字段,可能带有 last_insert_id?
Posted
技术标签:
【中文标题】Perl 和 MySQL - 使用 DBI 从表的最后一行返回字段,可能带有 last_insert_id?【英文标题】:Perl and MySQL - Return a field from last row of a table using DBI possibly with last_insert_id? 【发布时间】:2012-05-16 14:13:49 【问题描述】:我正在尝试从users
的最后一行的users
表中返回成员firstname
字段。
my $dbh = DBI->connect($dsn, $db_user_name, $db_password) or die "$DBI::errstr";
my $LastID = $dbh->last_insert_id(`firstname`); ##but I want from table users
print qq~$LastID~;
上面返回这个错误:
DBI last_insert_id: invalid number of arguments: got handle + 0, expected handle + between 4 and 5
Usage: $h->last_insert_id($catalog, $schema, $table_name, $field_name [, \%attr ])
那么,从表的最后一行获取字段firstname
的“最佳”方式是什么(最适合服务器、最快、最少的内存、负载、最少的开销……无论如何) 987654328@?
请意识到我上面的例子不应该被认真对待,因为我不知道如何做到这一点,而不只是做一些像我粗略但实用的事情: (p.s. UserID 不是通过自动递增分配的,而是按数字顺序分配的,新用户获得更高的 UserID。就像我解决预先存在的问题时那样。)
my $dbh = DBI->connect($dsn, $db_user_name, $db_password) or die "$DBI::errstr";
my $dsn = $dbh->prepare(qqSELECT `firstname` FROM `users` ORDER BY ABS(UserID) DESC LIMIT ?,?);
$dsn->execute('1','1') or die "$DBI::errstr";
while(@nrow = $dsn->fetchrow_array())
$firstname = $nrow[0];
我假设因为我使用 DBI 可能会提供最佳解决方案,但是我显然缺乏经验,需要一些建议和指导来学习正确的方法来做到这一点。感谢您的帮助。
【问题讨论】:
只是为了检查 - 在您的第一个代码块中,文本“名字”被反引号 (`) 包围,这意味着 Perl 将尝试执行内容。我不确切知道 DBI 将如何处理返回的任何内容,但这可能不是您想要的。也许这不是你的问题。 谢谢...我删除并得到:“严格的潜艇”时不允许裸词“名字”。也没有提到我需要哪个表的信息。这就是为什么我提到不要认真对待这个例子,因为我显然是新手,不知道自己在做什么。last_insert_id
是错误的工具——它的目的或多或少是返回最近插入的记录的主键,而不是返回与该记录关联的任意字段。你需要用 SQL 来解决这个问题,Joel's answer 基本上是正确的。
【参考方案1】:
您提到 UserID 不是自动递增的,所以我不确定last_insert_id 是否适用于这种情况。可能,但我只是不确定。该文件指出:
通常这将是数据库服务器分配给 具有 auto_increment 或 serial 类型的列。
我希望通过使用 SQL 语句来解决这个问题:
SELECT
u.firstname
FROM
users u
JOIN
(
SELECT
MAX(UserID) AS UserID
FROM
users
) t ON u.UserID = t.UserID
使用 DBI 的代码将如下所示:
my $stmt = 'SELECT u.firstname FROM users u JOIN(SELECT MAX(UserID) AS UserID FROM users) t ON u.UserID = t.UserID';
my $first_name = ($dbh->selectrow_array($stmt))[0];
【讨论】:
是的,这行得通。谢谢你把它分解成这样,这样我就可以理解那里发生了什么。 我假设这种方法比像以前一样通过“ORDER BY DESC LIMIT 1,1”返回名字“更好”?也许对为什么它更好的一个小解释,我可以进一步理解? @Jim_Bo 在您的示例中,您从表中获取所有行,对它们进行排序,然后只返回第一行。这浪费了一些处理时间,因为必须检索一个大的结果集然后对其进行排序。使用我的示例不会提取所有行,因此它可能更有效。实际上,我会使用对您有意义的 SQL 语句和 Perl 代码;最好能够维护自己的代码。【参考方案2】:last_insert_id 方法需要 4 个参数。像这样使用:
my $id = $connection->last_insert_id(undef, 'myschemaname', 'mytablename', 'mycolumnname');
查看 DBI pod。
【讨论】:
我读到了,但是,这不会返回 mysql 的最后一个 id 而不是名字吗?我对此真的很陌生,我已经阅读了所有 DBI 手册页,但是,我需要一个基于我的标准的具体示例来理解“机制”。也许 30 年前我会更快地理解这一点,但不像以前那么快了。 如果您希望最后插入的行的名字字段运行 last_insert_id ,如我上面所示,然后选择带有 id = 的名字列到返回的 last_insert_id 。 我试过我的 $firstname = $dbh->last_insert_id(undef, 'databasename', 'users', 'firstname');然后打印qq~$firstname~;它返回“0”;很抱歉,我完全不明白这一点。以上是关于Perl 和 MySQL - 使用 DBI 从表的最后一行返回字段,可能带有 last_insert_id?的主要内容,如果未能解决你的问题,请参考以下文章