2012-02-25 26 views
10

私はsomequestionsを見ていましたが、Zend Frameworkのクエリで結合を行う方法を尋ねていますが、答えは常に "ちょっとsetIntegrityCheck(FALSE)"のようなものです。setIntegrityCheck with Zend

私の質問はなぜこれを行う必要がありますか?

「完全性チェック」が無効になっているようですが、この作業を行う正しい方法ではありません。私の特定のケースでは、私は、外部キーを持ついくつかの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); 

これは私が私の$selectsetIntegrity(FALSE)を追加しない限り、例外を「クエリは、別のテーブルに参加することはできませんを選択し、」私にを与えている:コードは次のようになります。

答えて

9

[OK]を、私はいくつかの研究を行なったし、それはあなたが加入を行うために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で行うように、問題はありません。

+0

はい、動作しますが、あなたが指摘したように、結果セット内の結合テーブルからデータを取得することはできません。データはまだプライマリ・テーブルからのものであるため、結果の整合性に違反していません。「すべてのデータはプライマリ・テーブルに属しています」しかし、テーブルAの外部キーを持つ行だけを取得したい場合には便利です。それを指摘してくれてありがとう。整合性チェックが無効の – drew010

+0

プライマリテーブルと結合テーブルの両方から取得できました。 info @cambracaのおかげで – Varshaan

20

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

整合性チェックは、クエリが複数のテーブルを使用しないことを確認するためのものであり、その場所にある場合、行データが単一のテーブルに排他的であるためにZend_Db_Table_Rowオブジェクトが確実に削除または変更され、異なるテーブルのデータが混在しているわけではありません。

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

Zend_Db_Table - Advanced Usageにリファレンスガイドからの引用である(主に拘束し、それが合法SELECTクエリの基準を適用することができるように を検証するために使用されている実施例27

Zend_Db_Table_Selectにスキップただし、 Zend_Db_Table_Rowコンポーネントの柔軟性が必要な場合があり、書き込み可能または削除可能な行を必要としない場合があります。この特定のユーザーの場合は、ret行または 行セットをFALSEの値をsetIntegrityCheck()に渡すことによって行をrieveします。結果の 行または行セットは、save(),削除()を意味し、すべてのフィールド設定メソッドで例外がスローされます)が返されます。

参照:One-to-Many Joins with Zend_Db_Table_Select