SQL Server进阶(十一)存储过程

存储过程和函数的区别

存储过程是第一次编译之后就会被存储的下来的预编译对象,之后无论何时调用它都会去执行已经编译好的代码。而函数每次执行都需要编译一次。总结下来有下面几个区别:

基本不同:

  1. 函数必须有一个返回值而存储过程则不是必须的(存储过程可以返回0个到n个值);
  2. 函数只能有输入参数而存储过程可以同时又输入和输出参数;
  3. 函数至少有一个参数而存储过程可能需要n个参数;
  4. 函数可以被存储过程调用而存储过程不可以被函数调用;

高级不同:

  1. 存储过程允许SELECT还有DML(INSERT/UPDATE/DELETE)语句而函数只能使用SELECT语句;
  2. 存储过程不可以使用在WHERE/HAVING/SELECT语句中而函数可以
  3. 返回表变量的函数可以和其他表进行JOIN操作;
  4. 内联函数可以看做一个带参数的VIEW去和其他表进行JOIN操作;
  5. 存储过程可以使用try-catch块进行异常处理二函数不可以;
  6. 存储过程中可以使用事务而函数不可以;

总结

  1. 函数有且只有一个输入参数和一个返回值,而存储过程没有这个限制;
  2. 返回表变量的函数可以当做VIEW或者临时表用在WHERE/HAVING/SELECT/JOIN语句中而存储过程不可以;
  3. 存储过程中可以使用try-catch块和事务,而函数中不可以

变量

局部变量  

  1.声明局部变量

DECLARE @变量名  数据类型
DECLARE @name varchar(20)
DECLARE @id int

  2.为变量赋值

SET @变量名 =--set用于普通的赋值
SELECT @变量名 =--用于从表中查询数据并赋值,,可以一次给多个变量赋值

SET @name=‘张三’
SET @id = 1
SELECT @name = sName FROM student WHERE sId=@id

  3.输出变量的值

   SELECT 以表格的方式输出,可以同时输出多个变量;而PRINT 则是以文本的方式输出,一次只能输出一个变量的值

SELECT @name,@id
PRINT @name
PRINT @id
print @name,@id  --错误!!

全局变量

 《SQL Server进阶(十一)存储过程》

  用全局变量

select @@LANGUAGE as '当前使用语言'
select @@SERVERNAME as '当前服务器名称'
select @@TRANCOUNT as '当前连接打开的事务数'
select @@MAX_CONNECTIONS as '可以同时连接的最大数目'
select @@VERSION as '当前服务器版本'
select @@ERROR as '最后一个T-SQL错误的错误号'

IF ELSE

条件选择语法

IF(条件表达式)
  BEGIN --相当于C#里的{
    语句1  ……
  END --相当于C#里的}
ELSE
 BEGIN
    语句1
    ……
  END

WHILE

循环语句语法

WHILE(条件表达式)
  BEGIN --相当于C#里的{
    语句
    ……
    continue --退出本次循环
    BREAK    --退出整个循环
  END --相当于C#里的}

计算1-100之间所有奇数的和

declare @index int = 1
declare @sum int = 0
while(@index <= 100)
begin
    if(@index%2!=0)
    begin
        set @sum=@sum+@index
    end
    set @index=@index+1
end

存储过程

新建存储过程

Create PROCEDURE [dbo].[p_test]
    @type int
AS
BEGIN
    declare @count int
    declare @result varchar(50)
    if(@type =1)
        begin
            select  @count = (select count(*) from dbo.UserGrowthDetail)
            set @result='求第一个总数'
            print @result
            return @count
        end
    else if(@type =2)
        begin
            select  @count = (select count(*) from dbo.UserGrowthValue)
            set @result='求第二个总数'
            print @result
            return @count
        end
END

执行存储过程

GO

DECLARE    @return_value int

EXEC    @return_value = [dbo].[p_test]
        @type = 1

SELECT    'Return Value' = @return_value

GO

 存储过程通用分页

《SQL Server进阶(十一)存储过程》
《SQL Server进阶(十一)存储过程》

Create  PROCEDURE [dbo].[WF_Pager]
@tblName varchar(255), -- 表名
@strGetFields varchar(1000), -- 返回字段列表要足够大
@orderName varchar(255), -- 字段名用于排序
@OrderType bit = 0,--0 升序 1降序
@PageSize int = 10, -- 页尺寸
@PageIndex int, -- 页码
@strWhere varchar(1000) = '' ,-- 查询条件(注意:不要加where) 
@RecordCount int output --总数
AS
BEGIN
    DECLARE @sql nvarchar(4000)
    declare @sortStr varchar(50)--排序方式
    if @OrderType!=1  --升序
    set @sortStr=' asc '
    else      --降序
    set @sortStr=' desc '
    if @strWhere !=''
    set @strWhere=' where '+@strWhere
    SELECT @sql =N'
    DECLARE @temp int;
    DECLARE @minRecord int;
    DECLARE @PageSize int;
    DECLARE @PageIndex int;    
    SET @temp = 0
    SET @minRecord = 0
    SET @PageSize ='+ cast(@PageSize as varchar(10)) +'
    SET @PageIndex = '+ cast(@PageIndex as varchar(10)) +'
    SELECT @RecordCount = COUNT(0) FROM '+@tblName+ @strWhere +'
    --    限制每页记录数,默认每页10项记录    --
    IF(@PageSize < 1)
        SET @PageSize = 10
    --    限制页号 BEGIN    --
    IF(@PageIndex < 1)
        SET @PageIndex = 1
    DECLARE @MaxPageIndex INT  --    最大页数。
    SET @MaxPageIndex = @RecordCount / @PageSize --(完整数量的页的数量)
    IF(@RecordCount % @PageSize > 0)
    BEGIN
        SET @MaxPageIndex = @MaxPageIndex + 1        
    END
    IF (@MaxPageIndex = 0)
    BEGIN
        SET @MaxPageIndex=1
    END
    IF(@PageIndex > @MaxPageIndex)
        SET @PageIndex = @MaxPageIndex
    SET @minRecord = (@PageIndex - 1) * @PageSize;
    SET @temp = @PageIndex * @PageSize;    
SELECT * FROM
    (
        SELECT 
        ROW_NUMBER() OVER (ORDER BY '+@orderName+@sortStr+') AS Item,'+@strGetFields+'  
        FROM '+@tblName+ @strWhere +'
        ) AS T
    WHERE T.Item >= @minRecord + 1
    AND T.Item <= @temp '
    --执行
    EXEC SP_EXECUTESQL @sql, N'@RecordCount varchar(10) output',@RecordCount output
    SELECT @RecordCount
END

View Code

存储过程综合示例

《SQL Server进阶(十一)存储过程》
《SQL Server进阶(十一)存储过程》

USE [SCST]
GO
/****** Object:  StoredProcedure [dbo].[p_test]    Script Date: 2018/8/23 19:43:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[p_test]
    @strWhere varchar(1000),
    @PageSize int = 10, -- 页尺寸
    @PageIndex int = 0, -- 页码
    @RecordCount int output --输出参数 总数
AS
BEGIN
    DECLARE @Result nvarchar(50)
    IF(@strWhere=1)
        BEGIN
            --CET公共表表达式
            with tbStudent as
            (
                select * from Student where Ssex = ''
            )
            SELECT @Result = (select count(*) from tbStudent)

            --输出参数赋值
            SELECT @RecordCount=1
        END
    ELSE
        BEGIN

            SELECT dense_rank() OVER (ORDER BY s.Sage DESC) AS Rank,ROW_NUMBER() OVER(ORDER BY s.S# ASC) as RowNumber,s.S#,s.Sname,s.Ssex,ISNULL(s.Ssex,'空值') as Ssex,
            Sage=(case  Sage
                        when 17 then ''
                        when 18 then '正好'
                        when 19 then ''
                  end
                  )    
            from Student s

            SELECT CAST('12' AS int)

            SELECT CONVERT(VARCHAR(19),GETDATE())

            --exists

            --while
            declare @index int = 1
            declare @sum int = 0
            while(@index <= 100)
            begin
                if(@index%2!=0)
                begin
                    set @sum=@sum+@index
                end
                set @index=@index+1
            end
            print @sum


            SET @Result = '2'
            SELECT @RecordCount=2
        END
        print @Result
    return  @Result
END

View Code

 实战

 

 

资料

https://www.cnblogs.com/skybreak/p/3642593.html

,存储过程是第一次编译之后就会被存储的下来的预编译对象,之后无论何时调用它都会去执行已经编译好的代码。而函数每次执行都需要编译一次。总结下来有下面几个区别:

基本不同:

  1. 函数必须有一个返回值而存储过程则不是必须的(存储过程可以返回0个到n个值);
  2. 函数只能有输入参数而存储过程可以同时又输入和输出参数;
  3. 函数至少有一个参数而存储过程可能需要n个参数;
  4. 函数可以被存储过程调用而存储过程不可以被函数调用;

高级不同:

  1. 存储过程允许SELECT还有DML(INSERT/UPDATE/DELETE)语句而函数只能使用SELECT语句;
  2. 存储过程不可以使用在WHERE/HAVING/SELECT语句中而函数可以
  3. 返回表变量的函数可以和其他表进行JOIN操作;
  4. 内联函数可以看做一个带参数的VIEW去和其他表进行JOIN操作;
  5. 存储过程可以使用try-catch块进行异常处理二函数不可以;
  6. 存储过程中可以使用事务而函数不可以;

总结

  1. 函数有且只有一个输入参数和一个返回值,而存储过程没有这个限制;
  2. 返回表变量的函数可以当做VIEW或者临时表用在WHERE/HAVING/SELECT/JOIN语句中而存储过程不可以;
  3. 存储过程中可以使用try-catch块和事务,而函数中不可以
    原文作者:~沐风
    原文地址: https://www.cnblogs.com/cnki/p/9520338.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞