码迷,mamicode.com
首页 > 数据库 > 详细

笔记-Microsoft SQL Server 2008技术内幕:T-SQL语言基础-10 可编程对象

时间:2015-06-24 07:05:41      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:

关于批处理

下列语句不能在同一批处理中和其他语句同时编译:CREATE DEFAULT、CREATE FUNCTION、CREATE PROCEDURE、CREATE RULE、CREATE SCHEMA、CREATE TRIGGER及CREATE VIEW。例如,以下代码包含一个IF语句,之后在同一批处理中跟着一个CREATE VIEW语句,SQL Server将会报错:

IF OBJECT_ID(Sales.MyView, V) IS NOT NULL DROP VIEW Sales.MyView;

CREATE VIEW Sales.MyView
AS

SELECT YEAR(orderdate) AS orderyear, COUNT(*) AS numorders
FROM Sales.Orders
GROUP BY YEAR(orderdate);
GO

 应该改为:

IF OBJECT_ID(Sales.MyView, V) IS NOT NULL DROP VIEW Sales.MyView;
GO

CREATE VIEW Sales.MyView
AS

SELECT YEAR(orderdate) AS orderyear, COUNT(*) AS numorders
FROM Sales.Orders
GROUP BY YEAR(orderdate);
GO

 GO n 选项,n表示批处理需要执行的次数,比如:

INSERT INTO dbo.T1 DEFAULT VALUES;
GO 100

游标

基本代码:

DECLARE
  @custid     AS INT,
  @prvcustid  AS INT,
  @ordermonth DATETIME,
  @qty        AS INT,
  @runqty     AS INT;

DECLARE C CURSOR FAST_FORWARD /* read only, forward only */ FOR
  SELECT custid, ordermonth, qty
  FROM Sales.CustOrders
  ORDER BY custid, ordermonth;

OPEN C

FETCH NEXT FROM C INTO @custid, @ordermonth, @qty;

SELECT @prvcustid = @custid, @runqty = 0;

WHILE @@FETCH_STATUS = 0
BEGIN
  IF @custid <> @prvcustid
    SELECT @prvcustid = @custid, @runqty = 0;

  SET @runqty = @runqty + @qty;

  INSERT INTO @Result VALUES(@custid, @ordermonth, @qty, @runqty);
  
  FETCH NEXT FROM C INTO @custid, @ordermonth, @qty;
END

CLOSE C;

DEALLOCATE C;

临时表

局部临时表,在命名时以单个#作为前缀,例如#T1。全局临时表,在命名时用两个#作为前缀,如##T1。

动态SQL

DECLARE @sql AS NVARCHAR(100);

SET @sql = NSELECT orderid, custid, empid, orderdate
FROM Sales.Orders
WHERE orderid = @orderid;;

EXEC sp_executesql
  @stmt = @sql,
  @params = N@orderid AS INT,
  @orderid = 10248;
GO

 带有输出参数的sp_executesql,

DECLARE @Counts TABLE
(
  schemaname sysname NOT NULL,
  tablename sysname NOT NULL,
  numrows INT NOT NULL,
  PRIMARY KEY(schemaname, tablename)
);

DECLARE
  @sql AS NVARCHAR(350),
  @schemaname AS sysname,
  @tablename  AS sysname,
  @numrows    AS INT;

DECLARE C CURSOR FAST_FORWARD FOR
  SELECT TABLE_SCHEMA, TABLE_NAME
  FROM INFORMATION_SCHEMA.TABLES;

OPEN C

FETCH NEXT FROM C INTO @schemaname, @tablename;

WHILE @@fetch_status = 0
BEGIN
  SET @sql =
    NSET @n = (SELECT COUNT(*) FROM 
    + QUOTENAME(@schemaname) + N.
    + QUOTENAME(@tablename) + N);;

  EXEC sp_executesql
    @stmt = @sql,
    @params = N@n AS INT OUTPUT,
    @n = @numrows OUTPUT;

  INSERT INTO @Counts(schemaname, tablename, numrows)
    VALUES(@schemaname, @tablename, @numrows);

  FETCH NEXT FROM C INTO @schemaname, @tablename;
END

CLOSE C;

DEALLOCATE C;

SELECT schemaname, tablename, numrows
FROM @Counts;
GO

 在PIVOT中使用动态SQL。先看静态的PIVOT SQL:

SELECT *
FROM (SELECT shipperid, YEAR(orderdate) AS orderyear, freight
      FROM Sales.Orders) AS D
  PIVOT(SUM(freight) FOR orderyear IN([2006],[2007],[2008])) AS P;

 动态的SQL如下:

DECLARE
  @sql       AS NVARCHAR(1000),
  @orderyear AS INT,
  @first     AS INT;

DECLARE C CURSOR FAST_FORWARD FOR
  SELECT DISTINCT(YEAR(orderdate)) AS orderyear
  FROM Sales.Orders
  ORDER BY orderyear;

SET @first = 1;

SET @sql = NSELECT *
FROM (SELECT shipperid, YEAR(orderdate) AS orderyear, freight
      FROM Sales.Orders) AS D
  PIVOT(SUM(freight) FOR orderyear IN(;

OPEN C

FETCH NEXT FROM C INTO @orderyear;

WHILE @@fetch_status = 0
BEGIN
  IF @first = 0
    SET @sql = @sql + N,
  ELSE
    SET @first = 0;

  SET @sql = @sql + QUOTENAME(@orderyear);

  FETCH NEXT FROM C INTO @orderyear;
END

CLOSE C;

DEALLOCATE C;

SET @sql = @sql + N)) AS P;;

EXEC sp_executesql @stmt = @sql;
GO

例程

SQL Server支持三种例程:用户定义函数、存储过程、触发器。

存储过程:

USE TSQLFundamentals2008;
IF OBJECT_ID(Sales.usp_GetCustomerOrders, P) IS NOT NULL
  DROP PROC Sales.usp_GetCustomerOrders;
GO

CREATE PROC Sales.usp_GetCustomerOrders
  @custid   AS INT,
  @fromdate AS DATETIME = 19000101,
  @todate   AS DATETIME = 99991231,
  @numrows  AS INT OUTPUT
AS
SET NOCOUNT ON;

SELECT orderid, custid, empid, orderdate
FROM Sales.Orders
WHERE custid = @custid
  AND orderdate >= @fromdate
  AND orderdate < @todate;

SET @numrows = @@rowcount;
GO

DECLARE @rc AS INT;

EXEC Sales.usp_GetCustomerOrders
  @custid   = 1, -- Also try with 100
  @fromdate = 20070101,
  @todate   = 20080101,
  @numrows  = @rc OUTPUT;

SELECT @rc AS numrows;
GO

触发器:

CREATE TRIGGER trg_T1_insert_audit ON dbo.T1 AFTER INSERT
AS
SET NOCOUNT ON;

INSERT INTO dbo.T1_Audit(keycol, datacol)
  SELECT keycol, datacol FROM inserted;
GO

错误处理

基本代码:

BEGIN TRY
  PRINT 10/2;
  PRINT No error;
END TRY
BEGIN CATCH
  PRINT Error;
END CATCH
GO

 

下面是一个封装了错误处理代码的存储过程:

IF OBJECT_ID(dbo.usp_err_messages, P) IS NOT NULL
  DROP PROC dbo.usp_err_messages;
GO

CREATE PROC dbo.usp_err_messages
AS
SET NOCOUNT ON;

IF ERROR_NUMBER() = 2627
BEGIN
  PRINT Handling PK violation...;
END
ELSE IF ERROR_NUMBER() = 547
BEGIN
  PRINT Handling CHECK/FK constraint violation...;
END
ELSE IF ERROR_NUMBER() = 515
BEGIN
  PRINT Handling NULL violation...;
END
ELSE IF ERROR_NUMBER() = 245
BEGIN
  PRINT Handling conversion error...;
END
ELSE
BEGIN
  PRINT Handling unknown error...;
END

PRINT Error Number  :  + CAST(ERROR_NUMBER() AS VARCHAR(10));
PRINT Error Message :  + ERROR_MESSAGE();
PRINT Error Severity:  + CAST(ERROR_SEVERITY() AS VARCHAR(10));
PRINT Error State   :  + CAST(ERROR_STATE() AS VARCHAR(10));
PRINT Error Line    :  + CAST(ERROR_LINE() AS VARCHAR(10));
PRINT Error Proc    :  + COALESCE(ERROR_PROCEDURE(), Not within proc);
GO

 

笔记-Microsoft SQL Server 2008技术内幕:T-SQL语言基础-10 可编程对象

标签:

原文地址:http://www.cnblogs.com/laixiancai/p/4596685.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!