zoukankan      html  css  js  c++  java
  • 【转】SQL SERVER 存储过程中变量的作用域

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

    先来看例子。

    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 语句中不小心重复定义相同的变量而引起不必要的麻烦,也可以避免像前边的例子中的错误

     1 SET ANSI_NULLS ON
     2 
     3 GO
     4 
     5 SET QUOTED_IDENTIFIER ON
     6 
     7 GO
     8 
     9  
    10 
    11 CREATE PROCEDURE GetOrderBeforeDays
    12 
    13     @BeforDays INT
    14 
    15 AS
    16 
    17 BEGIN
    18 
    19     DECLARE @Today DATETIME
    20 
    21     SET @Today = GETDATE()
    22 
    23     DECLARE @Date DATETIME
    24 
    25     SET @Date = DATEADD(DAY,@BeforDays,@Today)
    26 
    27     IF @BeforDays < 0
    28     BEGIN
    29     SELECT * FROM Orders WHERE CONVERT(VARCHAR(10),OrderDate,110) = CONVERT(VARCHAR(10),@Date,110)
    30     END
    31     ELSE
    32     BEGIN
    33     SELECT * FROM Orders WHERE CONVERT(VARCHAR(10),OrderDate,110) = CONVERT(VARCHAR(10),@Today,110)
    34     END
    35 
    36 END
    37 
    38 GO
  • 相关阅读:
    C++中的结构体
    C++转换
    C++常见问题解答
    hdu 1491
    hdu 1253
    [恢]hdu 2529
    [恢]hdu 2539
    hdu 1708
    [恢]hdu 2512
    [恢]hdu 2401
  • 原文地址:https://www.cnblogs.com/gates/p/4149251.html
Copyright © 2011-2022 走看看