【发布时间】:2019-12-06 11:05:08
【问题描述】:
我正在使用 Doctrine 2 接口访问 MS SQL 数据库。我发现了双方都非常有趣的问题:Doctrine 2 和 MS SQL。
Doctrine 2 出于某种原因更改查询
$this->getEntityManager()->createQueryBuilder()
->from(table::class, 'il')
->select('CONCAT(il.col1,il.col2,il.col3) AS concated')
更改为类似(它使用自己的别名):
SELECT (t0_.col1+ t0_.col2+ t0_.col3) AS sclr_0 FROM tableName t0_
最重要的 - 它将CONCAT 更改为带有“+”的表达式。但它工作正常(或者看起来确实如此),直到我想将连接字符串与其他表中的值进行比较......
$targetQueryBuilder->getEntityManager()->createQueryBuilder()
->from($namespace, 's')
->select('1')
->where('CONCAT(il1.col1, il1.col2, il1.col3) = s.controlValue')
->andWhere('s.tableName = :tablename')
->andWhere('s.tableRowIdentifier='.$rowIdentifier);
(我是凭记忆写这个查询的,如果有问题 - 没关系 - 是为了可视化问题)
使用 CONCAT 函数在 SQL Studio 中执行原始查询绝对可以正常工作。使用“+”则不然。所有具有 nvarchar 类型的连接列。问题是:区别在哪里?
我在原则中检查了大量组合以跳过将 CONCAT 映射到“+”但没有成功,我不得不编写一些虚拟词法分析器扩展来强制将 CONCAT 函数应用于最终查询。
其他(可能是特定于 ms sql server)的问题是: 测试的时候
SELECT
(i1_.NameUnternehmen + i1_.Land + i1_.Ort + i1_.Straße + i1_.Postleitzahl) AS a,
CONCAT(i1_.NameUnternehmen , i1_.Land , i1_.Ort , i1_.Straße , i1_.Postleitzahl) AS c
FROM tablename
(Straße 列名称在此问题中看起来并不重要)
使用 WHERE 语句比较连接字符串与控制值时,选择结果不同。
->where('CONCAT(il1.col1, il1.col2, il1.col3) = s.controlValue') - 一切都正确
->where('(il1.col1 + il1.col2 + il1.col3) = s.controlValue') - 结果列“a”为空。我刚刚测试过,在其他表上它有时不为空。我不知道为什么。
“c”列总是正确的。
【问题讨论】:
-
Larnu 很好地解释了这些差异。你可以做
ISNULL(il1.col1, '') + ...或COALESCE(il1.col1, '') + ...但是 eww。不知道为什么教义会改变查询。看起来像一个大错误。
标签: php sql-server doctrine-orm