您的位置:首页 > 其它

脚本编写

2016-07-27 17:25 363 查看
一个简单的脚本:

USE Accounting;
DECLARE @Ident int;

INSERT INTO Orders
(CustomerNo,OrderDate, EmployeeID)
VALUES
(1, GETDATE(), 1);
SELECT @Ident = @@IDENTITY;
INSERT INTO OrderDetails
(OrderID, PartNo, Description, UnitPrice, Qty)
VALUES
(@Ident, '2R2416', 'Cylinder Head', 1300, 2);
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分开。

例:会产生错误

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

下面的例子不会产生错误:
DECLARE @Test money;
SET @Test = (SELECT MAX(UnitPrice) FROM Sales.SalesOrderDetail);
SELECT @Test;

2、初始化变量:
第一次声明变量时,他的默认值是NULL。
可以在声明的过程中赋值:
DECLARE @Counter INT = 0;
DECLARE @MaxPrice MONEY = (SELECT MAX(UnitPrice) FROM Sales.SalesOrderDetail);

3、使用SELECT设置变量
DECLARE @Test money;
SELECT @Test = MAX(UnitPrice) FROM Sales.SalesOrderDetail;
SELECT @Test;


使用标识列,代码必须:
(1)声明变量。
(2)插入父值。
(3)使用SCOPE_IDENTITY()填充变量。
(4)插入子值。
使用序列时,代码改为:
(1)声明变量。
(2)获取序列中的下一个值。
(3)插入父值和子值。

使用@@ROWCOUNT通过编程来知道影响了多少行:
例:
DECLARE @PersonCount int;  --Notice the single @ sign
SELECT * FROM Person.Person;
SELECT @PersonCount = @@ROWCOUNT;
PRINT 'The value of @@ROWCOUNT was ' +
CONVERT(varchar(6),@PersonCount);


将语句分组到批处理中:
为了将一个脚本划分为多个批处理,可以使用GO语句,GO语句具有以下特点:
必须自成一行。
使从脚本的开始部分或者最近一个GO语句(任何一个较近的GO语句)以后的所有语句编译成一个执行计划并发送到服务器,与任何其他批处理无关。
不是T-SQL命令,而是有各种SQL Server命令实用程序识别的命令。
每个批处理单独发送到服务器:
因为每个批处理被独立的处理,所以一个批处理中的错误不会阻止另一个批处理的运行。
例:
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

注:GO不是T-SQL命令。

批处理中的错误:
语法错误。
运行错误。
如果查询分析器发现一个语法错误,那么批处理的处理过程会立即被取消。因为语法检查发生在批处理编译或者执行之前,所以在语法检查期间的一个失败意味着还没有批处理被执行——不管语法错误发生在批处理中的什么位置。
运行时错误的工作方式有很大的不同。因为在任何遇到运行时错误之前执行的语句已经完成了,所以除非是未提交的事物的一部分,否则这些语句所做的任何事情将不受影响。运行时错误之外所发生的事情取决于错误的性质。一般而言,运行时错误将终止从错误发生的地方到批处理末端的批处理执行。一些运行时错误只会阻止违反相应约束的语句运行——仍然会执行批处理中的所有其他语句。

何时使用批处理:
使用批处理有若干目的,但是所有的批处理具有一个共同点——当脚本中的一些事情必须发生在另外一件事情之前或者分开发生时,就需要使用批处理。
1、要求有自己的批处理语句
有一些命令必须有他们自己的批处理。
CREARE DEFAULT
CREATE PROCEDURE
CREATE RULE
CREATE TRIGGER
CREATE VIEW
如果想在单个脚本中将这些语句中的任何一个和其他语句进行组合,那么需要通过使用GO语句将他们分散到各自的批处理中。
2、是用批处理建立优先权
例:
CREATE DATABASE Test;
GO

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


从命令提示符运行:sqlcmd
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语句:
例:
IF NOT EXISTS (
SELECT s.name AS SchemaName, t.name AS TableName
FROM sys.schemas s
JOIN sys.tables t
ON s.schema_id = t.schema_id
WHERE s.name = 'dbo'
AND t.name = 'MyIFTest'
)
CREATE TABLE MyIFTest(
Col1    int        PRIMARY KEY
);
ELSE
PRINT 'WARNING: Skipping CREATE as table already exists';


将代码组合成块:
BEGIN ......END:
IF NOT EXISTS (
SELECT s.name AS SchemaName, t.name AS TableName
FROM sys.schemas s
JOIN sys.tables t
ON s.schema_id = t.schema_id
WHERE s.name = 'dbo'
AND t.name = 'MyIFTest'
)
BEGIN
PRINT 'Table dbo.MyIFTest not found.';
PRINT 'CREATING: Table dbo.MyIFTest';
CREATE TABLE MyIFTest(
Col1    int    PRIMARY KEY
);
END
ELSE
PRINT 'WARNING: Skipping CREATE as table already exists';


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;


搜索CASE语句:
没有输入表达式(即CASE关键字和第一个WHEN关键字之间的部分)。
WHEN表达式必须求值为一个布尔值
搜索CASE语句最棒的地方是可以完全更改构成表达式基础的内容——根据可能的不同的情形,混合搭配列表达式。
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
ORDER BY SalesOrderID DESC;


用WHILE语句进行循环:
WHILE 1 = 1
BEGIN
WAITFOR TIME '01:00';
EXEC sp_updatestats;
RAISERROR('Statistics Updated for Database', 1, 1) WITH LOG;
END

注:尽管可以只执行一条语句,但是对于完整的语句块,几乎所有的WHILE关键字之后都会跟一个BEGIN......END语句块。
BREAK语句用于退出循环而不需要等待到达循环地步和表达式被重新求值。使用BREAK语句通常是较差的做法。

WAITFOR语句:
1、DELAY参数:
DELAY参数指定了等待的时间段,不能指定天数——只能制定小时数、分钟数和秒数。允许延迟的最长时间为24小时。
WAITFOR DELAY '01:00';
2、TIME参数:
TIME参数指定到达指定时间的等待时间。这也不能指定日期——只能是24小时制的某个时间。同样,可延迟的最长时间也是一天。
WAITFOR TIME ‘01:00’;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: