为什么SQL Server Management Studio从复制的代码中获取这些语法错误

Jas*_*ish 0 sql-server ssms

因此,在测试某些代码时,我发现粘贴在查询窗口中的代码行为异常。以下是我从哪里获得代码的简化示例:

declare @a nvarchar(max) = '';

select @a = 'select ' + cast(n as char(1)) + ';' + char(13) + 'GO' + char(13) from nums where n = 1;

print @a

exec sp_executesql @a
Run Code Online (Sandbox Code Playgroud)

这是在SSMS的查询窗口中执行的。当然,它会出错,因为该GO分隔符在动态SQL中不起作用。

但是,只是为了确认代码本身是否正确,我将其复制到了新的查询窗口中。继续示例:

select 1;
GO

select 1
GO
Run Code Online (Sandbox Code Playgroud)

第一条语句给出语法错误,第二条语句将GO视为列别名。有趣的是,如果我只是直接在该查询窗口中键入代码,这仍然是正确的。它并没有影响其他窗口或新窗口,只是我将PRINT结果粘贴到的窗口中。

关于这一点的最后一个有趣的事实是,如果LEN()将上面的示例在“错误”查询窗口中与在可正常工作的查询中进行比较,则“错误”查询的长度为26个字符,但正常情况下为31个字符。

我发现退格所有字符似乎无济于事,但是如果我执行全选并删除操作,似乎可以解决此问题。我认为这意味着它将得到一个不可打印的字符,但是如果我执行“全选”并使用“显示所有符号”选项复制到Notepad ++中,则看不到任何注意事项。

有谁知道为什么SSMS会有这种行为?我正在使用版本17.9(如果有问题,请针对SQL Server 2014实例运行)。

Dav*_*oft 6

char(13)是回车(CR)。 char(10)是换行(LF)。

Windows使用CRLF作为行终止符。Linux使用LF作为行终止符。

没有现代环境像脚本那样仅将CR用作行终止符。SSMS恰好通过插入垂直空间来呈现CR,并且此行为可能是从基础Visual Studio代码库继承的。

但是,SSMS的TSQL批处理解析器无法将CR识别为行终止符,因此它不会在CR之后寻找GO符号。它适用于LF或CRLF。