当没有结果时,CakePHP 中带有虚拟字段的分页不会返回空数组

发布于 2024-12-09 12:06:17 字数 1586 浏览 0 评论 0原文

我在模型中使用虚拟字段。该字段表示多个字段的总和:SUM(Model.amount_1 + Model.amount_2 + ...)。这是架构:

create table `current_transfers` (
  `id` integer unsigned not null auto_increment primary key,
  `description` varchar(1024) not null,
  `product_amount` decimal(13,2) default 0.0 not null,
  `tax_amount` decimal(13,2) default 0.0 not null,
  `other_amount` decimal(13,2) default 0.0 not null,
  `record_id` integer unsigned not null,
  constraint foreign key (`record_id`) references `records`(`id`) on delete cascade,
) ENGINE=InnoDB;

这是 CurrentTransfer 模型中虚拟字段的定义:

var $virtualFields = array(
  'amount' => 'SUM(
    CurrentTransfer.product_amount +
    CurrentTransfer.tax_amount +
    CurrentTransfer.other_amount)'
);

假设该表还没有任何记录,并且您使用 $this->paginate()< /code> 在 RecordsController 中检索结果列表,如下所示:

class RecordsController extends AppController {

  var $name = 'Records';

  var $paginate = array(
    'CurrentTransfer' => array(
      'order' => array('CurrentTransfer.amount' => 'desc'),
    ),
  );

  // ...

  public function view($id) {
    // ...
    $this->paginate('CurrentTransfer', array('CurrentTransfer.record_id' => $id));
    // ...
  }

  // ...
}

我发现了两种不同的行为:

  • 如果虚拟字段实际上在模型中定义,则结果是一个数组,其中一个元素存储一个空记录,即每个字段设置为NULL
  • 如果模型中未定义虚拟字段,则结果为空数组,这是 CakePHP 中查询返回空值集时的常见行为。

我总是期望第二种行为,因为如果有结果或没有结果更容易比较。

当表中实际上没有记录时,为什么 CakePHP 返回一个虚构的结果?为什么添加虚拟字段会产生这样的行为?

I am using a virtual field in a model. That field represents the sum of several fields: SUM(Model.amount_1 + Model.amount_2 + ...). This is the schema:

create table `current_transfers` (
  `id` integer unsigned not null auto_increment primary key,
  `description` varchar(1024) not null,
  `product_amount` decimal(13,2) default 0.0 not null,
  `tax_amount` decimal(13,2) default 0.0 not null,
  `other_amount` decimal(13,2) default 0.0 not null,
  `record_id` integer unsigned not null,
  constraint foreign key (`record_id`) references `records`(`id`) on delete cascade,
) ENGINE=InnoDB;

And this is the definition of the virtual field in CurrentTransfer model:

var $virtualFields = array(
  'amount' => 'SUM(
    CurrentTransfer.product_amount +
    CurrentTransfer.tax_amount +
    CurrentTransfer.other_amount)'
);

Let's say the table does not have any records yet and you use $this->paginate() in RecordsController to retrieve a list of results, like this:

class RecordsController extends AppController {

  var $name = 'Records';

  var $paginate = array(
    'CurrentTransfer' => array(
      'order' => array('CurrentTransfer.amount' => 'desc'),
    ),
  );

  // ...

  public function view($id) {
    // ...
    $this->paginate('CurrentTransfer', array('CurrentTransfer.record_id' => $id));
    // ...
  }

  // ...
}

I have found two different behaviors:

  • If the virtual field is actually defined in the model the result is an array with one element storing an empty record, i.e. every field is set to NULL.
  • If the virtual field is not defined in the model the result is an empty array, which is the common behavior in CakePHP when a query returns an empty set of values.

I would always expect the second behavior, since is easier to compare if there are results or not.

Why is CakePHP returning a fictitious result when there are actually no records in the table? Why the addition of virtual fields produce such behavior?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑忘罢 2024-12-16 12:06:17

SUM() 是一个聚合函数,它对一列中的所有行进行求和,而不是像您可能想要的那样对一行中的所有列求和。作为聚合函数,它总是返回一个值,至少NULL。这意味着 SQL 查询至少返回一行,且所有列均设置为 NULL。 Cake只是简单地选择了这一点。

我认为您实际上正在寻找这个:

public $virtualFields = array(
  'amount' => 'CurrentTransfer.product_amount + CurrentTransfer.tax_amount + CurrentTransfer.other_amount'
);

即没有 SUM() 的简单 + 运算符。

SUM() is an aggregate function that sums up all rows in a column, not all columns in a row as you probably want. As an aggregate function, it always returns a value, at least NULL. That means the SQL query returns at least one row with all columns set to NULL. Cake is simply picking this up.

I think you're actually looking for this:

public $virtualFields = array(
  'amount' => 'CurrentTransfer.product_amount + CurrentTransfer.tax_amount + CurrentTransfer.other_amount'
);

I.e. the simple + operator without the SUM().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文