14

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`);

(これは私のDBの非常に単純化されたバージョンです)

そして、私のクエリコードは次のようになります。

$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

4

2 に答える 2

24

呼び出しsetIntegrityCheck(false)は、参加を行うための適切な方法です。とを使用している場合はZend_Db_TableZend_Db_Table_Select整合性チェックを無効にしない限り参加できません。

整合性チェックは、クエリが複数のテーブルを使用しないことを確認するためにZend_Db_Table_Row実施されます。また、実施された場合、行データは単一のテーブル専用であり、異なるテーブルからのデータの混合。

複数のテーブルを使用することを示すにはsetIntegrityCheck(false)、それが意図的なものであることをZendFrameworkに通知するように指定します。save()その結果、呼び出しまたはオンにできないロックされた行が取得さdelete()れます。

これは、Zend_Db_Tableのリファレンスガイドからの引用です-高度な使用法(例27にスキップしてください)。

Zend_Db_Table_Selectは、主に制約と検証に使用され、正当なSELECTクエリの基準を適用できるようにします。ただし、 Zend_Db_Table_Rowコンポーネントの柔軟性が 必要であり、書き込み可能または削除可能な行を必要としない場合があります。この特定のユーザーの場合、 setIntegrityCheck()FALSEに値を渡すことにより、1つまたは複数の行セットを取得できます。結果の1つまたは複数の行セットは、「ロックされた」行として返されます(つまり、save()delete()、およびフィールド設定メソッドは例外をスローします)。

参照:Zend_Db_Table_Selectを使用した1対多の結合

于 2012-02-25T01:46:19.663 に答える
10

わかりました、私はいくつかの調査を行いましたが、結合を行うために電話する必要があるというのはあまり真実ではありません.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);

この新しいクエリは、 からのフィールドのみを返しますが、SQL で通常行うように、任意のテーブルに条件をtableB追加できます。問題はありません。where

于 2012-02-25T18:49:40.917 に答える