zoukankan      html  css  js  c++  java
  • SQL Server中Rowcount与@@Rowcount的用法 和set nocount on 也会更新@@Rowcount

    rowcount的用法:


    rowcount的作用就是用来限定后面的sql在返回指定的行数之后便停止处理,比如下面的示例,

    set rowcount 10
    select * from 表A


    这样的查询只会返回表A中的前10条数据。它和 "select top 10 * from 表A" 的作用一样。注意一点,set rowcount 的设置会在整个会话中有效。比如下面的sql示例:

    set rowcount 10
    select * from 表A
    go
    select * from 表B


    表A和表B都只会返回前10条数据。
    要取消set rowcount的限定,只要设置 set rowcount 0 就可以了。

    从上面的示例来看,好像rowcount没有多大的用处,限制查询结果的数据,我们使用top就可以了,而且还不用担心如果忘记取消rowcount的设置而对后面的sql的影响。 但在下面的情况下,rowcount的设置就会给我们带来很大的方便哦。

    我们都知道select top 后面不能加参数,只能使用一个具体的int类型的数字。如果我们想实现top后面跟参数的功能,就只有构造sql字符串,然后使用exec来执行了。比如:

    declare @n int
    declare @sql nvarchar(1000)
    set @n=10
    set @sql='select top '+cast(@n as varchar(10))+' * from 表A'
    exec(@sql)


    先不说上面语句中exec的性能,单从sql的可读性上来看就很不友好。但如果我们使用rowcount来解决,就显的很优雅了,因为set rowcount后面是可以使用参数的。示例如下:

    declare @n int
    set @n=10
    set rowcount @n
    select * from 表A


    注意:set rowcount的限定对修改,删除一样有效。比如下面的示例:

    set rowcount 10
    update 表a set qty=10 where id<100


    这样,上面语句最多只会修改表a中id<100的前10条数据(假设id<100的数据数量大于10)

    删除也是一样

    set rowcount 10
    delete from 表a


    这样,上面的语句最多只会删除表a中前10条数据。

    @@Rowcount的用法


    @@Rowcount与Rowcount看起来很像,只相差了两个@,但它们的功能是不一样的,@@Rowcount主要是返回上次sql语句所影响的数据行数,比如:

    select top 2 * from 表A
    select @@Rowcount


    如果表A中的数据量大于或等于2,那么select @@Rowcount就会返回2,如果只有1条或0条数据,那么select @@Rowcount就会返回1或者0。

    注意,不要把@@Rowcount理解为只返回查询的结果数量,删除,修改,新增等语句,也会正确的返回@@Rowcount值。比如:

    update 表A set gid='a' where gid='a'
    select @@Rowcount


    如果表A中存在gid='a'的数据,那么select @@Rowcount就会返回它所修改数据的行数,如果不存在gid='a'的数据,那么select @@Rowcount就会返回0,删除与新增都是同样。

    那么,哪些地方我们会用到@@Rowcount呢?
    一、可能我们见到@@Rowcount身影最多的地方是触发器中,好的触发器,一般都会在最前面加上if @@rowcount=0 return语句,比如:

    create trigger ti_tablea on tablea after update
    as
    if @@rowcount=0 return
    ……


    这样,如果tablea被修改的数据行数为0,那么触发器ti_tablea就会直接退出,而不用执行后面的代码了。

    二、第二个可能用到的地方就是我们可以使用@@rowcount来作递归或循环。比如下面示例:

    declare @n int
    set @n=1
    select * from client_goods where id=@n

    while @@rowcount>0
    begin
    set @n=@n+1
    select * from client_goods where id=@n
    end


    这个示例是先查询client_goods中是否有id=1的数据,如果有,再查询是否有id=2的数据,一直查下去,直到id没有连续为止。当然大家在看这个示例的时候不要考虑这个示例的意义,它只是说明了@@rowcount可以作为循环条件来用。

    rowcount与@@rowcount的其它用法,欢迎大家在评论中补充。

    每次我们在使用查询分析器调试SQL语句的时候,通常会看到一些信息,提醒我们当前有多少个行受到了影响,这是些什么信息?在我们调用的时候这些信息有用吗?是否可以关闭呢? 

    答案是这些信息在我们的客户端的应用程序中是没有用的,这些信息是存储过程中的每个语句的DONE_IN_PROC 信息。 

    我们可以利用SET NOCOUNT 来控制这些信息,以达到提高程序性能的目的。 

    MSDN中帮助如下: 
     
    SET NOCOUNT 
    使返回的结果中不包含有关受 Transact-SQL 语句影响的行数的信息。 

    语法 
    SET NOCOUNT { ON | OFF } 

    注释 
    当 SET NOCOUNT 为 ON 时,不返回计数(表示受 Transact-SQL 语句影响的行数)。当 SET NOCOUNT 为 OFF 时,返回计数。 

    即使当 SET NOCOUNT 为 ON 时,也更新 @@ROWCOUNT 函数。 

    当 SET NOCOUNT 为 ON 时,将不给客户端发送存储过程中的每个语句的 DONE_IN_PROC 信息。当使用 Microsoft SQL Server 提供的实用工具执行查询时,在 Transact-SQL 语句(如 SELECT、INSERT、 UPDATE 和 DELETE)结束时将不会在查询结果中显示"nn rows affected"。 

    如果存储过程中包含的一些语句并不返回许多实际的数据,则该设置由于大量减少了网络流量,因此可显著提高性能。 

    SET NOCOUNT 设置是在执行或运行时设置,而不是在分析时设置。 

    权限 
    SET NOCOUNT 权限默认授予所有用户。 

    结论:我们应该在存储过程的头部加上SET NOCOUNT ON 这样的话,在退出存储过程的时候加上 SET NOCOUNT OFF这样的话,以达到优化存储过程的目的。 

    还有一种说法:
    前台一般是一个返回就当一个结果集, 不管这个返回是结果集, 还是操作的反馈信息. 
     
    为了保证前台得到的只是真实的记录集, 而不是反馈信息, 因此得使用 set nocount on
    多说两句: 

    1:在查看SqlServer的帮助的时候,要注意“权限”这一节,因为某些语句是需要一定的权限的,而我们往往忽略。 

    2:@@ROWCOUNT是返回受上一语句影响的行数,包括找到记录的数目、删除的行数、更新的记录数等,不要认为只是返回查找的记录数目,而且@@ROWCOUNT要紧跟需要判断语句,否则@@ROWCOUNT将返回0。

  • 相关阅读:
    Feb292012 个人核心竞争力的构建
    让读书成为一种习惯
    软件工厂方法(二):软件工厂应用
    Scrum之 站立例会
    信息系统开发平台OpenExpressApp - AutoUI自动生成界面
    信息系统开发平台OpenExpressApp-内置支持的属性编辑方式
    信息系统开发平台OpenExpressApp - 订单示例(Getting Started)
    需求入门: 原型开发
    信息系统开发平台OpenExpressApp - 学习必备知识
    从IT方法论来谈RUP
  • 原文地址:https://www.cnblogs.com/ilrc/p/5507704.html
Copyright © 2011-2022 走看看