如何将 Zend_Db_Table 与自定义查询一起使用?

发布于 2024-12-08 19:38:36 字数 462 浏览 0 评论 0原文

我需要在 Zend_Db_Table 之上实现一些带有连接的东西。 我注意到 Zend_Db_Table 本身没有提供简单的连接方法。因此,我决定简单地编写查询,然后使用 Zend_Db_Adapter::fetchAll 获取结果。

但是,我仍然需要以 Zend_Db_Table_Rowset 形式获取结果,以便其他需要行集的代码仍然可以正确运行。因此,我需要将从 Zend_Db_Adapter 获取的数组手动转换为 Zend_Db_Table_Rowset

我怎样才能做到这一点?

I need to implement something with joins on top of Zend_Db_Table. It has come to my attention that Zend_Db_Table provides no easy method of doing joins by itself. As a result, I have decided to simply write queries and then fetch the results using Zend_Db_Adapter::fetchAll.

However, I still somehow need to get the results as a Zend_Db_Table_Rowset so that other code expecting a rowset still operates correctly. I therefore need to take the array I get from Zend_Db_Adapter and turn that into a Zend_Db_Table_Rowset manually.

How can I do that?

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

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

发布评论

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

评论(4

分開簡單 2024-12-15 19:38:36

这不是一个记录的功能,但您可以使用任意数据数组的数组实例化 Rowset 对象。这就是 Zend_Db_Table 在其 find()fetchall() 方法中所做的事情。

<?php

// this can be the result of any Zend_Db_Statement::fetchAll()
$query_result = array(
  array('id'=>123, 'foo'=>'bar'),
  array('id'=>456, 'foo'=>'baz')
);

$rowset = new Zend_Db_Table_Rowset(
  array(
    'readonly' => true,
    'data'     => $query_result
  )
);

foreach ($rowset as $row) {
  print "id  = " . $row->id . "\n";
  print "foo = " . $row->foo . "\n";
}

请注意,这不是“实时”行集。您无法更改字段并将其 save() 到数据库中的基表中。行集或行中没有存储有关哪些基表包含与 Row 对象的字段对应的列的信息。原始 SQL 查询的某些列可能是表达式或聚合,因此无论如何都没有确定的方法来 save() 它们。

因此,与使用 PDO::FETCH_OBJ 来获取结果集作为对象而不是哈希数组相比,这基本上没有任何改进。


回复:

是的,您可以使用 setTable() 就像使用反序列化的 Rowset 对象一样。但是 Zend_Db_Table_Row 不知道每一列属于哪个表。因此它将尝试根据 Row 对象的字段生成 UPDATE 或 INSERT 查询。如果您创建 Row 对象的结果集包含来自多个连接表的列,则此操作将会失败。

您需要确保 Row 对象仅包含来自单个表的字段,并且包含主键列,并且 Row 明确地从表中的单个行映射。

It's not a documented feature, but you can instantiate a Rowset object with any arbitrary array of arrays of data. This is what Zend_Db_Table does in its find() and fetchall() methods.

<?php

// this can be the result of any Zend_Db_Statement::fetchAll()
$query_result = array(
  array('id'=>123, 'foo'=>'bar'),
  array('id'=>456, 'foo'=>'baz')
);

$rowset = new Zend_Db_Table_Rowset(
  array(
    'readonly' => true,
    'data'     => $query_result
  )
);

foreach ($rowset as $row) {
  print "id  = " . $row->id . "\n";
  print "foo = " . $row->foo . "\n";
}

Note that this is not a "live" rowset. You can't change fields and save() them to the base tables in the database. There's no information stored in the rowset or rows about which base tables contain the columns corresponding to the fields of your Row objects. Some columns of your original SQL query may be expressions or aggregations, so there would be no deterministic way to save() them anyway.

So this is basically no improvement over using PDO::FETCH_OBJ to fetch result sets as objects instead of hash arrays.


Re comments:

Yes, you can use setTable() just like with a deserialized Rowset object. But Zend_Db_Table_Row does not have any idea which table each column belongs to. So it will try to generate an UPDATE or INSERT query based on the fields of the Row object. This will fail if the result set from which you make your Row object includes columns from more than one joined tables.

It's up to you to make sure the Row object contains fields only from a single table, and that the primary key column(s) are included, and that the Row is unambiguously mapped from a single row in the table.

夜司空 2024-12-15 19:38:36

Zend_Db_Table 顾名思义,抽象了一个数据库表。您可以加载数据、更改数据并保存结果。但是,这意味着您仅限于实例正在抽象的表。

您可以通过调用对象的 select() 来更新对象的 select 语句。然后,您可以在其他表上 join() ,然后使用 fetchall(select) 从连接的表中获取数据。但是,由于 zend_db_table 抽象了单个表,因此它不允许您这样做。

您可以通过在选择上执行 setIntegrityCheck(false) 来解决此问题,这将允许您加入。然而,这意味着您只能通过该对象读取数据。写入将被禁用。

或者,您可以使用 zend_db_select 对象来代替,它不会映射到特定的表。

Zend_Db_Table as its name suggests abstracts a database table. You can load data, change it and save the results. However, this means you're restricted to the table that your instance is abstracting.

You can update the object's select statement by calling select() on it. You can then join() on additional tables and then fetchall(select) to get data from the joined table. However, as zend_db_table abstracts a single table, it wont allow you to.

You can get around this by doing a setIntegrityCheck(false) on the select, and this will allow you to join. However this means you'll only be able to read data through this object. Writing will be disabled.

Alternatively, you could use a zend_db_select object instead, which doesn't map to a particular table.

蓝梦月影 2024-12-15 19:38:36

我以前也被这个问题困扰过。我认为除非您自己编写实现,否则您不能返回 zend_db_table_rowset 。尝试查看行集摘要以了解该结构是如何工作的。 zend_db_table_rowset 是 zend_db_table_row 对象的集合。您从 zend_db_adapter 返回的内容不兼容*。您可能需要做的是以某种方式将结果转换为 zend_db_table_rows,然后将它们添加到新的 zend_db_table_rowset 以获得对这些类的所有成员的访问权限。

* 这描述了可以从 Zend_Db_Adapter 返回的内容,并且我没有看到 Zend_Db_Table/Rowset/Row 作为选项:
http://framework .zend.com/manual/en/zend.db.adapter.html#zend.db.adapter.select.fetch-mode

I've been stymied by this before, too. I don't think you can return a zend_db_table_rowset unless you write the implementation yourself. Try looking into the rowset abstract to see how the structure works. A zend_db_table_rowset is a collection of zend_db_table_row objects. What you're getting back from zend_db_adapter just isn't compatible*. What you might need to do is somehow convert your results into zend_db_table_rows and then add them to a new zend_db_table_rowset to gain access to all of the members of those classes.

* this describes what can be returned from Zend_Db_Adapter, and I don't see Zend_Db_Table/Rowset/Row as an option:
http://framework.zend.com/manual/en/zend.db.adapter.html#zend.db.adapter.select.fetch-mode

静谧 2024-12-15 19:38:36
  $table = new Zend_Db_Table('tableName');

    $myRowset = $table->fetchAll();

最后,Zend_Db 提供了通过 Zend_Db_Select 连接表的绝佳方法。

  $table = new Zend_Db_Table('tableName');

    $myRowset = $table->fetchAll();

Lastly Zend_Db provices excellent way of joining table through Zend_Db_Select .

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