【问题标题】:DBIx::Class update only one rowDBIx::Class 只更新一行
【发布时间】:2012-08-10 04:14:31
【问题描述】:

我正在使用DBIx::Class,我只想更新表中的一行。目前我是这样做的:

my $session = my_app->model("DB::Session")->find(1);    
$session->update({done_yn=>'y',end_time=>\'NOW()'});

它可以工作,但问题是当它确实找到该行时,它会执行整个查询:

SELECT me.id, me.project_id, me.user_id, me.start_time, me.end_time, me.notes, me.done_yn FROM sessions me WHERE ( me.id = ? ): '8'

当我只想更新一行时,这似乎有点多。无论如何更新一行而不必先将整行拉出数据库?我正在寻找这样的东西:

my_app->model("DB::Session")->update({done_yn=>'y',end_time=>\'NOW()'},{id=>$id});

其中$id 是查询的WHERE id=? 部分。有谁知道如何做到这一点?谢谢!

【问题讨论】:

    标签: mysql catalyst dbix-class


    【解决方案1】:

    您可以在仅匹配此单行的受限结果集上运行更新:

    my_app->model("DB::Session")->search_rs({ id=> 1 })->update({done_yn=>'y',end_time=>\'NOW()'});

    我建议您使用 DateTime->now 对象而不是文字 SQL 来更新 end_time 列,因为它使用应用服务器日期和时间而不是数据库服务器,并使您的架构与不同的 RDBMS 更兼容。

    【讨论】:

    • 这很好,因为它是在一行中完成的,但真的是两条sql语句,因为它必须首先找到结果集吗?
    • search(_rs) 仅限制结果集定义,在您调用 all 或 next 或在列表上下文中使用之前,不会生成或运行 SQL。
    【解决方案2】:

    您是否检查是否找到了该行以防止出现错误以防万一?

    您可能想改用update_or_create

    【讨论】:

    • 我知道这已经晚了,但这实际上对我有用。谢谢!
    【解决方案3】:

    您可以使用“列”属性:

    my $session = my_app->model("DB::Session")->find(1, {columns => "id"});
    

    【讨论】:

    • 一般来说,允许find() 检索您希望更新的列以及主键,使update() 在不需要时不发出UPDATE 语句(即,新数据与现有数据相同)。当然,这与您的情况无关。
    • 但这如何使它成为一个查询?之后我是否还需要在找到的行上运行更新?
    • 对不起,我误解了你的问题。
    猜你喜欢
    • 2018-07-03
    • 2011-09-12
    • 2011-07-09
    • 2016-08-25
    • 2018-02-13
    • 2012-02-15
    • 2013-01-21
    • 2013-03-08
    • 2011-07-09
    相关资源
    最近更新 更多