动态SQL当然可以。--测试代码
if exists(select 1 from sysobjects where name='up_test')
drop proc up_test
GO
create proc up_test
as
select top 10 id,name into #t from sysobjects
--alter table #t add test char(1) --使用动态SQL也不行exec ('alter table #t add test char(1)')
update #t
set test='1'
select * from #t
drop table #t
GOexec up_test

解决方案 »

  1.   

    sql 的执行是先做执行计划, 做执行计划的时候, 没有发生 alter 的操作, 当然就没有这个列, 没有这个列, 做执行计划当然报错啦.
      

  2.   

    应该用第2种方法处理, 如果要定义列的类型, 可以用:convert(char(1), '0') as test
      

  3.   

    使用动态 T-SQL 的话, 你应该只把后面的 UPDATE 放进去, 这样 UPDATE 因为在 EXEC 中, 会在 ALTER 完成之后做执行计划, 这时就可以了
      

  4.   

    这样可以
    create proc up_test
    as
    select top 10 id,name into #t from sysobjects
    alter table #t add test char(1) --使用动态SQL也不行
    exec('
    update #t
    set test=''1''
    ')select * from #t
    drop table #t
    GO
      

  5.   

    谢谢各位!之前我写的动态SQL有问题,所以报错.
    试了下wang的可以.但是不明白就是alter table ...执行后,select 是可以输出这个列的.为个么不能update呢?
      

  6.   

    zjcxc(邹建) ( ) 信誉:673    Blog   加为好友  2007-07-09 10:48:09  得分: 0  
     
     
       sql 的执行是先做执行计划, 做执行计划的时候, 没有发生 alter 的操作, 当然就没有这个列, 没有这个列, 做执行计划当然报错啦.
      
    --------------------------------------------------
    多谢老大也来捧场~!
    小弟愚笨,这句话没理解透.
    发生错误是在update处,那也就是update的时候没有发生alter操作,但是如果把alter改成动态SQL就可以.而且alter后select是有这个字段的,实在不知道SQL是怎么处理的!!
      

  7.   

    简单地说, 楼主应该知道如何看执行计划的啦?
    create table #(id int)
    alter table # add col int
    exec('update # set col = 1')
    drop table #对于上面的语句 , 按 Ctrl + L 看到的执行计划是什么? 
    对于 EXEC 的那句, 你看不到它里面的执行计划是什么吧? 这是因为 EXEC 里面的执行, 是执行到那一句的时候, 再根据EXEC 的内容去生成执行计划的.
    而 EXEC 的语句, 按 Ctrl + L 的时候, 你都可以看到语句是怎么执行的所以为什么放在 EXEC 中做 UPDATE 能成功, 而在外面不能成功的原因就很明显啦
    放在外面的时候, T-SQL 执行前的计划根本就生成不了, 计划都生成不了, 那来执行啊, 所以照楼主的第1种方法, 报错是在生成执行计划的时候, 而不是在执行开始的时候
    而 UPDATE 放在 EXEC 中的时候, 执行计划生成肯定没有问题, 所以会顺利执行到 EXEC , 这时候去生成 EXEC 中语句的执行计划, 当然是没有问题的, 因为这时候已经有列了, 那接下来的一系列处理也当然没有问题了