繁体   English   中英

Zend中的setIntegrityCheck使用联接选择

[英]setIntegrityCheck in Zend Selects with joins

我一直在看一些 问题 ,询问如何在Zend Framework查询中进行联接,但是答案始终像是“ just 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否则这setIntegrity(FALSE)“选择查询无法与另一个表 setIntegrity(FALSE) 例外。

调用setIntegrityCheck(false)是进行setIntegrityCheck(false)的正确方法。 如果您使用的是Zend_Db_TableZend_Db_Table_Select ,那么除非禁用完整性检查,否则您无法加入。

进行完整性检查只是为了确保查询不使用多个表,并且当存在适当的位置时,确保可以删除或修改Zend_Db_Table_Row对象,然后将其保存,因为该行数据是单个表专有的,而不是来自不同表的数据混合。

为了表明您希望使用多个表,请指定setIntegrityCheck(false)以使Zend Framework知道它是有意的。 结果是您得到了一个锁定的行,该行无法调用save()delete()

这是Zend_Db_Table-高级用法参考指南中的引文(跳至示例27。

Zend_Db_Table_Select主要用于约束和验证,以便可以强制执行合法SELECT查询的条件。 但是,在某些情况下,您需要Zend_Db_Table_Row组件的灵活性,并且不需要可写或可删除的行。 对于这种特定的用户情况,可以通过将FALSE值传递给setIntegrityCheck()来检索行或行集。 结果行或行集将作为“锁定”行返回(意味着save()delete()和任何字段设置方法将引发异常)。

另请参阅: 使用Zend_Db_Table_Select进行一对多联接

好的,我做了一些研究,并不是真的必须调用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的字段,但是您可以像通常使用SQL一样在任何表上添加where条件,没有问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM