由于某些功能变更,需要对一使用中的数十万数据量的表中ntext类型字段中的某些特定内容进行替换,拿到这个问题时,我想到的第一个方法是写一个存储过程去执行,但是sql server 2000的replace方法不支持对ntext类型的操作,而转为varchar又恐造成数据丢失,故放弃此方法。而后尝试了如下三种方法去实现:
方法一:
使用sqldatareader,用like匹配出需要处理的数据,在程序中执行replace。
对ntext字段使用like匹配将会是很占资源,但是对ntext使用charindex无效,cast为varchar同样当心数据丢失,故仍用like。由于数据量不少,如果是一次全部读出数据则当心影响现有程序的运行。使用 SqlDataReader rdr = cmd.ExecuteReader() 这种方法是否一次只读出一条数据,一直没去验证过,于我是作为一个测试。在执行一次while(rdr.read()){}中的代码之后,修改对应表中的下一条数据,再在程序中去查看下次取出的数据,我测试的结果,程序中拿到的数据仍是修改前的数据,此时我得出的结论是 SqlDataReader rdr = cmd.ExecuteReader() 这种方式还是将数据全部取了出来的。因为取出的数据量太大会影响现有程序的运行,而且如果执行时间长的话,还要考虑数据库的数据被用户修改,而我再更新回去便形成脏数据,故放弃了这种方法。
方法二:
使用 Cursor和updatetext 更新ntext字段部分内容。
create table #temp(
[id] int identity(1,1),
[content] ntext
)
insert into #temp ([content]) values ('我的英文名是--sherman--fdsgfadfadfassherman')
insert into #temp ([content]) values ('sherman测试123时代财富')
insert into #temp ([content]) values ('265g46sfr456a5,><>?5555sherman')
declare @str varbinary(16),@id int,@position int,@len int
set @len = datalength('sherman')
declare cursor_replace scroll Cursor
for select textptr([content]),[id] from #temp
for read only
open cursor_replace
fetch next from cursor_replace into @str,@id
while @@fetch_status=0
begin
select @position=patindex('%sherman%',[content]) from #temp where [id]=@id
while @position>0
begin
set @position=@position-1
updatetext #temp.[content] @str @position @len '时代财富'
select @position=patindex('%sherman%',[content]) from #temp where [id]=@id
end
fetch next from cursor_replace into @str,@id
end
close cursor_replace
deallocate cursor_replace
go
由于这种方法不能控制执行过程,不方便查看进度,而且游标也不是一个好选择,所以也没有用这种方法
方法三
使用xmlhttprequest异步的方法
在程序中用top的方式取单条数据出来,用 indexof 的方式查找特定内容并将符合条件的进行替换,页面进行监控
执行界面如下:
目前是采用这种方法,其实如果用winform程序,在服务器上执行或在客端用webservice方式操作数据库,用委托实现监控程序运行过程,这种方法是否执行速度会快点呢?有待进一步验证。