理解T-SQL: 脚本和批处理

      脚本能够将相应的T-SQL命令组织起来,实现一个完整的功能目标。脚本提供了变量、分支、循环等控制语句,可以用来实现一些复杂的任务。通过组织一系列的SQL命令编成脚本和批处理,也减低了数据库管理的复杂性。

1. USE语句

     没啥好讲的,功能就是设置当前的数据库。

2. 声明变量

     使用declare关键字,语法非常简单:
       declare @<变量名> <变量类型> [,@<变量名> <变量类型> [.. ]]
    可以一次声明多个变量。变量声明后,但未赋值前,其值为NULL。

3. 给变量赋值

     有两种方法,使用SET和使用select.
    当知识该值是确切值或者是其它变量时,使用SET、当变量赋值基于一个查询时,使用SELECT

      set   @Test   =   10 ;     set   @test = @var1
     
select   @Test = Max (Unitprice)  from  SalesOrderDetail;



4. 系统变量

      SQL Server有30多个全局系统变量,但以下几个关键的系统变量要记住,经常用到:
     @@ERROR                :    返回当前连接下,最后执行T-SQL语句的错误代码,如无错误则返回0
     @@FETCH_STATUS   :     和FETCH配合使用,返回0表示FETCH有效,%表示超出结果集,-2表示不存在该行
     @@IDENTITY            :     返回最后插入的标识值,作为最后INSERT或者SELECT INTO语句的结果。
     @@ROWCOUNT        :     一个最有用的系统变量,返回最后语句影响的函数
     @@SERVRNAME        :    返回脚本正在运行的本地服务器的名字
     @@TRANCOUNT        :    返回活动事务的数量。

 

5.批处理

     批处理是T-SQL语句集合的逻辑单元。 在批处理的所有语句被整合成一个执行计划。一个批处理内的所有语句要么被放在一起通过解析,要么没有一句能够执行。
    为了将脚本分成多个批处理,需要使用GO语句.以下语句被分为三个批处理:

USE  AdventureWorks
DECLARE   @MyVarchar   varchar ( 50 -- This DECLARE only lasts for this batch!
SELECT   @MyVarchar   =  ‘Honey, I’’m home
PRINT  ‘Done  with  first Batch
GO
PRINT   @MyVarchar   -- This generates an error since @MyVarchar   --isn’t declared in this batch
PRINT  ‘Done  with  second Batch’
GO
PRINT  ‘Done  with  third batch’  --  Notice that this still gets executed -- even after the error
GO

 

     对于以上,每一个批处理都会被独立执行,每个批处理的错误不会阻止其它批处理的运行(批处理2发生错误,不被执行,但批处理3照样可以执行。)
     另外,GO不是一个SQL命令,它只是一个被编辑工具(SQL Server Management Studio,SQLCMD)识别的命令。

 

6.何时使用批处理

      批处理有多种用途,但常被用在某些事情不得不放在前面发生,或者不得不和其它事情分开的脚本中。
     使用以下几个命令时,必须独自成批处理,包括:
     ● CREATE DEFAULT
     ● CREATE PROCEDURE
     ● CREATE RULE
     ● CREATE TRIGGER
     ● CREATE VIEW

 

7. 使用批处理建立优先级

      当需要考虑语句执行的优先顺序时,需要一个任务在另一个任务开始前,前一个任务必须被执行。优先级就需要考虑到。看一下下面的例子:  

CREATE   DATABASE  Test
USE  Test
CREATE   TABLE  TestTable
(
col1 
int ,
col2 
int
)


     以上语句不能正确执行,原因何在,是因为在USE Test时,必须需要前面一条语句"Create DataBase Test”被执行,而要让创建数据库的命令在USE TEST时被执行,必须为前面一个语句创建批处理:

CREATE   DATABASE  Test
GO
USE  Test
CREATE   TABLE  TestTable
(
    col1 
int ,
    col2 
int
)


    然后,用以下语句进行验证,发现表确实被创建了:

use  master;
SELECT  TABLE_CATALOG  FROM  INFORMATION_SCHEMA.TABLES  WHERE  TABLE_NAME  =  ‘TestTable’;


 

8. 创建批处理后的执行

     ●可以使用sqlcmd命令来执行,一般命令格式如下:
      c:\>sqlcmd –Usa –Ppasswd –i mysql.sql
    sqlcmd的命令开关包括很多项,以下列出:

sqlcmd
[  { { -U  [ -P   ]  }  |  –E  < 可信连接 > } ]
[ -S <服务器名> [ \<实例名>  ]  ]  [  -H <工作站名>  ]   [  -d <数据库名>  ]
[  -l <登录超时>  ]   [  -t <查询超时>  ]   [  -h <标题(间行数)>  ]
[  -s <列分隔符>  ]   [  -w <列宽>  ]   [  -a <分组大小>  ]
[  -e  ]   [  -I  ]
[  -c <批处理终止符>  ]   [  -L [ c  ]  ]  [  -q “”  ]   [  -Q “”  ]
[  -m   ]   [  -V  ]   [  -W  ]   [  -u  ]   [  -r [ 0 | 1  ]  ]
[  -i   ]   [  -o   ]
[  -f <代码页> | i:<输入代码页> [ <, o: <输出代码页>  ]
[  -k [ 1 | 2  ]  ]
[  -y <可变类型显示宽度>  ]   [ -Y <固定类型显示宽度>  ]
[  -p [ 1  ]  ]  [  -R  ]   [  -b  ]   [  -v  ]   [  -A  ]   [  -X [ 1  ]  ]  [  -x  ]
[  -?  ]
]



   ● 另外,也可心使用EXEC来执行相应的批处理
          EXEC ((字符串变量)|(字面值命令字符串))
          EXECUTE ((字符串变量)|(字面值命令字符串))

DECLARE   @InVar   varchar ( 50 )
DECLARE   @OutVar   varchar ( 50 )
--  Set up our string to feed into the EXEC command
SET   @InVar   =  ‘ SELECT   @OutVar   =  FirstName  FROM  Person.Contact  WHERE  ContactID  =   1
EXEC  ( @Invar )



    执行EXEC有许多需要留意的地方,具体可查看《SQL Server2005高级程序设计》10.4节。

9. 流控制语句

     T-SQL包括的流控制语句包括:
       ● IF…ELSE
       ● GOTO
       ● WHILE
       ● WAITFOR
       ● TRY/CATCH
       ● CASE

    a. IF…ELSE语句
       IF…ELSE语句用得很频繁,其基本语法是:

IF   < Boolean Expression >
< SQL statement >   |   BEGIN   < code series >   END
[ ELSE
 | BEGIN  END
]


       注意,使用代码行时,别忘了BEGIN与END
       另外,对于IF判断有一个陷阱,就是 if @var = NULL.这样子写法是不对的,因为NULL不等于任何东西,甚至也不等于NULL,应该写成:
         if @var IS NULL

     b. CASE语句
         有不止一句方式来写CASE语句,可以同时输入表达式或布尔表达式协同工作。
         第一种选择是使用一个输入表达式,同每一个WHEN子句使用的值进行比较,这种CASE称作简单CASE: 

CASE   < input expression >
WHEN   < when  expression >   THEN   < result expression >
[ n ]
[ ELSE  ]
END


         第二种情况是把每一个WHEN子句的布尔值提供给表达式,这种CASE叫作搜索CASE:

CASE
WHEN   < Boolean expression >   THEN   < result expression >
[ n ]
[ ELSE  ]
END



        ●● 简单CASE需要使用一个能得到布尔值的表达式,例如:

SELECT   TOP   10  SalesOrderID, SalesOrderID  %   10   AS  ‘Last Digit’, Position  =
CASE  SalesOrderID  %   10
    
WHEN   1   THEN  ‘First’
    
WHEN   2   THEN  ‘Second’
    
WHEN   3   THEN  ‘Third’
    
WHEN   4   THEN  ‘Fourth’
ELSE   ‘Something  Else
END
FROM  Sales.SalesOrderHeader


以上,得出的结果如下所示:
OrderID      Last Digit        Position
---------    -----------     --------------------
10249           9              Something Else
10251           1               First
10258           8               Something Else
10260           0               Something Else
10265           5               Something Else
10267           7               Something Else
10269           9               Something Else
10270           0               Something Else
10274           4               Fourth
10275           5               Something Else
(10 row(s) affected)

、  ●● 搜索CASE和简单CASE类似,但有两点微小的差异:
         在CASE和第一个WHEN之间没有输入表达式
         WHEN表达式必须同一个布尔值相比较 

SELECT   TOP   10  SalesOrderID  %   10   AS  ‘OrderLastDigit’,
ProductID 
%   10   AS  ‘ProductLastDigit’,
“How 
Close ?”  =  
CASE
     
WHEN  (SalesOrderID  %   10 <   3   THEN  ‘Ends  With  Less Than Three’
     
WHEN  ProductID  =   6   THEN  ‘ProductID  is   6
     
WHEN   ABS (SalesOrderID  %   10   -  ProductID)  <=   1   THEN  ‘Within  1
ELSE
   ‘More Than One Apart’
END
FROM  Sales.SalesOrderDetail


         得到的结果如下所示:
OrderLastDigit       ProductLastDigit       How Close?
--------------       ----------------       -------------------
2                               5                   More Than One Apart
3                               2                   More Than One Apart
3                              9                   More Than One Apart
3                               8                   More Than One Apart
2                               2                   More Than One Apart
2                              8                  More Than One Apart
1                              7                   Within 1
1                               0                  Within 1
1                              1                   Within 1
0                              2                  Exact Match!
        搜索CASE把条件放到了WHEN后面,而不是所有的WHEN共用一个条件!

    

    C. WHILE语句
            WHILE语句的语法如下所示:

WHILE   < Boolean expression >    < sql statement >   |
[ BEGIN
     
     [BREAK
]
      
< sql statement >   |   < statement block >
     
[ CONTINUE ]
END ]


          看一个例子,使用WHILE与WAITFOR创建一个监视进程 ,打算每天自动更新一次统计数据:

WHILE   1   =   1
BEGIN
       
WAITFOR  TIME ‘ 01 : 00
       
EXEC  sp_updatestats
       
RAISERROR (‘ Statistics  Updated  for   Database ’,  1 1 WITH   LOG
END


       d. WAITFOR语句
           WAITFOR语句表示时间等待,语法如下:
WAITFOR
       DELAY <’time’> | TIME <’time’>
           DELAY参数指定等待的时间量,不能指定天数,只能指定小时,分钟,秒。最大的延迟时间是24小时,

WAITFOR  DELAY  ‘ 01 : 00 ‘; 等1个小时后执行下面的语句


           TIME参数指定等到一天中某个特定时刻。同样也只能用24小时制: 

WAITFOR  TIME ‘ 01 : 00 ’;  等到今天01:00时刻执行下面的语句


你可能感兴趣的:(理解T-SQL: 脚本和批处理)