这两个T-SQL语句有什么区别?

时间:2011-07-26 18:30:48

标签: tsql

在工作中的SSIS包中,有一些SQL任务可以创建用于保存导入数据的登台表。所有陈述都采用以下形式:

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'dbo.tbNewTable') AND type in (N'U'))
BEGIN
    TRUNCATE TABLE dbo.tbNewTable
END
ELSE
BEGIN
    CREATE TABLE dbo.tbNewTable (
        ColumnA VARCHAR(10) NULL,
        ColumnB VARCHAR(10) NULL,
        ColumnC INT NULL
    ) ON PRIMARY
END

在Itzik Ben-Gan的T-SQL Fundamentals中,我看到了创建表格的不同形式的陈述:

IF OBJECT_ID('dbo.tbNewTable', 'U') IS NOT NULL
BEGIN
    DROP TABLE dbo.tbNewTable
END

CREATE TABLE dbo.tbNewTable (
    ColumnA VARCHAR(10) NULL,
    ColumnB VARCHAR(10) NULL,
    ColumnC INT NULL
) ON PRIMARY

这些似乎都做同样的事情。执行后,dbo架构中会有一个名为tbNewTable的空表。

两者之间是否有任何实际或理论上的差异?他们可能会有什么影响?

4 个答案:

答案 0 :(得分:6)

第一个假定如果表存在,则它与它创建的列具有相同的列。第二个没有做出这个假设。因此,如果具有该名称的表恰好存在并且具有不同的列集,则两者将具有非常不同的结果。

答案 1 :(得分:2)

第一个实际上不会删除表 - 它只是TRUNCATES所述表中的所有数据。因此,为什么CREATE受到保护。

因此,带有DROP的表单将允许后续CREATE更改架构(创建新表时),即使先前存在tbNewTable

因为DROP / CREATE改变了数据库模式,所以在所有情况下都不允许这样做。例如,使用SCHEMABINDING创建的视图将阻止删除表。 (对于更普遍的FK关系,这也适用,如果存在的话。)

  
    

...指定SCHEMABINDING时,不能以影响视图定义的方式修改基表。

  

TRUNCATE 应该在其中一种“不关心”的方式中略微加快:对于一方而言,不应该考虑性能。

还有许可差异。 TRUNCATE只需要ALTER权限。

  
    

所需的最小权限是table_name上的ALTER。 TRUNCATE TABLE权限默认授予表所有者...

  

快乐的编码。

答案 2 :(得分:1)

这些非常不同......

第一个对sys.objects系统表进行相等性检查,并查看是否存在匹配的表名。如果是这样,它会截断表格。基本上删除所有行但保持表结构本身 - 即实际表永远不会丢弃。

在第二步中,使用OBJECT_ID()方法隐式地进行检查以确保表存在。如果是这样,表格将完全删除 - 行和结构。

如果你在表上有一个主键和外键约束,你肯定会有问题完全丢弃它...如果你有其他表链接到表,你试图'截断'你将在那里也有问题,除非你打开了级联删除。

答案 3 :(得分:1)

我倾向于不喜欢SSIS包中的构造。我在部署脚本中创建表,如果我之后使用的某个表在以后丢失,我希望包失败,因为之后发生了一些严重错误,我想在我尝试将数据放到任何地方之前调查一下。