【问题标题】:Zend_Db_Select with 'FOR XML PATH' for SQL ServerZend_Db_Select 与 SQL Server 的“FOR XML PATH”
【发布时间】:2012-12-04 06:36:33
【问题描述】:

我正在尝试使用 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 中对它们进行迭代需要很长时间。

【问题讨论】:

  • 你能打出相关的表格和字段吗?
  • @KSiimson,就问题而言,有一个“产品”表,其中包含“SKU”和“状态”字段

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


【解决方案1】:

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

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

当您使用. 进行字符串构造时,不必担心__toString() 会被调用;无论哪种方式,表达式最终都会进行字符串转换。

【讨论】:

  • 这就是我在最后一分钟更改变量以获得可读性的结果。我已经修复了第二个 select() 并添加了一些澄清代码。
【解决方案2】:

看起来我很接近,并且考虑到 KSiimson 的关于字符串转换的 cmets,这很有效:

$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 子句与第一个查询作为字符串连接起来。没有我希望的那么优雅,但“完美是善的敌人”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 2017-12-06
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    相关资源
    最近更新 更多