sql server 存储过程中执行带输出参数的动态 sql

本文介绍了一个SQL Server存储过程的例子,该过程用于动态执行SQL查询,处理用户列表并实现分页,同时包含了死锁和超时检测功能。存储过程接受用户类型、页数、每页大小等参数,并返回总页数和记录数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 这是个经常碰到的问题,比如根据一些条件查询列表,并返回记录数等。下面是个例子,查询用户列表,用临时表实现翻页,并带有死锁和超时检测功能。
CREATE procedure pUserList
(
    
@UserType char(2),
    
@pagenum int,
    
@perpagesize int,
    
@pagetotal int out,
    
@rowcount int out
)
as
    
set nocount on 

    
DECLARE @Err INT,@ErrCounter INT
    
declare @sql nvarchar(2000--声明动态sql执行语句 
    declare @pagecount int --当前页数 
    declare @sWhere nvarchar(200)
    
declare @sOrder nvarchar(100)

    
set @sWhere = ' where 1=1 '
    
if not(@UserType is null)
    
set @sWhere = @sWhere + ' and UserType = ' + @UserType
    
set @sOrder = ' order by UserID '

    
--取得当前数据库的记录总数 
    declare @row_num int 

    LockTimeOutRetry:

    
--创建临时表,作为数据过滤 
    create table #change (T_id int


    
set @sql = 'select @row_num=count(*) from dbo.[User]' + @sWhere
    
exec sp_executesql @sql,N'@row_num int output'@row_num output

    
if @row_num % @perpagesize =0 
        
set @pagetotal = @row_num/@perpagesize
    
else
        
set @pagetotal = @row_num/@perpagesize + 1

    
set @rowcount = @row_num

    
if @row_num > @perpagesize
    
begin
        
set @row_num = @pagenum * @perpagesize 

        
if @row_num = @perpagesize 
        
begin
            
set @sql = N'select top ' + cast(@perpagesize as varchar+ ' UserID,LoginName,RealName from dbo.[User]' + @sWhere + @sOrder
            
exec sp_executesql @sql 

            
SET @Err = @@ERROR
            
IF @Err <> 0 GOTO ErrorHandler 

            
return 0
        
end
        
else
        
begin 
            
set @row_num = (@pagenum-1* @perpagesize 
            
set @pagecount = @row_num 
            
set @sql=N'insert #change (T_id) select top ' + cast(@pagecount as varchar+ ' UserID from dbo.[User] '+@sWhere+' and UserID not in (select T_id from #change)' + @sOrder 
            
exec sp_executesql @sql 
            
set @sql = N'select top ' + cast(@perpagesize as varchar+ ' UserID,LoginName,RealName from dbo.[User] '+@sWhere+' and UserID not in (select T_id from #change)' + @sOrder 
            
exec sp_executesql @sql

            
SET @Err = @@ERROR
            
IF @Err <> 0 GOTO ErrorHandler 

            
return 0

        
end
    
end
    
else
    
begin
        
set @sql = 'select UserID,LoginName,RealName
        from dbo.[User]
' + @sWhere + @sOrder
        
exec sp_executesql @sql

        
SET @Err = @@ERROR
        
IF @Err <> 0 GOTO ErrorHandler 

        
return 0
    
end 

    ErrorHandler:
    
IF (@Err = 1222 OR @Err = 1205AND @ErrCounter = 5
    
BEGIN 
        
RAISERROR ('Unable to Lock Data after five attempts.'16,1
        
return -100
    
END
    
IF @Err = 1222 OR @Err = 1205 -- Lock Timeout / Deadlock
    BEGIN
        
WAITFOR DELAY '00:00:00.25'
        
SET @ErrCounter = @ErrCounter + 1
        
GOTO LockTimeOutRetry
    
END
-- else unknown error
RAISERROR (@err16,1WITH LOG
return -100

GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

SET QUOTED_IDENTIFIER ON 
GO
SET ANSI_NULLS ON 
GO 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值