MS SQL CONCAT 与"+"查询差异(与原则 2)



我正在使用Doctrine 2接口访问MS SQL数据库。我发现了双方都非常有趣的问题:原则2和MS SQL。

原则 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);

(我是根据内存编写此查询的,如果有问题 - 没关系 - 这是可视化问题( 在SQL Studio中执行原始查询绝对可以与CONCAT函数一起使用。使用"+"则不会。所有具有 nvarchar 类型的列。问题是:区别在哪里?

我在学说中检查了大量的组合以跳过将CONCAT映射到"+"但没有成功,我不得不编写一些虚拟词法分析器扩展来强制将CONCAT函数应用于最终查询。

其他(可能是特定于MS sql服务器(问题是: 当我在测试时

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"列始终正确。

CONCAT+的操作方式不同。如果任何表达式在使用+时具有值NULL,则将返回NULL。对于CONCAT,它将隐式地将NULL替换为'',因此NULL不会被返回。

CONCAT还将隐式地将表达式中的任何值转换为(n)varchar,其中+使用数据类型优先级来确定数据类型,并将表达式中的其他值隐式转换为优先级最高的数据类型。

例子:

SELECT c1,
c2,
c3,
c4,
c1 + c2 + c3 + c4, --NULL 
CONCAT(c1, c2, c3, c4) --'abcdefxyc'
FROM (VALUES('abc','def',NULL,'xyz'))V(c1, c2, c3, c4);

隐式转换:

SELECT c1 + c2 + c3 + c4
FROM (VALUES('abc','def',7,'xyz'))V(c1, c2, c3, c4);

Msg 245,级别 16,状态 1,第 9 行
将 varchar 值"abcdef"转换为数据类型 int 时转换失败。

SELECT CONCAT(c1, c2, c3, c4) --'abcdef7xyz'
FROM (VALUES('abc','def',7,'xyz'))V(c1, c2, c3, c4);

有趣但预期的行为:

SELECT c1 + c2 + c3 + c4 --NULL
FROM (VALUES('abc','def',NULL,7))V(c1, c2, c3, c4);
SELECT c1 + c2 + c3 + c4 --123456790
FROM (VALUES('123','456','789',1))V(c1, c2, c3, c4);

此行为的原因是表达式是从左到右计算的。因此,对于第一个,您必须先'abc' + 'def' = 'abcdef'然后'abcdef' + NULL = NULL(varchar(。最后你有NULL + 7 = NULL,这很好,因为NULL可以隐式转换为int

对于后者,您'123' + '456' = '123456'然后'123456' + '789' = '123456789'.最后你'123456789' + 1 = 123456789 + 1 = 123456790.请注意,在最终表达式中,varchar首先隐式转换为int,然后+运算符充当加法,而不是串联。

CONCAT和"+"都是不同的。 在mysql中,简单的组合/连接我们的数据/刺/数字。 主要区别在于数据类型。

相关内容

  • 没有找到相关文章

最新更新