在工作中的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的空表。
两者之间是否有任何实际或理论上的差异?他们可能会有什么影响?
答案 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包中的构造。我在部署脚本中创建表,如果我之后使用的某个表在以后丢失,我希望包失败,因为之后发生了一些严重错误,我想在我尝试将数据放到任何地方之前调查一下。