首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >sql NOCOUNT的语义

sql NOCOUNT的语义
EN

Stack Overflow用户
提问于 2013-03-16 01:13:18
回答 2查看 303关注 0票数 1

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

我看到它在MSDN上列出,后面有分号和GO语句,如下所示:

代码语言:javascript
复制
SET NOCOUNT ON;
GO

我在没有尾部分号的情况下看到过:

代码语言:javascript
复制
SET NOCOUNT ON
GO

我在没有GO语句的情况下看到过

代码语言:javascript
复制
SET NOCOUNT ON

我知道GO只是发出批处理结束的信号,但是为了使NOCOUNT生效,应该调用它吗?

分号的意义是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-16 01:16:06

分号结束当前SQL语句。

据我所知,在将NOCOUNT设置为ON之后,就不需要它了。

你不应该需要'GO‘才能让NOCOUNT生效,尽管我对此不太确定。

票数 0
EN

Stack Overflow用户

发布于 2013-03-16 02:56:01

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

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

将proc blah创建为....去

将proc blah2创建为....去

然后你就可以拥有一个很好的创建脚本。如果没有GO,它就会中断,因为它会这样说:"Create (thing)必须是创建中的第一个语句……“这意味着SQL认为您正在为这两个操作执行单个操作。“‘GO”表示:“新的作用域,新的对象”。所以它绕过了这一点。如果你看一下pubs和Northwind (旧的MS测试数据库)的创建脚本,我相信它们都在为一个'*.sql‘文件使用批处理终止符。它使得在一个文件中进行大量的创建成为可能。

A;将只终止内存直到语句。大多数情况下,省略它们是可以的,但你们中的一些SQL专家将知道,您无法摆脱这一点的一个大地方是.....CTE的!

是的,CTE会立即对你大喊大叫,因为它以' with‘开头,但你也可以使用(nolock)提示和' with’,所以它需要区分这两个事务,因此你应该使用';‘。

例如:

代码语言:javascript
复制
Select * from table -- standard SQL no biggie

代码语言:javascript
复制
Select * from table 
Select * from table2  -- these are fine stacked and will run

但是..。

代码语言:javascript
复制
Select * from table
with a as (select * from table2) select * from a

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

代码语言:javascript
复制
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的引擎将其视为:

将NoRead设置为打开;--不,谢谢引擎我不需要查看计数\n设置事务级别隔离级别读取未提交;\n--将我设置为默认的脏读取\n\n从表中选择\n*\n;\n\n从表2中选择\n*\n;

所以它需要从告诉它空格在哪里结束的人那里得到一点帮助。或者它不是人类,不知道一条语句在哪里结束,另一条语句在哪里开始。

无论你做什么,如果你是为别人写的,并且在定义良好的指导方针下,我总是被告知要做';‘结束符,使它成为正式的结束序列。

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

使用Database1 GO

Select * from TableOnDatabase1;

使用Database2 GO

Select * from TableOnDatabase2;

另外,为了节省空间,我只做了一行,但实际上您应该在单独的行上执行主要的sql语法,并且还应该在下面这样的子语法上执行:

代码语言:javascript
复制
Select 
    ColumnA
,   ColumnB
,   count(ColumnC) as cnt
From table
Where thing happens
Group by 
    ColumnA
,   ColumnB
Having Count(ColumnC) > 1
Order by ColumnA

编辑真实世界中常见的示例:

代码语言:javascript
复制
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‘。当我想要看到一些插入而忽略过程中的其他插入时,我总是这样做。在一些情况下,如果我想把它们传递出去,我就会设置一个输出变量,或者简单地选择一个最终的行数来返回。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15438327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档