我在查看some questions询问如何在Zend Framework查询中进行连接,但答案总是像“只做setIntegrityCheck(FALSE)
”。
我的问题是:为什么我需要这样做?
在我看来,禁用“完整性检查”并不是使这项工作正常的方法。在我的特定情况下,我正在使用带有外键的一些InnoDB表的MySQL数据库,例如:
CREATE TABLE IF NOT EXISTS `tableA`
(
`id` CHAR(6),
`name` VARCHAR(255),
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `tableB`
(
`tableA_id` CHAR(6),
`somefield` VARCHAR(255),
PRIMARY KEY (`tableA_id`)
) ENGINE=InnoDB;
ALTER TABLE `tableB` ADD FOREIGN KEY fk1 (`tableA_id`) REFERENCES `tableA` (`id`);
(这是我的数据库的一个非常简化的版本)
而且,我的查询代码如下所示:
$table = new Zend_Db_Table('tableB');
$select = $table->select(TRUE)
->join(array('a' => 'tableA'), 'tableB.tableA_id = a.id');
$result = $table->fetchAll($select);
除非我将setIntegrity(FALSE)
添加到我的$select
,否则这会给我“选择查询无法加入其他表格”例外。
答案 0 :(得分:23)
调用setIntegrityCheck(false)
是进行加入的正确方法;如果您使用Zend_Db_Table
和Zend_Db_Table_Select
,则除非禁用完整性检查,否则无法加入。
完整性检查就是为了确保查询不使用多个表,并且在适当的位置确保可以删除或修改Zend_Db_Table_Row
对象然后保存,因为行数据是独占的单个表,并不是来自不同表的数据的混合。
要表明您想要使用多个表,请指定setIntegrityCheck(false)
以让Zend Framework知道它是故意的。结果是您获得了一个无法调用save()
或delete()
的锁定行。
以下是Zend_Db_Table - Advanced Usage参考指南的引用(跳至示例27。
Zend_Db_Table_Select 主要用于约束和验证 以便它可以强制执行合法
SELECT
查询的条件。然而 在某些情况下,您需要灵活性 Zend_Db_Table_Row 组件,不需要可写或可删除 行。对于这个特定的用户案例,可以检索一行或 通过将FALSE
值传递给 setIntegrityCheck()来进行行集。所结果的 行或行集将作为“锁定”行返回(表示 save(), delete(),任何字段设置方法都会抛出异常。)
答案 1 :(得分:9)
好的,我做了一些研究,而且非常真实你需要调用setIntegrityCheck(FALSE)
来进行连接。
Zend_Db_Select
类中的相关代码(即找到此参数的最后一个单词的唯一位置)包含此代码:
if ($this->_integrityCheck !== false) {
foreach ($fields as $columnEntry) {
list($table, $column) = $columnEntry;
// Check each column to ensure it only references the primary table
if ($column) {
if (!isset($from[$table]) || $from[$table]['tableName'] != $primary) {
require_once 'Zend/Db/Table/Select/Exception.php';
throw new Zend_Db_Table_Select_Exception('Select query cannot join with another table');
}
}
}
}
因此,实际上,它会检查查询中的所有选定字段是否属于“主表”。 查询不一定要返回相关表格中的所有字段。
回到我的问题中的例子,结果是做工作:
$table = new Zend_Db_Table('tableB');
$select = $table->select(TRUE)
->join(array('a' => 'tableA'), 'tableB.tableA_id = a.id', NULL); // <-- notice the third parameter here
$result = $table->fetchAll($select);
此新查询仅返回tableB
中的字段,但您可以在任何表上添加where
条件,就像通常使用SQL一样,没有问题。