2

MySQL データベースと Doctrine 1.1.2 を使用しています。

leftJoin を使用してクエリを作成しようとしていますが、何度も問題が発生したため、結果を理解しようとしています。いくつかの異なるテストを実行した後、それはほとんど断続的であるように見えますが、そうであるとは思えません。

以下では、クエリを作成するための DQL とクエリからの出力の両方を貼り付けます。これら 4 つは、「s.id IS NULL」が追加される理由と、「s.id IN ('184158')」が追加される理由を理解しようとして作成した例です。どちらも追加されていなくても問題ありませんが、なぜそこにあるのか、また、DQLに不要であることを伝える方法を誰かに説明してもらえますか?

私が行ったいくつかの調査から、このクエリにサブクエリが含まれているかどうかに関するバグ修正 (#1868) の一部である可能性があることがわかりました。しかし、これにはサブクエリがないため、その問題のテストを確実に進める方法がわかりません。

doctrine/lib/Doctrine/Query.php のバグ修正 #1868 のコードは次のとおりです。

// FIX #1868: If not ID under MySQL is found to be restricted, restrict pk column for null  
//            (which will lead to a return of 0 items)  
$limitSubquerySql = $this->_conn->quoteIdentifier($field)  
    . (( ! empty($subquery)) ? ' IN (' . $subquery . ')' : ' IS NULL')  
    . ((count($this->_sqlParts['where']) > 0) ? ' AND ' : '');  

よろしくお願いします。

$query = Doctrine_Query::create()  
    ->select('s.id, p.id')  
    ->from('Submission s')  
    ->leftjoin('s.Products p ON s.product_id = p.id')  
    ->where('s.id = ?',$id)  
    ->limit(1);  
echo $query->getSqlQuery() . '< br />';  

$query = Doctrine_Query::create()  
    ->select('s.id, p.id, p.field1')  
    ->from('Submission s')  
    ->leftjoin('s.Products p ON s.product_id = p.id')  
    ->where('s.id = ?',$id)  
    ->limit(1);  
echo $query->getSqlQuery() . '< br />';  

$query = Doctrine_Query::create()  
    ->select('s.id, p.id, p.field1, p.field2')  
    ->from('Submission s')  
    ->leftjoin('s.Products p ON s.product_id = p.id')  
    ->where('s.id = ?',$id)  
    ->limit(1);  
echo $query->getSqlQuery() . '< br />';  

$query = Doctrine_Query::create()  
    ->select('s.id, p.id, p.field1, p.field2, p.field3')  
    ->from('Submission s')  
    ->leftjoin('s.Products p ON s.product_id = p.id')  
    ->where('s.id = ?',$id)  
    ->limit(1);  
echo $query->getSqlQuery() . '< br />';    

**-- OUTPUT --**  
**-- $id = 184158**  

SELECT s.id AS s__id, p.id AS p__id  
FROM submission s   
LEFT JOIN products p   
ON (s.prodid = p.id)   
WHERE **s.id IS NULL** AND (s.id = 184158) **<-- Notice the s.id IS NULL**  

SELECT s.id AS s__id, p.id AS p__id, p.field1 AS p__field1   
FROM submission s   
LEFT JOIN products p   
ON (s.prodid = p.id)   
WHERE **s.id IN ('184158')** AND (s.id = 184158) **<-- Notice the s.id IN ('184158')**  

SELECT s.id AS s__id, p.id AS p__id, p.field1 AS p__field1, p.field2 AS p__field2   
FROM submission s   
LEFT JOIN products p   
ON (s.prodid = p.id)   
WHERE **s.id IS NULL** AND (s.id = 184158) **<-- Notice the s.id IS NULL**  

SELECT s.id AS s__id, p.id AS p__id, p.field1 AS p__field1, p.field2 AS p__field2, p.field3 AS p__field3   
FROM submission s   
LEFT JOIN products p   
ON (s.prodid = p.id)   
WHERE **s.id IN ('184158')** AND (s.id = 184158) **<-- Notice the s.id IN ('184158')**  
4

1 に答える 1

2

これは、いくつかの理由で発生します。

1)Doctrineは「行」ではなくオブジェクトを処理するため、結合を追加すると、すぐに単純な制限以上のものが必要になります。たとえば、1対多の関係を持つテーブルの単一の(fetchOne)オブジェクトが必要です。これらの関係SQLの行数に追加して、Doctrineが2段階で実行するようにします。

table1.id table2.id
1,11
1,12
2,11
2,13
2,22
3,33

要求しfetchOneたとすると、2行になりますが、1つのオブジェクトがハイドレイトされます(「id = 1」行の場合)

2)クエリで何も見つからない場合、DQLは一致するものがないことを認識しているため、を追加しますid = NULL。または、何かを見つけた場合は追加します。IN (id-that-is-first)

私は同じ問題を抱えていて、ここに私を導きました、そしてそれはクエリが何も返さなかっただけであることがわかりました。お役に立てれば。

于 2012-11-29T15:25:51.177 に答える