SQL2005以上版本怎樣實現一個比sp_executesql支持 變量傳參功能更強大的存儲過程

  1 use master
  2 go
  3 if object_id('Sp_ExecSQL'is not null
  4     drop proc Sp_ExecSQL
  5 go
  6 /******************************************************************************************************************************************************
  7 注:日期類型要準確性,用字符串傳入或字符串輸出(同sp_executesql同樣存在的問題)
  8 
  9 以10參數為例,寫一下實現方法
 10 
 11 作者:中國風(Roy)
 12 
 13 日期:2008.06.19
 14 ******************************************************************************************************************************************************/
 15 create proc Sp_ExecSQL(
 16                 @s nvarchar(4000)=N'',
 17                 @input nvarchar(1000)='',
 18                 @Parameter1 nvarchar(4000)=null output,
 19                 @Parameter2 nvarchar(4000)=null output,
 20                 @Parameter3 nvarchar(4000)=null output,
 21                 @Parameter4 nvarchar(4000)=null output,
 22                 @Parameter5 nvarchar(4000)=null output,
 23                 @Parameter6 nvarchar(4000)=null output,
 24                 @Parameter7 nvarchar(4000)=null output,
 25                 @Parameter8 nvarchar(4000)=null output,
 26                 @Parameter9 nvarchar(4000)=null output,
 27                 @Parameter10 nvarchar(4000)=null output)
 28 as
 29 set nocount on;
 30 begin try
 31 begin tran
 32 declare @dec nvarchar(4000),@set nvarchar(4000),@update nvarchar(4000),@error nvarchar(200)
 33 select @input=replace(replace(@input,nchar(13)+nchar(10),nchar(32)),nchar(9),nchar(32))
 34 
 35 while charindex(nchar(32)+nchar(32),@input)>0
 36     select @input=replace(@input,nchar(32)+nchar(32),nchar(32))
 37 while charindex(nchar(32)+'@',@input)>0
 38     select @input=replace(@input,nchar(32)+'@','@')
 39 while charindex('@'+nchar(32),@input)>0
 40     select @input=replace(@input,'@'+nchar(32),'@')
 41 
 42 if isnull(@s,'')!>''
 43     return
 44 
 45 if object_id('tempdb..#Parameter'is not null
 46     drop table #Parameter
 47 select 
 48     Row=row_number()over(order by t2.row),
 49     Parameter=left(ltrim(t2.Col),charindex(nchar(32),ltrim(t2.Col)+',@')-1),
 50     ParaType=rtrim(stuff(ltrim(t2.Col),1,charindex(nchar(32),ltrim(t2.Col)),'')),
 51     [Value]=cast(null as nvarchar(4000)),
 52     [Flag]=cast(null as bit),
 53     [IsChar]=cast(null as bit)
 54 into #Parameter
 55 from 
 56     (select convert(xml,'<root><v>'+replace(@input,',@','</v><v>@')+'</v></root>'))T(c)
 57 outer apply
 58     (select row=1,Col=N.v.value('.','nvarchar(100)'from T.c.nodes('/root/v')N(v))T2
 59 
 60 
 61 update #Parameter set ParaType=case when charindex(reverse(N'output'),reverse(ParaType))=1 then rtrim(left(ParaType,len(ParaType)-6))
 62                                     when charindex(reverse(N'out'),reverse(ParaType))=1 then rtrim(left(ParaType,len(ParaType)-3))
 63                                     else  ParaType end
 64 
 65 update a
 66 set [IsChar]=b.[IsChar],[Flag]=case when b.Name is null or (b.ID in(106,108and patindex('%[(]%',replace(ParaType,b.Name,''))>patindex('%[0-9,)]%',replace(ParaType,b.Name,'')))
 67                                     then 1 when  b.[IsChar]=0 and b.ID not in(106,108and ParaType<>b.Name
 68                                     then 1  else 0 end
 69 from 
 70     #Parameter a
 71 outer apply
 72     (select top 1 ID=user_type_id,Name,case when precision>0 and user_type_id not in(58,61then 0 else 1 end [IsChar] from sys.types where  charindex(Name,rtrim(a.ParaType))>0 order by len(Name) desc)b
 73 
 74 if exists(select 1 from #Parameter where [Flag]=1)
 75     begin
 76         set @error=N'檢查格式是否正確'
 77         raiserror 50001 N'#'
 78     end
 79 
 80 
 81 update #Parameter 
 82 set [Value]=case row when 1 then @Parameter1 when 2 then @Parameter2 when 3 then @Parameter3 when 4 then @Parameter4 
 83             when 5 then @Parameter5 when 6 then @Parameter6 when 7 then @Parameter7 when 8 then @Parameter8 
 84             when 9 then @Parameter9 when 10 then @Parameter10 end
 85 
 86 select @dec='',@set='',@update=''
 87 
 88 select 
 89     @dec=@dec+case when row=1 then 'Declare ' else ' ,' end +Parameter+' '+ParaType,
 90     @set=@set+case when row=1 then 'select ' else ' ,' end +Parameter+'='
 91         +case when [IsChar]=1 then isnull(quotename([Value],''''),'Null'else isnull(rtrim([Value]),'Null'end,    
 92     @update=@update+case when row=1 then 'Update #Parameter set [Value]= case Row when ' else ' when ' end+rtrim(Row)+' then convert(nvarchar(4000),'+Parameter+')'
 93 from 
 94     #Parameter
 95 order by row asc
 96 
 97 exec(@dec+' '+@set+' '+@s+' '+@update+' end')
 98 
 99 set @Parameter1= (select [Value] from  #Parameter where row=1)
100 set @Parameter2= (select [Value] from  #Parameter where row=2)
101 set @Parameter3= (select [Value] from  #Parameter where row=3)
102 set @Parameter4= (select [Value] from  #Parameter where row=4)
103 set @Parameter5= (select [Value] from  #Parameter where row=5)
104 set @Parameter6= (select [Value] from  #Parameter where row=6)
105 set @Parameter7= (select [Value] from  #Parameter where row=7)
106 set @Parameter8= (select [Value] from  #Parameter where row=8)
107 set @Parameter9= (select [Value] from  #Parameter where row=9)
108 set @Parameter10=(select [Value] from  #Parameter where row=10)
109 
110 commit tran
111 end try
112 begin catch
113     set @error=isnull(@error,ERROR_MESSAGE())
114     rollback tran
115     raiserror 50001 @error
116 end catch
117 
118 go
119 
120 
121 declare @i int,@Name sysname,@j decimal(18,5)
122 select @i=100
123 exec sp_execsql N'select @j=count(1) from sysobjects where ID>@char','     @    char int        , @j decimal (18,5)   output    ',@i,@j output
124 select @j
125 
126 

 

posted on 2009-10-06 17:55  中國風  阅读(290)  评论(0)    收藏  举报