SqlServer_SQLServer2005存储过程概述;

SQL Server 2005 存储过程
出处:http://www.cnblogs.com/qwertWZ/archive/2013/04/22/3036829.html;请支持原版;
摘自:《SQL Server 2005 编程入门经典》 第12章;

存储过程:存储过程(stored procedure)有时也称为sproc。存储过程存储于数据库中而不是在单独的文件中,有输入参数、输出参数以及返回值等。

12.1 创建存储过程:基本语法
>说明:在数据库中,创建存储过程和创建其他对象的过程一样,除它使用AS关键字外;
>基本语法:
CREATE PROCEDUER|PROC
    [
        [schema.][VARYING][=][OUT [PUT]]
        [
            ,[schema.][VARYING][=][OUT [PUT]]
        ]
        [,...]
    ]
[WITH
    RECOMPILE|ENCRYPTION|[EXECUTE AS {CALLER|SELF|OWNER|<'user name'>}]
[FOR REPLICATION]
AS
    |EXTERNAL NAME .
>基本示例
/*创建*/
USE dbName
G
CREATE PROC spName
AS
    SELECT * FROM tablename;
/*执行*/
exec spName;

12.2 使用ALTER改变存储过程
>注意:当使用T-SQL编辑存储过程的时候,需要记住的是它完全取代了现存的存储过程;
>使用ALTER PROC和CREATE PROC的区别在于: ALTER PROC期望找到现存的存储过程,而CREATE则不是;ALTER PROC保留已经建立的存储过程的任何权限,它在系统对象中保留相同的对象ID并允许保留依赖关系;ALTER PROC在其他对象上保留任何依赖关系的信息,这些对象可以调用修改的存储过程;切记,如果执行DROP,然后使用CREATE,这和使用ALTER PROC语句一样,几乎都能得到相同的效果,除了一个很重要的区别——如果使用DROP和CREATE,则需要完全重新建立权限,权限规定了可以使用以及不能使用存储过程的用户;

12.3 删除存储过程
DROP PROC|PROCEDURE ;

12.4 参数化(Parameterization)
1、声明参数
>说明:声明参数需要以下2到4部分信息: 名称、数据类型、默认值、方向;
>语法:
@parameter_name [AS] datatype[= default|NULL] [VARYING] [OUTPUT|OUT];名称有一个简单的规则集合,首先,它必须以@开始,此外,命名规则除了不能有嵌套的空格外,它和SQL的命令规则是相同的;数据类型可以使用SQL Server内置的或用户自定义的类型;切记,声明CURSOR类型参数的时候,必须也使用VARYING和OUTPUT选项;OUTPUT可以简写为OUT;
>示例:
//创建
USE Northwind
GO
CREATE PROC spInsertShippers
    @CompanyName NVARCHAR(40),
    @Phone NVARCHAR(24)
AS
    INSERT INTO Shippers VALUES(@CompanyName, @Phone);
// 执行
EXEC spInsertShippers 'Speedy Shippers, Inc.', '(503)555-5566';
切记,因为并没有为任何参数提供默认值,所以需要提供两个参数;这意味着为了成功运行该存储过程,则必须提供两个参数;
2、为参数提供默认值
>示例:为了使参数是可选的,可以提供默认值,
//创建
USE Northwind
GO

CREATE PROC spInsertShipperOptionalPhone
    @CompanyName NVARCHAR(40),
    @Phone NVARCHAR(24) = NULL
AS
    INSERT INTO Shippers VALUES (@CompanyName, @Phone);
// 执行
EXEC spInsertShipperOptionalPhone 'Speedy Shippers, Inc';
3、创建输出参数
// 创建
USE Northwind
GO

CREATE PROC spInsertOrder
    @CustomerID NVARCHAR(5),
    @EmployeeID INT,
    @OrderDate DATETIME = NULL,
    @RequiredDate DATETIME = NULL,
    @ShippedDate DATETIME = NULL,
    @ShipVia INT,
    @Freight MONEY,
    @ShipName NVARCHAR(40) = NULL,
    @ShipAddress NVARCHAR(60) = NULL,
    @ShipCity NVARCHAR(15) = NULL,
    @ShipRegion NVARCHAR(15) = NULL,
    @ShipPostalCode NVARCHAR(10) = NULL,
    @ShipCountry NVARCHAR(15) = NULL,
    @OrderID INT OUTPUT
AS
    INSERT INTO Orders
    VALUES
    (
        @CustomerID,
        @EmployeeID,
        @OrderDate,
        @RequiredDate,
        @ShippedDate,
        @ShipVia,
        @Freight,
        @ShipName,
        @ShipAddress,
        @ShipCity,
        @ShipRegion,
        @ShipPostalCode,
        @ShipCountry
    )

SELECT @OrderID = @@IDENTITY

// 执行
USE Northwind
GO

DECLARE @MyIdent INT

EXEC spInsertOrder
    @CustomerID = 'ALFKI',
    @EmployeeID = 5,
    @OrderDate = '5/1/1999'
    @ShipVia = 3,
    @Freight = 5.00,
    @OrderID = @MyIdenty OUTPUT

SELECT @MyIdent AS IdentityValue

SELECT OrderID, CustomerID, EmployeeID, OrderDate, ShipName FROM Orders WHERE OrderID = @MyIdent
切记,在存储过程声明中,输出参数需要使用OUTPUT关键字;调用存储过程的时候也必须使用OUTPUT关键字,才能保证参数被正确的输出,注意如果没有使用OUTPUT关键字,不会产生任何错误,但是此时输出参数的值将是无法保证的;赋给输出变量的变量不需要和存储过程中的内部参数拥有相同的名称,例如在本例中,内部参数叫做@OrderID,而传给值的变量叫做@MyIdent;需要使用EXEC(或EXECUTE)关键字来调用存储过程;

12.5 流控制语句
>说明:T(TRANSACTION)-SQL提供大多数流控制语句的典型的选择,IF...ELSE;GOTO;WHILE;WAITFOR;TRY/CATCH;同样也有CASE语句,但是它没有像其他语言中预期的那种流控制级的能力;
12.5.1 IF...ELSE语句
>说明:IF...ELSE语句的实现方式和C是接近相同的,其中的表达式可以是取布尔值的任意表达式;
>语法:
IF
    | BEGIN END
[ELSE
    | BEGIN END]
切记,不恰当的使用NULL值是个常见的陷阱;例如经常会有如下错误出现:IF @MyVar = NULL,在大多数系统上(遵循ANSI标准)这样的表达式永远都不会为真,并且为绕过所有的NULL值结束;想要判断一个值是否为空应该这样来写:IF @MyVar IS NULL,不要忘记了NULL不等于任何值——甚至是NULL,不要使用"="而要使用"IS";
>DATEDIFF函数:
语法:DATEDIFF (, , ) ;
说明:DATEDIFF可以比较日期型数据的任意部分,可以从年到毫秒。start date和end date参数是合法的日期表达式。datepart参数可以是下列的值,年year, yy, yyyy;季度quarter,qq,q;月month, mm,m;星期week,dw,w;日day,dd,d;时hour,hh;分minute, mi,n;秒second, ss,s;毫秒millisecond,ms;
>ELSE子句:结果返回值为NULL的表达式会被当作FALSE从而进入ELSE子句。也就是说,如果IF子句中的语句返回值为FALSE或者NULL,则执行ELSE子句中的语句;
>从DATETIME字段中截取时间:
说明:
为了能截取日期信息,要么把日期分成多个部分,然后不带时间地进行重组,要么可以使用CONVERT函数,该函数能把它转换为不带时间的日期,并且也能把它转换回来;CONVERT()原来是SQL Server中唯一一个用来在数据类型之间转换数据的方法。现在,CAST()复制了它的大部分功能,并且是兼容ANSI的;然而,CONVERT()还是有一些特殊的日期格式化处理的能力,这些是CAST所不具备的;
语法:
CONVERT (, ,