一个奇怪的临时表问题???
在查询分析器分两次执行下面的语句:
第一次:(第一次当然出错了,因为临时表根本没有c字段)
if Object_id( 'tempdb.dbo.#TempTable1 ') is not null
drop table #TempTable1
select 1 as a,2 as b into #TempTable1
SELECT a,b,c from #TempTable1
第二次:
if Object_id( 'tempdb.dbo.#TempTable1 ') is not null
drop table #TempTable1
select 1 as a,2 as b,3 as c into #TempTable1
SELECT a,b,c from #TempTable1
奇怪的是这次还是同样的错误,说c字段不存在???为什么啊???????
如果把SELECT a,b,c from #TempTable1
改成:SELECT * from #TempTable1
那么就可以正常执行
我不明白的是我明明把临时表删除了,为什么他还是记住我第一次错误的表结构呢???
------解决方案--------------------第二次:
if Object_id( 'tempdb.dbo.#TempTable1 ') is not null
drop table #TempTable1
select 1 as a,2 as b,3 as c into #TempTable1
SELECT a,b,c from #TempTable1
直接使用高速缓存中的查询执行计划,当然报错。
------解决方案--------------------查询是首先生成查询计划,然后再查询 步骤: 生成查询执行计划---> 执行查询
因为你第一次查询时已经生成了查询计划,第一次生成的查询执行计划里并没有字段C
当你第二次查询时,(SELECT a,b,c from #TempTable1)直接调用了高速缓存中的查询执行计划,并没有重新生成查询执行计划,这时当然会报错,C字段不存在
查询执行计划都没有,何来查询!!!
------解决方案--------------------奇怪真奇怪!
因为Sql语句都是批处理的,这个应该都知道的了,加了GO就代表批处理结束,而没有加那么就是所有的语句当成一个批处理
那么我们来分析一下
第二次:
if Object_id( 'tempdb.dbo.#TempTable1 ') is not null
drop table #TempTable1
select 1 as a,2 as b,3 as c into #TempTable1
SELECT a,b,c from #TempTable1
这三条语句其实是一起执行的,那么 drop table #TempTable1 以后其实还没有提交到,只是在一个隐式的事务中,接着 select into 也能通过,因为它认为这以及是一个新表了,虽然名字一样但是ID是不一样的,
注意: ID 是不一样的
最后一个 SELECT 在执行前有一个编译的过程,其实每条语句执行前都会编译的时候,那么它发现其实上一个 #TempTable1 还在因为还没提交,所以编译这句话的时候就会报错
注意:是执行前编译报的错,并不是执行报的错