高分求答案

shenen 2007-09-12 10:51:29
use master

declare @database sysname
declare cursor_name cursor fast_forward read_only for
select [name] from sysdatabases where dbid>6

open cursor_name

FETCH NEXT FROM cursor_name
INTO @database

WHILE @@FETCH_STATUS = 0
BEGIN
execute('if exists(select * from '+@database+'..syscolumns where name=''logtext'' and id=object_id('''+@database+'..logregister''))
begin
if not exists(select * from '+@database+'..syscolumns where name=''logtext_new'' and id=object_id('''+@database+'..logregister''))
begin
alter table '+@database+'..logregister add logtext_new ntext
end
update '+@database+'..logregister set logtext_new=logtext
alter table '+@database+'..logregister drop column logtext
alter table '+@database+'..logregister add logtext ntext
update '+@database+'..logregister set logtext=logtext_new
alter table '+@database+'..logregister drop column logtext_new
end'
)

FETCH NEXT FROM cursor_name
INTO @database
END

CLOSE cursor_name
DEALLOCATE cursor_name

这段代码执行不成功,会报找不到logtext_new找不到的错误,不知道怎么改
...全文
195 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
叶子 2007-09-13
  • 打赏
  • 举报
回复
Limpire(昨夜小楼) ( ) 信誉:100
说的有理!
up
LYDF4151 2007-09-13
  • 打赏
  • 举报
回复
up
Limpire 2007-09-13
  • 打赏
  • 举报
回复
use master

declare @database sysname

declare @i varchar(10)
set @i=0

declare cursor_name cursor fast_forward read_only for
select [name] from sysdatabases where dbid>6

open cursor_name

FETCH NEXT FROM cursor_name
INTO @database

WHILE @@FETCH_STATUS = 0
BEGIN
execute('use '+@database+'
declare @logtext'+@i+' sysname, @logtext_new'+@i+' sysname
select @logtext'+@i+'=''logtext'', @logtext_new'+@i+'=''logtext_new''
if exists(select * from syscolumns where name=@logtext'+@i+' and id=object_id(''logregister''))
begin
if not exists(select * from syscolumns where name=@logtext_new'+@i+' and id=object_id(''logregister''))
begin
execute(''alter table logregister add ''+@logtext_new'+@i+'+'' ntext'')
end
execute(''update logregister set ''+@logtext_new'+@i+'+''=''+@logtext'+@i+')
execute(''alter table logregister drop column ''+@logtext'+@i+')
execute(''alter table logregister add ''+@logtext'+@i+'+'' ntext'')
execute(''update logregister set ''+@logtext'+@i+'+''=''+@logtext_new'+@i+')
execute(''alter table logregister drop column ''+@logtext_new'+@i+')
end'
)

set @i=@i+1

FETCH NEXT FROM cursor_name
INTO @database
END

CLOSE cursor_name
DEALLOCATE cursor_name
Limpire 2007-09-13
  • 打赏
  • 举报
回复
哦,我明白了。

只能对表名进行延迟名称解析和编译执行计划,其它对象名包括字段名,不进行延迟名称解析和编译执行计划。也就是说,在编译执行计划前,除了表名,其它所有对象包括字段名必须存在,否则报错,生成不了执行计划。

------------------------

然而,我的测试怎么又通过了呢,其实并不难理解,我的测试过程如下:

首先在某个库建一个 logregister 表,就一个字段 logtext,插入一些数据。
把语句 PRINT 出来,去到建表的库,逐条手工执行,没问题,再一起执行,没问题。
然后我把你的语句加了 USE 这一行,执行,仍然没问题。

所以我的测试貌似通过了,其实不然,我逐条执行的时候,已经生成执行计划,保存在高速缓存,其后的两次执行,都是使用高速缓存中的执行计划。

------------------------

行延迟名称解析和编译,就是你所为的“扫描”,这是没得改的,只对表名延迟,其它都不能延迟。

不过可以在 EXECUTE 里再 EXECUTE,通过变量绕过去,下面给出的代码肯定是OK的了,抱歉抱歉!
Limpire 2007-09-12
  • 打赏
  • 举报
回复
我测试过的呀
Limpire 2007-09-12
  • 打赏
  • 举报
回复
而且能执行啊
Limpire 2007-09-12
  • 打赏
  • 举报
回复
加了这句就没报错啊
shenen 2007-09-12
  • 打赏
  • 举报
回复
你加个'use '+@database+'没有用的.
主要原因是,执行器在执行前扫描语句时发现找不到logtext_new
如果它去顺序执行是没有错误的.
不知道有没有办法关闭那个扫描

shenen 2007-09-12
  • 打赏
  • 举报
回复
你把我的代码拷贝一份干嘛^_^
Limpire 2007-09-12
  • 打赏
  • 举报
回复
use master

declare @database sysname
declare cursor_name cursor fast_forward read_only for
select [name] from sysdatabases where dbid>6

open cursor_name

FETCH NEXT FROM cursor_name
INTO @database

WHILE @@FETCH_STATUS = 0
BEGIN
execute('use '+@database+'
if exists(select * from '+@database+'..syscolumns where name=''logtext'' and id=object_id('''+@database+'..logregister''))
begin
if not exists(select * from '+@database+'..syscolumns where name=''logtext_new'' and id=object_id('''+@database+'..logregister''))
begin
alter table '+@database+'..logregister add logtext_new ntext
end
update '+@database+'..logregister set logtext_new=logtext
alter table '+@database+'..logregister drop column logtext
alter table '+@database+'..logregister add logtext ntext
update '+@database+'..logregister set logtext=logtext_new
alter table '+@database+'..logregister drop column logtext_new
end'
)

FETCH NEXT FROM cursor_name
INTO @database
END

CLOSE cursor_name
DEALLOCATE cursor_name

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧