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

时间:2019-03-20 21:44:01

标签: sql-server ssms

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

--output=something

这是在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 分隔符在动态SQL中不起作用。

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

GO

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

关于此的最后一个有趣的事实是,如果我比较了上面示例中在“错误”查询窗口中进行的PRINT与可以正常工作的情况,则“错误”查询的长度为26个字符,但是正常的是31岁。

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

有人知道为什么SSMS会有这种行为吗?我正在使用版本17.9(如果需要,可以在SQL Server 2014实例上运行)。

1 个答案:

答案 0 :(得分:6)

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

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

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

但是,

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