将新表列添加到 Microsoft SQL Server 中的特定序号位置

Posted

技术标签:

【中文标题】将新表列添加到 Microsoft SQL Server 中的特定序号位置【英文标题】:Add a new table column to specific ordinal position in Microsoft SQL Server 【发布时间】:2010-10-20 16:02:11 【问题描述】:

是否可以在 Microsoft SQL Server 的特定序号位置向表中添加列?

例如,我们的表总是在每个表定义的“末尾”都有 CreatedOn、CreatedBy、LastModifiedOn、LastModifiedBy 列?我希望新列显示在这些列上方的 SSMS 中。

如果我正在编写所有数据库更改的脚本,有没有办法在表的末尾保留这个顺序?

仅供参考,我并不想就是否应该这样做发起一场激烈的战争。如果您想了解一个快速退化为该线程的线程,这里有一个很好的:

http://www.developersdex.com/sql/message.asp?p=581&r=5014513

【问题讨论】:

或者这就是为什么我应该在每个表的顶部创建视图的原因? 相关:***.com/q/1605144/12484 想知道表定义上的“OrderBy”列的可行性是什么。这种删除和重新创建表的废话,因为需要在完全合乎逻辑的位置插入新字段,这对任何人都没有任何好处。 【参考方案1】:

您必须创建一个临时表,该表镜像原始表的架构但具有您想要的列顺序,然后将原始表的内容复制到临时表。删除原来的并重命名temp。

这就是 SQL Management Studio 在幕后所做的事情。

使用架构同步工具,您可以自动生成这些脚本。

【讨论】:

【参考方案2】:

进入 SQL Server 管理工作室,并“设计”一个现有的表。在中间插入一列,在空白处右击并选择Generate Change Script...

现在看看它创建的脚本。它基本上会创建一个具有正确列顺序的临时表,从原始表中插入数据,删除原始表,然后重命名临时表。这可能是您需要做的。

您可能还需要取消选中此选项以允许创建更改脚本

【讨论】:

【参考方案3】:

答案是肯定的,技术上是可行的,但是这样做会让人头疼,而且执行和设置需要很长时间。

一:创建/复制/删除/重命名

这实际上是 SQL Server 在图形界面中所做的事情:这是一个脚本示例,当您在表的开头添加新列后单击“保存”按钮时,它正在生成和执行脚本。

/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_SomeTable
    (
    MyNewColumn int NOT NULL,
    OriginalIntColumn int NULL,
    OriginalVarcharColumn varchar(100) NULL
    )  ON [PRIMARY]
     TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_SomeTable SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_SomeTable ON
GO
IF EXISTS(SELECT * FROM dbo.SomeTable)
     EXEC('INSERT INTO dbo.Tmp_SomeTable (OriginalIntColumn, OriginalVarcharColumn FROM dbo.SomeTable WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_SomeTable OFF
GO
DROP TABLE dbo.SomeTable
GO
EXECUTE sp_rename N'dbo.Tmp_SomeTable', N'SomeTable', 'OBJECT' 
GO

GO
COMMIT

二:添加列/更新/删除列/重命名

此方法基本上涉及创建要添加到新列“右侧”的任何现有列的副本,将数据传输到新列,然后删除原始列并重命名新列。这将对您拥有的任何索引或约束造成严重破坏,因为您必须重新指向它们。这在技术上是可行的,但在开发和执行方面同样耗时。

CREATE TABLE MyTest (a int, b int, d int, e int)

INSERT INTO MyTest (a,b,d,e) VALUES(1,2,4,5)

SELECT * FROM MyTest -- your current table

ALTER TABLE MyTest ADD c int -- add a new column
ALTER TABLE MyTest ADD d_new int -- create copies of the existing columns you want to move
ALTER TABLE MyTest ADD e_new int

UPDATE MyTest SET d_new = d, e_new = e -- transfer data to the new columns

ALTER TABLE MyTest DROP COLUMN d -- remove the originals
ALTER TABLE MyTest DROP COLUMN e

EXEC SP_RENAME 'MyTest.d_new', 'd'; -- rename the new columns
EXEC SP_RENAME 'MyTest.e_new', 'e';

SELECT * FROM MyTest 

DROP TABLE MyTest -- clean up the sample

三:顺其自然

这极大地冒犯了我的秩序感......但有时,它只是不值得重新洗牌。

【讨论】:

【参考方案4】:

据我所知,没有已知的方法可以更改列的顺序。在幕后 SQL Management Studio 执行 Jose Basilio 所说的操作。如果你有一张大桌子,那么像这样改变列顺序是不切实际的。

您可以使用“视图”。使用 SQL 视图,您可以使用任何您喜欢的顺序,而不会受到表列更改的影响。

【讨论】:

【参考方案5】:

TFS 2013 会自动为您执行此操作

将新列添加到您的表中,然后将您的更改提交到 TFS。从那里您可以在 Visual Studio 中打开表的 sql 文件并手动移动 T-SQL CREATE 脚本中的列顺序。然后,您可以使用工具 > SQL Server > 新架构比较下的 VS 架构比较工具来更新目标数据库。选择您的数据库项目,将您的更改作为源,将要更新的数据库作为目标。比较,选择表的脚本,然后更新。 VS 会自动删除和添加。您的所有数据和索引都是安全的。

【讨论】:

【参考方案6】:

我认为很简单的是添加列 ALTER TABLE table1 ADD .. 然后从 select 中创建一个像 tmp_table1 这样的 tmp 表 SELECT col1,col2,col5,col3,col4 into tmp_table1 from table1; 然后删除table1并将tmp_table1重命名为table1,就是这样。我希望它会帮助某人

【讨论】:

【参考方案7】:

将所有列选择到临时表中,并使用所需的新列创建一个新表。然后删除旧表,从临时表中选择所有列,并将它们插入到具有重新排序列的新表中。没有数据丢失。

SELECT * FROM TEMP
SELECT * FROM originaltbl
SELECT * FROM #Stagintbl

DECLARE @ColumnName nvarchar(max);
SET @ColumnName=(SELECT
    DISTINCT STUFF((
        SELECT ',' + a.COLUMN_NAME
        FROM (
            SELECT Column_name 
            FROM INFORMATION_SCHEMA.COLUMNS 
            WHERE TABLE_NAME='originaltbl') a
        for xml path('')
    ),1,1,'') AS ColumnName)

DECLARE @Sqlquery nvarchar(max)
SET @Sqlquery = 'SELECT ' + @ColumnName + ' FROM #Stagintbl' + '';
INSERT INTO originaltbl
EXECUTE(@Sqlquery)

【讨论】:

【参考方案8】:

我正在使用 SSMS 18。我以简单的方式做到了

开放式表设计 通过拖动来定位所需的列 根据 KM 的回答(线程中的第二个) - 取消选中允许创建更改脚本的选项,请参阅上图。 保存更改。 完成。立即检查您的餐桌。

【讨论】:

【参考方案9】:

又脏又简单。 将表格导出为 csv。 在所需位置插入新数据。 删除表。 创建具有所需列规范的新表。 将列从 csv 加载到新表。

【讨论】:

【参考方案10】:

我不确定该线程是否仍处于活动状态。我对 mysql 数据库进行了相同的查询。右键单击表格并选择“ALTER”自动生成以下代码。 sakila db 提供的样本,它有效。只需找出要放置新列的列并使用“AFTER”关键字

ALTER TABLE `sakila`.`actor` 
CHANGE COLUMN `middle_name` `middle_name` VARCHAR(50) NULL DEFAULT NULL AFTER `first_name`; 

【讨论】:

您的答案是特定于 MySQL。这将在 SQL Server 中工作,这是 OP 专门针对的。像这样混合 MySQL 答案只会让那些在这里寻找 SQL Server 答案的人感到困惑。

以上是关于将新表列添加到 Microsoft SQL Server 中的特定序号位置的主要内容,如果未能解决你的问题,请参考以下文章

将新成绩添加到数据库时,Microsoft sql 会触发自动更新 GPA

如何将新表添加到 Debezium MySQL 连接器?

将数据框从 jupyter notebook 写入雪花而不定义表列类型

在 EF 6 和 MVC 5 中使用 Code First 方法将新表添加到现有数据库

我可以使用 SQL 将存储为 CSV(逗号分隔值)的表列的内容拆分为新表中的单独行吗?

在运行时将新表重新加载/替换到 WPF DataGrid 中