1

ZF2 と SQL Server 2012 を使用しています。ページネーションを使用してユニオン クエリを作成しようとしています。

ZF2 でのユニオンのサポートは完全ではないようです。方法はありませんunion()が、方法があることがわかりcombine()ます。ユニオンを使用してクエリを作成しますが、ユニオンORDER BYクエリ全体ではなく、最初のクエリに配置します。そのため、ZF2 ページネーターが制限/オフセット部分を追加しようとすると、SQL ServerORDER BYが全体的なクエリを実行する必要があるため、チョークします。

これが私のコードです:

public function fetchPage($fkADUser, array $orderBy, $page = 1, $limit = 20) {

    $inboxSelect = $this->inboxTableGateway->getSql()
        ->select()
        ->columns([
            'pkid',
        ])
        ->join(['f' => 'Fax'], 'FaxInbound.fkFax = f.pkid', [
            'PageCount',
            'CreateTime',
        ])
        ->where(['f.fkADUser = ?' => $fkADUser])
        ->where('FaxInbound.DeleteTime IS NOT NULL');

    $sentSelect = $this->sentTableGateway->getSql()
        ->select()
        ->columns([
            'pkid',
        ])
        ->join(['f' => 'Fax'], 'FaxOutbound.fkFax = f.pkid', [
            'PageCount',
            'CreateTime',
        ])
        ->where(['f.fkADUser = ?' => $fkADUser])
        ->where('FaxOutbound.DeleteTime IS NOT NULL');

    $inboxSelect->combine($sentSelect)->order($orderBy);

    return $this->inboxTableGateway->paginate($inboxSelect, $page, $limit, $this->resultSetPrototype);
}

そして、(SQL プロファイラーから) 生成されたクエリは次のとおりです。

(
    SELECT
        [FaxInbound].[pkid] AS [pkid],
        [f].[PageCount] AS [PageCount],
        [f].[CreateTime] AS [CreateTime]
    FROM
        [FaxInbound]
        INNER JOIN [Fax] AS [f]
            ON [FaxInbound].[fkFax] = [f].[pkid]
    WHERE
        f.fkADUser = @P1
        AND FaxInbound.DeleteTime IS NOT NULL
    ORDER BY
        [CreateTime] DESC
) UNION (
    SELECT
        [FaxOutbound].[pkid] AS [pkid],
        [f].[PageCount] AS [PageCount],
        [f].[CreateTime] AS [CreateTime]
    FROM
        [FaxOutbound]
        INNER JOIN [Fax] AS [f]
            ON [FaxOutbound].[fkFax] = [f].[pkid]
    WHERE
        f.fkADUser = @P2
        AND FaxOutbound.DeleteTime IS NOT NULL
)
OFFSET 0 ROWS
FETCH NEXT 20 ROWS ONLY

ORDER BY結合されたクエリ全体ではなく、最初のクエリにあることに注意してください。だから私が得るエラーメッセージは次のとおりです。

Msg 156, Level 15, State 1, Line 13
Incorrect syntax near the keyword 'ORDER'.
Msg 102, Level 15, State 1, Line 28
Incorrect syntax near 'OFFSET'.
Msg 153, Level 15, State 2, Line 29
Invalid usage of the option NEXT in the FETCH statement.

しかしORDER BY、の直前に外側を移動するOFFSETと、クエリが機能します。

ORDER BY問題は、最初のクエリの代わりにクエリ全体にを配置する方法を知っている人はいますか? または、手動で記述したクエリで ZF2 Paginator を使用する方法はありますか?

4

1 に答える 1

2

ZF2 にバグがあるようです。ZF2 issue trackerに追加しました。

Zend\Db\Sql\Select::$specifications のエントリを並べ替えて問題を修正しました。

オリジナル:

protected $specifications = array(
    'statementStart' => '%1$s',
    self::SELECT => array(...),
    self::JOINS  => array(...),
    self::WHERE  => 'WHERE %1$s',
    self::GROUP  => array(...),
    self::HAVING => 'HAVING %1$s',
    self::ORDER  => array(...),
    self::LIMIT  => 'LIMIT %1$s',
    self::OFFSET => 'OFFSET %1$s',
    'statementEnd' => '%1$s',
    self::COMBINE => '%1$s ( %2$s )',
);

新しい:

protected $specifications = array(
    'statementStart' => '%1$s',
    self::SELECT => array(...),
    self::JOINS  => array(...),
    self::WHERE  => 'WHERE %1$s',
    self::GROUP  => array(...),
    self::HAVING => 'HAVING %1$s',
    'statementEnd' => '%1$s',
    self::COMBINE => '%1$s ( %2$s )',
    self::ORDER  => array(...),
    self::LIMIT  => 'LIMIT %1$s',
    self::OFFSET => 'OFFSET %1$s',
);

ORDER、LIMIT、OFFSET を最後に移動しました。これでクエリが修正されました。

于 2013-09-23T16:55:02.933 に答える