脚本编写

男娘i 2022-09-24 06:24 265阅读 0赞

一个简单的脚本:

  1. USE Accounting;
  2. DECLARE @Ident int;
  3. INSERT INTO Orders
  4. (CustomerNo,OrderDate, EmployeeID)
  5. VALUES
  6. (1, GETDATE(), 1);
  7. SELECT @Ident = @@IDENTITY;
  8. INSERT INTO OrderDetails
  9. (OrderID, PartNo, Description, UnitPrice, Qty)
  10. VALUES
  11. (@Ident, '2R2416', 'Cylinder Head', 1300, 2);
  12. SELECT 'The OrderID of the INSERTed row is ' + CONVERT(varchar(8),@Ident);

声明变量:

语法:DECLARE @变量名 变量类型。

设置变量中的值:

1、使用SET设置变量:

例:

SET @TotalCost=10

SET @TotalCost=@UnitCost*1.1

注:使用SET,不能将查询得到的值赋给变量——必须将查询语句和SET分开。

例:会产生错误

  1. DECLARE @Test money;
  2. SET @Test = MAX(UnitPrice) FROM [Order Details];
  3. SELECT @Test;

下面的例子不会产生错误:

  1. DECLARE @Test money;
  2. SET @Test = (SELECT MAX(UnitPrice) FROM Sales.SalesOrderDetail);
  3. SELECT @Test;

2、初始化变量:

第一次声明变量时,他的默认值是NULL。

可以在声明的过程中赋值:

  1. DECLARE @Counter INT = 0;
  2. DECLARE @MaxPrice MONEY = (SELECT MAX(UnitPrice) FROM Sales.SalesOrderDetail);

3、使用SELECT设置变量

  1. DECLARE @Test money;
  2. SELECT @Test = MAX(UnitPrice) FROM Sales.SalesOrderDetail;
  3. SELECT @Test;

使用标识列,代码必须:

(1)声明变量。

(2)插入父值。

(3)使用SCOPE_IDENTITY()填充变量。

(4)插入子值。

使用序列时,代码改为:

(1)声明变量。

(2)获取序列中的下一个值。

(3)插入父值和子值。

使用@@ROWCOUNT通过编程来知道影响了多少行:

例:

  1. DECLARE @PersonCount int; --Notice the single @ sign
  2. SELECT * FROM Person.Person;
  3. SELECT @PersonCount = @@ROWCOUNT;
  4. PRINT 'The value of @@ROWCOUNT was ' +
  5. CONVERT(varchar(6),@PersonCount);

将语句分组到批处理中:

为了将一个脚本划分为多个批处理,可以使用GO语句,GO语句具有以下特点:

必须自成一行。

使从脚本的开始部分或者最近一个GO语句(任何一个较近的GO语句)以后的所有语句编译成一个执行计划并发送到服务器,与任何其他批处理无关。

不是T-SQL命令,而是有各种SQL Server命令实用程序识别的命令。

每个批处理单独发送到服务器:

因为每个批处理被独立的处理,所以一个批处理中的错误不会阻止另一个批处理的运行。

例:

  1. DECLARE @MyVarchar varchar(50); --This DECLARE only lasts for this batch!
  2. SELECT @MyVarchar = 'Honey, I''m home...';
  3. PRINT 'Done with first Batch...';
  4. GO
  5. PRINT @MyVarchar; --This generates an error since @MyVarchar
  6. --isn't declared in this batch
  7. PRINT 'Done with second Batch';
  8. GO
  9. PRINT 'Done with third batch'; -- Notice that this still gets executed
  10. -- even after the error
  11. GO

注:GO不是T-SQL命令。

批处理中的错误:

语法错误。

运行错误。

如果查询分析器发现一个语法错误,那么批处理的处理过程会立即被取消。因为语法检查发生在批处理编译或者执行之前,所以在语法检查期间的一个失败意味着还没有批处理被执行——不管语法错误发生在批处理中的什么位置。

运行时错误的工作方式有很大的不同。因为在任何遇到运行时错误之前执行的语句已经完成了,所以除非是未提交的事物的一部分,否则这些语句所做的任何事情将不受影响。运行时错误之外所发生的事情取决于错误的性质。一般而言,运行时错误将终止从错误发生的地方到批处理末端的批处理执行。一些运行时错误只会阻止违反相应约束的语句运行——仍然会执行批处理中的所有其他语句。

何时使用批处理:

使用批处理有若干目的,但是所有的批处理具有一个共同点——当脚本中的一些事情必须发生在另外一件事情之前或者分开发生时,就需要使用批处理。

1、要求有自己的批处理语句

有一些命令必须有他们自己的批处理。

CREARE DEFAULT

CREATE PROCEDURE

CREATE RULE

CREATE TRIGGER

CREATE VIEW

如果想在单个脚本中将这些语句中的任何一个和其他语句进行组合,那么需要通过使用GO语句将他们分散到各自的批处理中。

2、是用批处理建立优先权

例:

  1. CREATE DATABASE Test;
  2. GO
  3. USE Test;
  4. CREATE TABLE TestTable
  5. (
  6. col1 int,
  7. col2 int
  8. );

从命令提示符运行:sqlcmd

  1. SQLCMD -E -Q "SELECT * FROM AdventureWorks2012.Production.Location"

注:-P是指示密码的标记。如果服务器配置成需要其他密码而不是空密码(应该这么设置!),那么需要紧跟在-P之后提供密码,中间没有空格。如果使用Windows身份验证而不是SQL Server身份验证,那么在-U和-P参数的位置用-E参数替换(删除这两个参数,而替换成一个-E参数)。

快速创建一个文本文件以了解sqlcmd语法包括一个文件是的工作方式。在命令提示符下输入代码:

copy con testsql.sql

这样将转入一个空行(没有任何种类的提示符),在该空行中可以输入下列命令:

SELECT * FROM AdventureWorks2012.Production.Location

然后按F6键和回车键(结束文本文件的创建)。这是得到这样一条消息:

1 file(s) copied.

这次使用一个脚本文件重新尝试先前的查询。提示符处的命令行仅仅有一个细微的变化:

sqlcmd -Usa -Pmypass -i testsql.sql

运行结果和以前一样。

-U和-P命令提供了登陆用户名和密码信息。-i参数告诉sqlcmd有一个输入文件,并且紧跟在-i参数后面包含那个文件的名称。最后包含了-o参数以告诉sqlcmd希望见输出写到一个文件中。

使用控制流语句:

IF ……ELSE语句:

例:

  1. IF NOT EXISTS (
  2. SELECT s.name AS SchemaName, t.name AS TableName
  3. FROM sys.schemas s
  4. JOIN sys.tables t
  5. ON s.schema_id = t.schema_id
  6. WHERE s.name = 'dbo'
  7. AND t.name = 'MyIFTest'
  8. )
  9. CREATE TABLE MyIFTest(
  10. Col1 int PRIMARY KEY
  11. );
  12. ELSE
  13. PRINT 'WARNING: Skipping CREATE as table already exists';

将代码组合成块:

BEGIN ……END:

  1. IF NOT EXISTS (
  2. SELECT s.name AS SchemaName, t.name AS TableName
  3. FROM sys.schemas s
  4. JOIN sys.tables t
  5. ON s.schema_id = t.schema_id
  6. WHERE s.name = 'dbo'
  7. AND t.name = 'MyIFTest'
  8. )
  9. BEGIN
  10. PRINT 'Table dbo.MyIFTest not found.';
  11. PRINT 'CREATING: Table dbo.MyIFTest';
  12. CREATE TABLE MyIFTest(
  13. Col1 int PRIMARY KEY
  14. );
  15. END
  16. ELSE
  17. PRINT 'WARNING: Skipping CREATE as table already exists';

CASE语句:

  1. SELECT TOP 10 SalesOrderID,
  2. SalesOrderID % 10 AS 'Last Digit',
  3. Position = CASE SalesOrderID % 10
  4. WHEN 1 THEN 'First'
  5. WHEN 2 THEN 'Second'
  6. WHEN 3 THEN 'Third'
  7. WHEN 4 THEN 'Fourth'
  8. ELSE 'Something Else'
  9. END
  10. FROM Sales.SalesOrderHeader;

搜索CASE语句:

没有输入表达式(即CASE关键字和第一个WHEN关键字之间的部分)。

WHEN表达式必须求值为一个布尔值

搜索CASE语句最棒的地方是可以完全更改构成表达式基础的内容——根据可能的不同的情形,混合搭配列表达式。

  1. SELECT TOP 10 SalesOrderID % 10 AS 'OrderLastDigit',
  2. ProductID % 10 AS 'ProductLastDigit',
  3. "How Close?" = CASE
  4. WHEN (SalesOrderID % 10) < 3 THEN 'Ends With Less Than Three'
  5. WHEN ProductID = 6 THEN 'ProductID is 6'
  6. WHEN ABS(SalesOrderID % 10 - ProductID) <= 1 THEN 'Within 1'
  7. ELSE 'More Than One Apart'
  8. END
  9. FROM Sales.SalesOrderDetail
  10. ORDER BY SalesOrderID DESC;

用WHILE语句进行循环:

  1. WHILE 1 = 1
  2. BEGIN
  3. WAITFOR TIME '01:00';
  4. EXEC sp_updatestats;
  5. RAISERROR('Statistics Updated for Database', 1, 1) WITH LOG;
  6. END

注:尽管可以只执行一条语句,但是对于完整的语句块,几乎所有的WHILE关键字之后都会跟一个BEGIN……END语句块。

BREAK语句用于退出循环而不需要等待到达循环地步和表达式被重新求值。使用BREAK语句通常是较差的做法。

WAITFOR语句:

1、DELAY参数:

DELAY参数指定了等待的时间段,不能指定天数——只能制定小时数、分钟数和秒数。允许延迟的最长时间为24小时。

WAITFOR DELAY ‘01:00’;

2、TIME参数:

TIME参数指定到达指定时间的等待时间。这也不能指定日期——只能是24小时制的某个时间。同样,可延迟的最长时间也是一天。

WAITFOR TIME ‘01:00’;

发表评论

表情:
评论列表 (有 0 条评论,265人围观)

还没有评论,来说两句吧...

相关阅读

    相关 编写脚本批量 ping

    批量 ping 脚本 如果有很多 ip 或者域名,我们要判断哪些能 ping 通,采用自动化脚本特别方便。 先看脚本,如下所示: ping\_ip.sh

    相关 shell脚本基础编写

    shell脚本的格式 名称:Shell 脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议将 .sh 后缀加上,以表示是一个脚本文件。  shell 脚本中一般