1

NOCOUNT这是关于语句的用法和语义的一个小问题。我已经看到它使用了几种不同的方式,我想知道实际需要什么。

我在 MSDN 上看到它带有尾随分号和 GO 语句,如下所示:

SET NOCOUNT ON;
GO

我已经看到没有尾随分号:

SET NOCOUNT ON
GO

我已经看到它没有 GO 语句

SET NOCOUNT ON

我意识到这GO只是一个批次结束的信号,但是应该调用它以NOCOUNT使其生效吗?

分号的意义何在?

4

2 回答 2

0

一个 ';' 是一个内存终止符,我一直认为 GO 语句是一个批处理终止符。

因此,如果您创建 DDL,例如创建 proc、视图、函数或其他对象,您可以执行以下操作:

创建 proc blah 为 .... GO

创建 proc blah2 为 .... GO

然后你可以有一个很好的创建脚本。如果您没有 GO,它会中断,因为它会说:“Create (thing) must be the first statement in a creation ....” 这意味着 SQL 认为您正在为两者执行单个操作。'GO' 说:“新范围,新对象”。所以它解决了这个问题。如果您查看 pubs 和 Northwind(旧的 MS 测试数据库)的创建脚本,我相信他们都在为单个“*.sql”文件使用批处理终止符。它使在单个文件中进行大量创建成为可能。

一个 ; 只会将内存终止到一个语句。大多数时候省略它们是可以的,但是你们中的一些 SQL 专家会知道你无法摆脱它的一个很大的地方是...... CTE!

是的,CTE 会立即对您大喊大叫,因为它以“with”开头,但您也可以使用带有“with”的 (nolock) 提示,因此它需要区分两个事务,因此您应该使用“;”。

例如:

Select * from table -- standard SQL no biggie

或者

Select * from table 
Select * from table2  -- these are fine stacked and will run

但...

Select * from table
with a as (select * from table2) select * from a

将立即中断,因为它不知道 'with' 的上下文已更改为新语句。如果您一丝不苟,正确的 SQL 应该是这样的:

Set NoCount ON;  -- No thank you engine I don't need to see counts
Set Transaction Level Isolation Level Read Uncommitted;  -- Set me to dirty reads as default

Select 
    * 
from table
;

Select 
  * 
from table2
;

SQL 引擎将其视为:

Set NoRead ON;-- 不,谢谢引擎,我不需要查看计数\nSet Transaction Level Isolation Level Read Uncommitted;\n-- 将我设置为默认脏读\n\nSelect\n*\nfrom table\n ;\n\n从表2中选择\n*\n\n;

所以它需要告诉它空白在哪里终止的人的一点帮助。否则它不是人类,不知道一个语句在哪里停止,另一个语句从哪里开始。

不管你做什么,如果你是为别人写的,并且根据明确的指导方针,我总是被告知要做';' 终结者使其成为正式的结束序列。

GO 是一个批处理终止器,但您可以使用它更改上下文,这对于切换数据库非常有用,例如:

使用数据库1 GO

从 TableOnDatabase1 中选择 *;

使用 Database2 GO

从 TableOnDatabase2 中选择 *;

另外为了节省空间,我做了一行,但实际上你应该在单独的行上执行主要的 sql 语法以及子语法,例如:

Select 
    ColumnA
,   ColumnB
,   count(ColumnC) as cnt
From table
Where thing happens
Group by 
    ColumnA
,   ColumnB
Having Count(ColumnC) > 1
Order by ColumnA

编辑常见的现实世界示例:

set nocount on;

declare @Table table ( ints int);
declare @CursorInt int = 1;

while @CursorInt <= 100 
begin 
  insert into @Table values (@CursorInt)

  set @CursorInt += 1
End

-- wait a second engine you did not tell me what happened in the 'Messages' section?!
-- aw come on I want to see each transaction!

Set nocount off;

while @CursorInt <= 200 
begin 
  insert into @Table values (@CursorInt)

  set @CursorInt += 1
End

-- okay that is annoying I did not have to see 100: "(1 row(s) affected)"

您可以在过程范围内根据需要打开和关闭带有内存终止符的“nocount”。当我想在我的过程中看到一些插入并忽略其他插入时,我总是这样做。在某些情况下,如果我想将它们传递出去,我会设置一个输出变量或一个简单的最终行数选择以返回。

于 2013-03-15T18:56:00.627 回答
0

分号结束当前的 SQL 语句。

据我所知,在 SET NOCOUNT ON 之后不需要它。

你不应该需要'GO'来让 NOCOUNT 生效,尽管我不太确定。

于 2013-03-15T17:16:05.530 回答