邹老大:
拜读过你很久以前的一个老帖子
http://topic.csdn.net/t/20031124/23/2490908.html
本来以为已经解决了ntext更新的问题,可今天偶然试了一下ntext长度为10000时,发现8000以后的本需要替换的内容没有按预期替换
是不是因为
declare   @p   varbinary(16)这句呢,
真头痛,如何能把ntext里的所有内容都完成替换呢
请指点。谢谢。

解决方案 »

  1.   

    是不是因为 
    declare   @p   varbinary(16)这句呢, --
    这是文件指针,应该无关
    你的text in row选项是什么  
      

  2.   

    两个支持text字段内文字替换的存储过程
    csdn realgz
    (http://topic.csdn.net/u/20080505/20/d2dffbbe-6d6b-41cf-b29a-41149540eafa.html?seed=562172452)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
      

  3.   

    to happyflystone :
    谢谢你的回答。
    我没有设置text in row选项,因为用的是默认值。
    另外怎么查看、修改text in row选项的值呢,
    这个选项有什么用
      

  4.   

    执行了sp_replaceTextWithMultiColPk,报了些错服务器: 消息 16916,级别 16,状态 1,过程 sp_replaceTextWithMultiColPk,行 80
    名为 '#c' 的游标不存在。
    服务器: 消息 16916,级别 16,状态 1,行 1
    名为 '#c' 的游标不存在。
    服务器: 消息 16916,级别 16,状态 1,过程 sp_replaceTextWithMultiColPk,行 104
    名为 '#c' 的游标不存在。
    服务器: 消息 16916,级别 16,状态 1,过程 sp_replaceTextWithMultiColPk,行 105
    名为 '#c' 的游标不存在。
    服务器: 消息 170,级别 15,状态 1,行 1
    第 1 行: '=' 附近有语法错误。
    警告: 已创建表 '#key',但其最大行大小(8297)超过了每行的最大字节数(8060)。如果结果行长度超过 8060 字节,则此表中行的 INSERT 或 UPDATE 将失败。
    警告: 已创建表 '#key',但其最大行大小(16315)超过了每行的最大字节数(8060)。如果结果行长度超过 8060 字节,则此表中行的 INSERT 或 UPDATE 将失败。
    警告: 已创建表 '#key',但其最大行大小(8297)超过了每行的最大字节数(8060)。如果结果行长度超过 8060 字节,则此表中行的 INSERT 或 UPDATE 将失败。
    警告: 已创建表 '#key',但其最大行大小(16315)超过了每行的最大字节数(8060)。如果结果行长度超过 8060 字节,则此表中行的 INSERT 或 UPDATE 将失败。
    警告: 已创建表 '#key',但其最大行大小(8297)超过了每行的最大字节数(8060)。如果结果行长度超过 8060 字节,则此表中行的 INSERT 或 UPDATE 将失败。
      

  5.   

    我用的是sqlserver2000简体中文版。