今天遇到一个很有趣的事情,以前没有注意过,所以记下来。

先来看例子。

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

CREATE PROCEDURE GetOrderBeforeDays

    @BeforDays INT

AS

BEGIN

    IF @BeforDays < 0

    BEGIN

        DECLARE @Today DATETIME
SET @Today = GETDATE()
DECLARE @Date DATETIME
SET @Date = DATEADD(DAY,@BeforDays,@Today) SELECT * FROM Orders WHERE CONVERT(VARCHAR(10),OrderDate,110) = CONVERT(VARCHAR(10),@Date,110) END
ELSE
BEGIN
SELECT * FROM Orders WHERE CONVERT(VARCHAR(10),OrderDate,110) = CONVERT(VARCHAR(10),@Today,110)
END END GO

这个存储过程创建时不会有什么问题,但实际执行时是不正确的,当参数大于0时并不能获取当天的数据。仔细看会发现@Today变量的定义在第一个IF语句中,但是在ELSE语句中竟然也可以使用,这与C#中的用法有所不同。

原来SQL SERVER中,声明变量的地方开始到声明变量的批处理或存储过程的结尾,因此在ELSE语句中也可以访问到IF语句中定义的变量。

但这会引起一些不必要的错误。如前边的例子中,虽然在ELSE语句中可以访问到定义的变量,但是并没有被赋值,所以执行时是查不到当天的定单的。

所以建议尽可能的把所有的变量和初始化都放在存储过程的最开始,一眼就可以看出定义了哪些变量,并赋了什么值。这样一来可以防止在大量的IF ELSE 语句中不小心重复定义相同的变量而引起不必要的麻烦,也可以避免像前边的例子中的错误

 SET ANSI_NULLS ON

 GO

 SET QUOTED_IDENTIFIER ON

 GO

 CREATE PROCEDURE GetOrderBeforeDays

     @BeforDays INT

 AS

 BEGIN

     DECLARE @Today DATETIME

     SET @Today = GETDATE()

     DECLARE @Date DATETIME

     SET @Date = DATEADD(DAY,@BeforDays,@Today)

     IF @BeforDays < 0
BEGIN
SELECT * FROM Orders WHERE CONVERT(VARCHAR(10),OrderDate,110) = CONVERT(VARCHAR(10),@Date,110)
END
ELSE
BEGIN
SELECT * FROM Orders WHERE CONVERT(VARCHAR(10),OrderDate,110) = CONVERT(VARCHAR(10),@Today,110)
END END GO

【转】SQL SERVER 存储过程中变量的作用域的更多相关文章

  1. SQL Server存储过程中变量使用函数调用变量

    USE  DB名称GO SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGO . CREATE   PROCEDURE     存储过程名 @formID   n ...

  2. SQL Server存储过程中使用表值作为输入参数示例

    这篇文章主要介绍了SQL Server存储过程中使用表值作为输入参数示例,使用表值参数,可以不必创建临时表或许多参数,即可向 Transact-SQL 语句或例程(如存储过程或函数)发送多行数据,这样 ...

  3. Sql Server 存储过程中查询数据无法使用 Union(All)

    原文:Sql Server 存储过程中查询数据无法使用 Union(All) 微软Sql Server数据库中,书写存储过程时,关于查询数据,无法使用Union(All)关联多个查询. 1.先看一段正 ...

  4. sql server存储过程中SELECT 与 SET 对变量赋值的区别

    SQL Server 中对已经定义的变量赋值的方式用两种,分别是 SET 和 SELECT. 对于这两种方式的区别,SQL Server 联机丛书中已经有详细的说明,但很多时候我们 并没有注意,其实这 ...

  5. 【转】sql server存储过程中SELECT 与 SET 对变量赋值的区别

    转自:http://www.cnblogs.com/micheng11/archive/2008/07/08/1237905.html SQL Server 中对已经定义的变量赋值的方式用两种,分别是 ...

  6. sql server存储过程中SELECT 与 SET 对变量赋值的区别 转自Theo

    SQL Server 中对已经定义的变量赋值的方式用两种,分别是 SET 和 SELECT. 对于这两种方式的区别,SQL Server 联机丛书中已经有详细的说明,但很多时候我们 并没有注意,其实这 ...

  7. sql server 存储过程中使用变量表,临时表的分析(续)

    最近,我有一朋友,对我说他的数据库中的很多存储过程,执行都是超时.让我替他看看是什么原因.我一看,原来他的存储过程中用了很多的临时表与变量表.于是我跟他说过犹不及. 在存储过程中使用临时表或变量表,使 ...

  8. SQL Server 存储过程中处理多个查询条件的几种常见写法分析,我们该用那种写法

    本文出处: http://www.cnblogs.com/wy123/p/5958047.html 最近发现还有不少做开发的小伙伴,在写存储过程的时候,在参考已有的不同的写法时,往往很迷茫,不知道各种 ...

  9. SQL Server存储过程中防止线程重入处理方式

    对于线程重入,在C#中有lock关键字锁住一个SyncObject,而SQL Server也可用一个表来模拟实现. 先创建一个同步表,相当于C#中的SyncObject,并插入一条记录(初始值为1) ...

随机推荐

  1. Codeforces Round #303 (Div. 2) D 贪心

    D. Queue time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...

  2. 使用 Spring Security 保护 Web 应用的安全

    安全一直是 Web 应用开发中非常重要的一个方面.从安全的角度来说,需要考虑用户认证和授权两个方面.为 Web 应用增加安全方面的能力并非一件简单的事情,需要考虑不同的认证和授权机制.Spring S ...

  3. ZOJ 1243 URLs

    /*In the early nineties, the World Wide Web (WWW) was invented. Nowadays, most people think that the ...

  4. SQL Server用户自定义函数

    用户自定义函数不能用于执行一系列改变数据库状态的操作,但它可以像系统 函数一样在查询或存储过程等的程序段中使用,也可以像存储过程一样通过EXECUTE 命令来执行.在 SQL Server 中根据函数 ...

  5. 跟上节奏 大数据时代十大必备IT技能(转)

    新的想法诞生新的技术,从而造出许多新词,云计算.大数据.BYOD.社交媒体……在互联网时代,各种新词层出不穷,让人应接不暇.这些新的技术,这些新兴应用和对应的IT发展趋势,使得IT人必须了解甚至掌握最 ...

  6. faster rcnn test demo ---repaired for video input and save the image, label, score et al. into .mat format

    faster rcnn test demo ---repaired for video input and save the image, label, score et al. into .mat ...

  7. ps白平衡

    ps白平衡:在正常光线下看起来是白颜色的东西在有色光或者较暗的光线下看起来可能就不是白色,还有荧光灯下的"白"也是"非白".对于这一切如果能调整白平衡,则在所得 ...

  8. Redis 源码解析

    http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness- ...

  9. 利用C#Marshal类实现托管和非托管的相互转换

    Marshal 类 命名空间:System.Runtime.InteropServices 提供了一个方法集,这些方法用于分配非托管内存.复制非托管内存块.将托管类型转换为非托管类型,此外还提供了在与 ...

  10. .NET垃圾回收 – 非托管资源

    前面一篇文章介绍了垃圾回收的基本工作原理,垃圾回收器并不是可以管理内存中的所有资源.对于所有的托管资源都将有.NET垃圾回收机制来释放,但是,对于一些非托管资源,我们就需要自己编写代码来清理这类资源了 ...