重新创建具有不同列的临时表失败。

15 浏览
0 Comments

重新创建具有不同列的临时表失败。

在编写脚本时,您经常需要更改临时表中的列。尽管受到drop-table-if-exists语句的保护,但仍会失败,因为列没有更改。为什么呢?

以下是一个示例,大致说明了我的意思,为什么这个脚本不起作用?在重新创建#t时失败,提示“数据库中已经存在名为“#t”的对象。”

感觉SQL服务器行骗,只清空表而不是删除它。

if exists (select * from tempdb..sysobjects where id=object_id('tempdb..#t'))
    drop table #t
create table #t (
    a int
)
if exists (select * from tempdb..sysobjects where id=object_id('tempdb..#t'))
    drop table #t
create table #t (
    a int
    ,b int
)

admin 更改状态以发布 2023年5月23日
0
0 Comments

在同一批处理中尝试创建相同的对象。SQL Server检测到此情况后,会生成编译错误(甚至在SQL实际运行之前就发生了)。

如果必须在同一批处理中执行此操作,可以使用sp_executesql将语句在单独的批处理中运行来避免错误。请注意,此处不使用以#为前缀的表,因为#表只会在sp_executesql的批处理中持续存在。然而,考虑到OP在此处展示的内容,我猜想我们所看到的可能过于简单了:

USE Sandbox;
GO
IF EXISTS (SELECT *
           FROM sys.sysobjects
           WHERE id = OBJECT_ID('MyTable'))
    DROP TABLE MyTable;
EXEC sp_executesql N'CREATE TABLE MyTable (a int);';
IF EXISTS (SELECT *
           FROM sys.sysobjects
           WHERE id = OBJECT_ID('MyTable'))
    DROP TABLE MyTable;
EXEC sp_executesql N'CREATE TABLE MyTable (a int, b int);';
GO
DROP TABLE MyTable;

0
0 Comments

这是一个解析错误。即使你在执行之前解析查询(Ctrl + F5),你仍会遇到此错误。这是因为在同一批处理中有两个同名的创建语句,而在名称解析期间表已经存在,第二个创建语句因此失败。

您需要两个会话或在语句之间放置一个GO命令。这是一篇类似的博客文章。有关SQL Server临时表的有趣发现

0