将列添加到现有 SQL Server 表 - 含义
Posted
技术标签:
【中文标题】将列添加到现有 SQL Server 表 - 含义【英文标题】:Add column to existing SQL Server table - Implications 【发布时间】:2013-08-12 13:40:54 【问题描述】:我在 SQL Server 中有一个现有表,其中包含现有条目(实际上超过 100 万个)。
前端应用程序会定期更新、插入和选择此表。我想要/需要添加一个 datetime
列,例如M_DateModified
可以这样更新:
UPDATE Table SET M_DateModified = GETDATE()
每当在前端按下按钮并调用存储过程时。此列将根据要求添加到现有报告中。
我的问题,答案是这样的。作为我们应用程序的核心表之一,ALTERING
表并添加额外的列会破坏其他现有查询吗?显然,如果不为所有列指定所有值,则无法插入表中,因此任何现有的 INSERT
查询都会中断(这是一个大问题)。
对于有关此问题的最佳解决方案的任何帮助将不胜感激。
【问题讨论】:
它会破坏设计不良的查询——比如SELECT * FROM ....
或INSERT
查询没有明确指定要插入的列列表进入.....
您说“显然,如果不指定所有列的所有值,您就无法插入到表中”。这不是真的。
糟糕,@RBarryYoung 对不起。我的意思是通过简单的插入,您会收到消息“列名或提供的值的数量与表定义不匹配”。例如,如果您只提供 5 个值,而表格需要 7 个?对不起,我的菜鸟,我是新来的:)
啊,是的,默认INSERT
。我已经忘记了它,但是因为它相当于使用“*”作为INSERT
,所以你不应该那样做(现在你知道为什么了)。明确指定您的列。
谢谢,以后会做的:)
【参考方案1】:
首先,正如 marc_s 所说,它应该只影响 SELECT *
查询,甚至不一定会影响所有查询。
其次,您只需要在INSERT
上指定所有非Null 字段,因此如果您将其设为NULL,您就不必担心这一点。此外,对于Created_Date
类型的列,通常会添加=GetDate()
的DEFAULT
设置,如果未指定,它将为您填写。
第三,如果您仍然担心影响现有代码库,请执行以下操作:
-
将您的表格重命名为“physicalTable”。
创建一个与以前的表同名的视图,执行
SELECT .. FROM physicalTable
,以相同的顺序显式列出列,但不要在其中包含 M_DateModified
字段。
保持代码不变,现在引用视图,而不是直接访问表。
现在您的代码可以安全地与表交互而无需进行任何更改(SQL DML 代码无法区分 Table 和这样的可写视图)。
最后,这种“ModifiedDate”列是一种常见的需求并且最常被处理,首先将其设为 NULL,然后添加一个自动设置它的插入和更新触发器:
UPDATE t
SET M_DateModified = GetDate()
FROM (SELECT * FROM physicalTable y JOIN inserted i ON y.PkId = i.PkId) As t
这样应用程序就不必自己维护字段。作为额外的好处,应用程序也不能错误地或错误地设置它(这是 SQL 中触发器的常见且可接受的用法)。
【讨论】:
【参考方案2】:如果新列不是强制性的,您无需担心。除非你有一些笨蛋用“*”而不是列列表来编写选择语句。
【讨论】:
很可能存在这样的查询。该应用程序非常庞大。 或其他编写INSERT INTO dbo.Table VALUES(.....)
且未指定要使用的列列表的笨蛋 - 如果您添加新列 - 这些插入将全部中断 - 强制与否....【参考方案3】:
好吧,只要您的 SELECT 不是 *,那应该没问题。对于 INSERT,如果你给字段一个默认的 GETDATE() 并允许 NULL,你可以排除它,它仍然会被填充。
【讨论】:
【参考方案4】:取决于您的其他查询的设置方式。如果他们是SELECT [Item1], [Item2], ect
.... 那么您将不会遇到任何问题。如果是SELECT * FROM
,那么您可能会遇到一些意想不到的结果。
请记住您希望如何设置它,您要么必须将其设置为可空的,这可能会让您适应未来,要么设置默认日期,这可能会为您提供不正确的数据以进行报告、检索, 查询等..
【讨论】:
这当然也是需要考虑的事情。考虑到这将用于报告。谢谢。以上是关于将列添加到现有 SQL Server 表 - 含义的主要内容,如果未能解决你的问题,请参考以下文章