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

时间:2009-04-20 19:48:59

标签: sql-server database-table change-management

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

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

如果我编写了所有数据库更改的脚本,是否有办法在表的末尾保留此顺序?

仅供参考,如果甚至做到这一点,我不会试图发动火焰战争。如果你想阅读一个快速退化的线程,这里有一个好的:

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

9 个答案:

答案 0 :(得分:26)

您必须创建一个临时表,该表反映原始表的架构,但具有所需的列顺序,然后将原始内容复制到temp。删除原始文件并重命名temp。

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

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

答案 1 :(得分:10)

进入SQL Server管理Studio,并“设计”现有表。在中间插入一列,右键单击空白区域并选择生成更改脚本...

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

enter image description here

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

enter image description here

答案 2 :(得分:6)

答案是肯定的,这在技术上是可行的,但你会头疼这样做,并且需要很长时间才能执行和设置。

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

这实际上是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

三:与之共存

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

答案 3 :(得分:3)

据我所知,没有已知的方法来改变列的顺序。在幕后,SQL Management Studio完成了Jose Basilio所说的话。如果你有一个大表,那么以这种方式更改列顺序是不切实际的。

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

肮脏而简单 将表导出到csv。
在所需位置插入新数据 放表。
创建具有所需列规格的新表 将列从csv加载到新表。

答案 6 :(得分:0)

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

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

选择临时表中的所有列,并使用所需的新列创建新表  删除旧表,从临时表中选择所有列,然后插入新的带有重新排序列。而且没有数据丢失

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)