怎樣實現一個同sp_executesql支持變量傳參功能的存儲過程

--以05環境實現方法
--2000同樣臨時表實現方法相同!! 动态语句语法同sp_executesql相同 --以sp開頭在master生成,其它庫可能直接調用  

use master
go
if object_id('Sp_ExecSQL') is not null
	drop proc Sp_ExecSQL
go
/*********************************************************************************************************
注:日期類型要準確性,用字符串傳入或字符串輸出(同sp_executesql同樣存在的問題)
限制变量不能把'@'需要改为'@a' 在@变量符后要加下其它符号
以10參數為例,寫一下實現方法
作者:中國風(Roy)
日期:2008.06.19
*********************************************************************************************************/
create proc Sp_ExecSQL(
				@s nvarchar(4000)=N'',
				@input nvarchar(1000)='',
				@Parameter1 nvarchar(4000)=null output,
				@Parameter2 nvarchar(4000)=null output,
				@Parameter3 nvarchar(4000)=null output,
				@Parameter4 nvarchar(4000)=null output,
				@Parameter5 nvarchar(4000)=null output,
				@Parameter6 nvarchar(4000)=null output,
				@Parameter7 nvarchar(4000)=null output,
				@Parameter8 nvarchar(4000)=null output,
				@Parameter9 nvarchar(4000)=null output,
				@Parameter10 nvarchar(4000)=null output)
as
set nocount on;
begin try
begin tran
declare @dec nvarchar(4000),@set nvarchar(4000),@update nvarchar(4000),@error nvarchar(200)
select @input=replace(replace(@input,nchar(13)+nchar(10),nchar(32)),nchar(9),nchar(32))

while charindex(nchar(32)+nchar(32),@input)>0
	select @input=replace(@input,nchar(32)+nchar(32),nchar(32))
while charindex(nchar(32)+'@',@input)>0
	select @input=replace(@input,nchar(32)+'@','@')
while charindex('@'+nchar(32),@input)>0
	select @input=replace(@input,'@'+nchar(32),'@')

if isnull(@s,'')!>''
	return

if object_id('tempdb..#Parameter') is not null
	drop table #Parameter
select 
	Row=row_number()over(order by t2.row),
	Parameter=left(ltrim(t2.Col),charindex(nchar(32),ltrim(t2.Col)+',@')-1),
	ParaType=rtrim(stuff(ltrim(t2.Col),1,charindex(nchar(32),ltrim(t2.Col)),'')),
	[Value]=cast(null as nvarchar(4000)),
	[Flag]=cast(null as bit),
	[IsChar]=cast(null as bit)
into #Parameter
from 
	(select convert(xml,'
 
 
  
  
   
   '+replace(@input,',@','
  
  
  
  
   
   @')+'
  
  
 
 '))T(c)
outer apply
	(select row=1,Col=N.v.value('.','nvarchar(100)') from T.c.nodes('/root/v')N(v))T2


update #Parameter set ParaType=case when charindex(reverse(N'output'),reverse(ParaType))=1 then rtrim(left(ParaType,len(ParaType)-6))
									when charindex(reverse(N'out'),reverse(ParaType))=1 then rtrim(left(ParaType,len(ParaType)-3))
									else  ParaType end

update a
set [IsChar]=b.[IsChar],[Flag]=case when b.Name is null or (b.ID in(106,108) and patindex('%[(]%',replace(ParaType,b.Name,''))>patindex('%[0-9,)]%',replace(ParaType,b.Name,'')))
									then 1 when  b.[IsChar]=0 and b.ID not in(106,108) and ParaType<>b.Name
									then 1  else 0 end
from 
	#Parameter a
outer apply
	(select top 1 ID=user_type_id,Name,case when precision>0 and user_type_id not in(58,61) then 0 else 1 end [IsChar] from sys.types where  charindex(Name,rtrim(a.ParaType))>0 order by len(Name) desc)b

if exists(select 1 from #Parameter where [Flag]=1)
	begin
		set @error='檢查格式是否正確'
		raiserror 50001 N'#'
	end


update #Parameter 
set [Value]=case row when 1 then @Parameter1 when 2 then @Parameter2 when 3 then @Parameter3 when 4 then @Parameter4 
			when 5 then @Parameter5 when 6 then @Parameter6 when 7 then @Parameter7 when 8 then @Parameter8 
			when 9 then @Parameter9 when 10 then @Parameter10 end

select @dec='',@set='',@update=''

select 
	@dec=@dec+case when row=1 then 'Declare ' else ' ,' end +Parameter+' '+ParaType,
	@set=@set+case when row=1 then 'select ' else ' ,' end +Parameter+'='
		+case when [IsChar]=1 then isnull(quotename([Value],''''),'Null') else isnull(rtrim([Value]),'Null') end,	
	@update=@update+case when row=1 then 'Update #Parameter set [Value]= case Row when ' else ' when ' end+rtrim(Row)+' then rtrim('+Parameter+')'
from 
	#Parameter
order by row asc

exec(@dec+' '+@set+' '+@s+' '+@update+' end')

set @Parameter1= (select [Value] from  #Parameter where row=1)
set @Parameter2= (select [Value] from  #Parameter where row=2)
set @Parameter3= (select [Value] from  #Parameter where row=3)
set @Parameter4= (select [Value] from  #Parameter where row=4)
set @Parameter5= (select [Value] from  #Parameter where row=5)
set @Parameter6= (select [Value] from  #Parameter where row=6)
set @Parameter7= (select [Value] from  #Parameter where row=7)
set @Parameter8= (select [Value] from  #Parameter where row=8)
set @Parameter9= (select [Value] from  #Parameter where row=9)
set @Parameter10=(select [Value] from  #Parameter where row=10)

commit tran
end try
begin catch
	set @error=isnull(@error,ERROR_MESSAGE())
	rollback tran
	raiserror 50001 @error
end catch

go
exec sp_ms_marksystemobject 'Sp_ExecSQL'
go

declare @i int,@Name sysname,@j decimal(18,5)
select @i=100
exec sp_execsql N'select @j=count(1) from sysobjects where ID>@char','	 @	char int		, @j decimal (18,5)   output	',@i,@j output
select @j
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: sp_executesql是一个SQL Server系统存储过程,可以用于执行动态SQL语句并返回结果。它的语法如下: ``` sp_executesql [@stmt =] N'sql语句', [@params =] N'参数定义', [@param1 =] '值1', ... ``` 其中,@stmt是要执行的SQL语句,@params是一个可选的字符串,用于定义参数。参数定义是一个以逗号分隔的字符串列表,每个参数由其名称、数据类型和方向组成。如果SQL语句中包含参数占位符(例如@parameter_name),则必须在@params字符串中定义该参数。然后,可以在@stmt中使用参数占位符来引用这些参数。 例如,以下代码演示了如何使用sp_executesql执行动态SQL语句,其中包含一个参数占位符: ``` DECLARE @sql NVARCHAR(MAX) = N'SELECT * FROM my_table WHERE id = @id' DECLARE @id INT = 1 EXEC sp_executesql @sql, N'@id INT', @id ``` 在上面的示例中,@sql包含要执行的SQL语句,其中包含一个参数占位符@id。然后,使用sp_executesql执行该语句,并将参数@id传递给它。这将返回my_table表中id为1的行。 ### 回答2: sp_executesql是用于在SQL Server数据库中执行动态SQL语句的系统存储过程。它提供了一种安全、高效的方式来执行动态生成的SQL语句,可以将参数传递给动态SQL语句,以避免SQL注入攻击,并且可以在执行相同的SQL语句时重用执行计划,提高性能。 sp_executesql的基本语法如下: sp_executesql [@stmt =] N'sql语句', [@params =] N'参数定义', [@param1 =] 值1, [@param2 =] 值2, ... 其中,@stmt是动态SQL语句的字符串,@params是定义参数的字符串,参数定义使用@参数名和数据类型的形式。 通过使用sp_executesql,可以将参数传递给动态SQL语句,以避免SQL注入攻击。例如,可以在动态SQL语句中使用参数@name来执行查询操作: DECLARE @name NVARCHAR(50) = N'John' DECLARE @sql NVARCHAR(1000) SET @sql = N'SELECT * FROM Customers WHERE CustomerName = @name' EXEC sp_executesql @sql, N'@name NVARCHAR(50)', @name 使用sp_executesql的另一个优点是,它可以在执行相同的SQL语句时重用执行计划,提高性能。例如,可以使用sp_executesql来执行一个频繁执行的动态SQL语句: DECLARE @sql NVARCHAR(1000) SET @sql = N'SELECT * FROM Orders WHERE OrderDate >= @startDate' EXEC sp_executesql @sql, N'@startDate DATETIME', '2022-01-01' EXEC sp_executesql @sql, N'@startDate DATETIME', '2022-02-01' 在执行第二个EXEC sp_executesql语句时,由于执行计划已经在第一个执行中生成,数据库引擎可以重用该计划,从而节省了资源和时间。 总之,sp_executesqlSQL Server数据库中的一个重要工具,可以安全、高效地执行动态SQL语句,并通过参数化和执行计划的重用提高性能。 ### 回答3: sp_executesql是一个存储过程,用于执行动态SQL语句。它可以接收动态生成的SQL语句以及参数列表作为输入,并执行这些语句。这个存储过程的语法如下: sp_executesql [@stmt =] N'sql语句', -- 需要执行的动态SQL语句 [@params =] N'参数定义列表', -- 参数列表的定义,包括参数的名称、数据类型和长度等信息 [@param1 =] '值1', -- 参数1 [@param2 =] '值2', -- 参数2 ... [@paramN =] '值N' -- 参数N 通过使用sp_executesql存储过程,我们可以在运行时动态生成SQL语句并将参数传递给它,从而实现更灵活的查询和操作数据库。使用sp_executesql的好处之一是可以防止SQL注入攻击,因为参数是作为参数传递给SQL语句,而不是直接拼接到字符串中。 在使用sp_executesql时,我们首先需要提供要执行的动态SQL语句,并使用参数占位符(如@ParamName)来表示需要传递的参数。然后,我们可以定义参数列表,包括参数的名称、数据类型和长度等信息。最后,我们可以通过传递参数的值来执行动态SQL语句。 例如,假设我们需要根据传入的城市名称查询员工信息。我们可以使用sp_executesql执行以下动态SQL语句: DECLARE @city NVARCHAR(50) SET @city = '北京' DECLARE @sql NVARCHAR(1000) SET @sql = N'SELECT * FROM Employee WHERE City = @CityParam' EXEC sp_executesql @sql, N'@CityParam NVARCHAR(50)', @CityParam = @city 通过这种方式,我们可以根据传入的城市名称动态生成SQL语句,并将参数传递给它,从而实现根据不同的城市查询员工信息的功能
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值