两个支持text字段内文字替换的存储过程

http://topic.csdn.net/u/20080505/20/d2dffbbe-6d6b-41cf-b29a-41149540eafa.html

--这样代码好看点,无他 
if object_id('sp_replaceTextWithMultiColPk') is not null 
drop  proc sp_replaceTextWithMultiColPk 
go 

create procedure sp_replaceTextWithMultiColPk 
@tableName sysname,@colName sysname,@oldStr nvarchar(512),@newStr nvarchar(512),@whereStr nvarchar(200)='' 
/* 
为一个表内的text做统一替换的存储过程 
缺点:慢,而且事实上还没办法支持任意表,而且代码看起来难受 
因为 varchar的长度有限,当然还可以扩展,不过在sql 2005 里已经没这个问题了,懒得再写。 
realgz 2008-05-05 

*/ 
as 
begin 
set nocount on 
declare @cursor nvarchar(4000),@fetch nvarchar(4000),@insert nvarchar(4000),@where nvarchar(4000) 
declare @replaceExec nvarchar(4000),@checkExec nvarchar(4000) 
declare @rpPtr varbinary(16),@rpPostion int,@rpLen int 
if object_id('tempdb..#key') is not null 
drop table #key 

--获得主键列表 
select  sc.name keyName  into #key  from 
sysobjects so 
join  sysindexes idx on so.parent_obj=idx.id 
join sysindexkeys idk on so.parent_obj=idk.id and idx.indid = idk.indid 
join syscolumns sc on so.parent_obj=sc.id and idk.colid=sc.colid 
where so.xtype='PK' and so.parent_obj =object_id(@tableName) and idx.status & 0x800>0 

if @@rowcount < 1 
begin 
raiserror ('表不符合要求或者没有这个表',12,1) 
return 
end 


--增加键值列 
alter table #key add keyValue sql_variant 
alter table #key add primary key(keyName) 

--替换的长度 
select @rpLen=len(@oldStr),@oldStr='%'+@oldStr+'%' 

--游标声明语句 
select @cursor ='declare #c cursor static  for  select textptr('+@colname+'),PATINDEX ('''+replace(@oldStr,'''','''''')+''','+@colname+')-1' 
select @cursor = @cursor +',['+keyName+']'  from #key  

select @cursor = @cursor +' from ' +@tablename+' '+@whereStr 



--为游标的提取生成语句 
select @fetch='',@insert='',@where='' 
select @fetch = @fetch +'declare @'+keyName +' sql_variant '+char(13) from #key 
select @fetch = @fetch +'fetch next  from #c into @rpPtr,@rpPostion' 
select @fetch = @fetch +',@'+keyName +char(13)  from #key 

--把游标提取出来的值放到临时表的语句 
select @insert = @insert +' insert into #key(keyName,keyValue ) ' 
select @insert = @insert + ' select '''+replace(keyName,'''','''''')+''',@'+keyName+' union all'  +char(13)  from #key 
select @insert = left(@insert,len(@insert)-10) 


select @fetch=@fetch +@insert 


--每次获得游标行对应text指针的语句 
select @where =' where 1=1' 
select @where =@where +' and ['+keyName+']= (select keyValue from #key where keyName = '''+replace(keyName,'''','''''')+''')' from #key 

--改写的sql 
select @replaceExec =  'updatetext '+@tablename+'.'+@colname+' @rpPtr @rpPostion  @rpLen @NewStr' 

--检查是否存在目标的sql 
select @checkExec =' select @rpPostion = PATINDEX ('''+replace(@oldStr,'''','''''')+''','+@colname+')-1 from ' +@tablename+@where 



--声明游标 
exec sp_executesql @cursor 
truncate table #key 
open #c 

--提取第一行 
exec sp_executesql @fetch,N'@rpPtr varbinary(16) output,@rpPostion int  output',@rpPtr output,@rpPostion  output 
--print @fetch 

while @@fetch_status=0 
begin 

--只要@rpPostion>0 证明还需要替换 
  while @rpPostion>0 
  begin 
--替换 

exec sp_executesql @replaceExec,N' @rpPtr varbinary(16),@rpPostion int,@rpLen int,@newStr nvarchar(512)',@rpPtr,@rpPostion,@rpLen,@NewStr 

--重新判断是否需要替换 
exec sp_executesql @checkExec,N'@rpPostion int output',@rpPostion output 
  end 
truncate table #key 

--提取下一行 
exec sp_executesql @fetch,N'@rpPtr varbinary(16) output,@rpPostion int output',@rpPtr output,@rpPostion  output 
end 
close #c 
deallocate #c 
if object_id('tempdb..#key') is not null 
drop table #key 
set nocount off 
end 

go
快乐渡过每一天,减肥坚持每一天