Zend_Db_Select与SQL Server的'FOR XML PATH'

时间:2012-12-04 06:36:34

标签: sql sql-server zend-framework zend-db

我正在尝试使用Zend_Db_Select编写以下查询:

SELECT p1.SKU,
(
 SELECT ',' + Status
 FROM "Products" "p2"
 WHERE p2.SKU = p1.SKU
 ORDER BY "Status"
 FOR XML PATH ('')
)  AS "Statuses"
FROM "Products" p1
GROUP BY SKU

这是我到目前为止所做的:

$s1 = $products->select()
               ->setIntegrityCheck(false)
               ->from(array('p2' => 'Products'),
                      new Zend_Db_Expr("',' + Status")
                 )
               ->where('p2.SKU = p1.SKU')
               ->order('Status');

$s2 = $products->select()
               ->from(array('p1' => 'Products'),
                      array('p1.SKU',
                            'Statuses' => new Zend_Db_Expr('(' . $s1 . ')')
                      )
                 )
               ->group('SKU');

echo $s2;
$dbRowSet = $Products->fetchAll($s2);

这给了我这个:

SELECT "p1"."SKU",
(
 SELECT ',' + Status
 FROM "Products" AS "p2"
 WHERE (p2.SKU = p1.SKU)
 ORDER BY "Status" ASC
) AS "Statuses"
FROM "Products" AS "p1"
GROUP BY "SKU"

我无法弄清楚如何获得所需的FOR XML PATH ('')

此外,我没有使用.运算符$s1调用__toString(),而是将其保留为本机Zend_Db_Select对象。是否还有其他方法可以获得$s1周围的问题?

或者,还有另一种方法可以完成整个查询吗?我想返回每个SKU和所有状态的连接分组(MySQL中的一个GROUP_CONCAT())。该表非常庞大,因此在PHP中迭代它们需要花费不可思议的长时间。

2 个答案:

答案 0 :(得分:0)

不幸的是,Zend Framework对构建MS SQL特定查询没有很大的支持。你可以做的是使用Zend_Db_Adapter_Abstract::query()并完全跳过面向对象的查询抽象。或者,您可以扩展Zend_Db_Select,将相应的代码添加到Zend_Db_Select::$_partsZend_Db_Select::_render*,但是您仍然会得到不完整的支持。

我不太明白你在第二个代码示例中到底做了什么,因为根本没有分配$2变量。

使用__toString()进行字符串构建时,不要担心调用.;表达式最终将以字符串转换的方式进行。

答案 1 :(得分:0)

看起来我很亲密,并且考虑到KSiimson关于字符串转换的评论,这有效:

$s1 = $products->select()
               ->setIntegrityCheck(false)
               ->from(array('p2' => 'Products'),
                      new Zend_Db_Expr("',' + Status")
                 )
               ->where('p2.SKU = p1.SKU')
               ->order('Status');

$s2 = $products->select()
               ->from(array('p1' => 'Products'),
                      array('p1.SKU',
                            'Statuses' => new Zend_Db_Expr('(' . $s1 .
                                " FOR XML PATH(''))")
                      )
                 )
               ->group('SKU');

echo $s2;
$dbRowSet = $Products->fetchAll($s2);

这只是将FOR XML PATH子句以第一个查询作为字符串连接起来。不像我希望的那样优雅,但“完美是善的敌人”。