Ошибка в SQL Server 2017 - PullRequest
       7

Ошибка в SQL Server 2017

0 голосов
/ 05 июня 2018

Я хочу сообщить об ошибке и обходном пути в SQL Server 2017. Microsoft предложила открыть сообщение здесь, так что ... Проблема связана с конкатенацией строк в сочетании с CAST и REPLACE.Что-то, что встречается в моем коде довольно часто.Запустите этот запрос:

USE master;

PRINT @@Version

DECLARE @l NVARCHAR(MAX) = '';

SELECT @l += CAST(s.object_id AS NVARCHAR(50)) + ' ' + REPLACE(s.name, 'x', 'y') + ', '
FROM sys.tables s
ORDER BY s.name;

PRINT '> ' + @l;

SET @l = '';

SELECT @l = @l + CAST(s.object_id AS NVARCHAR(50)) + ' ' + REPLACE(s.name, 'x', 'y') + ', '
FROM sys.tables s
ORDER BY s.name;

PRINT '> ' + @l;

На моих серверах вывод:

Microsoft SQL Server 2017 (RTM-CU6) (KB4101464) - 14.0.3025.34 (X64) 
    Apr  9 2018 18:00:41 
    Copyright (C) 2017 Microsoft Corporation
    Web Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: ) (Hypervisor)

    > 1787153412 MSreplication_options, 117575457 spt_fallback_db, 133575514 spt_fallback_dev, 149575571 spt_fallback_usg, 1483152329 spt_monitor, 
    > 1483152329 spt_monitor, 

Так что использование @l + = работает, @l = @l + - нет.Когда вы опускаете CAST или REPLACE, результаты совпадают.

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Как вы упомянули, что вы используете SQL Server 2017, я предлагаю использовать STRING_AGG и не полагаться на неопределенное поведение.

SELECT STRING_AGG(CONCAT(s.object_id,' ',REPLACE(s.name, 'x', 'y')), ',')      
       WITHIN GROUP(ORDER BY s.name)
FROM sys.tables s

DBFiddle Demo

0 голосов
/ 05 июня 2018

См. этот ответ , но ...

Код дает те же результаты (неправильно) на SQL Server 2016 и 2014
Все в порядке в 2012

Это как выражения оцениваются

  • @l += blah = бла полностью вычисляется, затем объединяется
  • @l = @l + blah = сцепляется слева направо, затем присваивается

ЛюбойТаким образом, использование этого метода для генерации CSV является внутренней реализацией, которая, вероятно, не должна зависеть от

. Это работает (добавлены круглые скобки вокруг CAST + replace), потому что оно вызывает правильный порядок оценки

SELECT 
    @l = @l + (CAST(s.object_id AS NVARCHAR(50)) + ' ' + REPLACE(s.name, 'x', 'y') + ', ')
FROM sys.tables s
ORDER BY s.name;
  • @l = @l + (blah) = бла полностью вычисляется, затем объединяется
...