Sql server T-SQL按特定顺序添加列

Sql server T-SQL按特定顺序添加列,sql-server,tsql,alter-table,Sql Server,Tsql,Alter Table,我对T-SQL有点陌生,来自MySQL的背景,我仍然在适应语法中的不同细微差别 我想在一个特定的列之后添加一个新的列。我发现AFTER是一个有效的关键字,但我认为它不适合这份工作 ALTER TABLE [dbo].[InvStockStatus] ADD [Abbreviation] [nvarchar](32) DEFAULT '' NOT NULL ; 这是我当前的查询,效果很好,只是它在表的末尾添加了字段,我更喜欢在[Name]之后添加它。我想用什么语法来表示这一点?在任何RDBMS中

我对T-SQL有点陌生,来自MySQL的背景,我仍然在适应语法中的不同细微差别

我想在一个特定的列之后添加一个新的列。我发现
AFTER
是一个有效的关键字,但我认为它不适合这份工作

ALTER TABLE [dbo].[InvStockStatus]
ADD [Abbreviation] [nvarchar](32) DEFAULT '' NOT NULL ;

这是我当前的查询,效果很好,只是它在表的末尾添加了字段,我更喜欢在
[Name]
之后添加它。我想用什么语法来表示这一点?

在任何RDBMS中,从严格的(功能性)意义上讲,列的顺序实际上都是不相关的——对于文档或人类来说,这只是一种“精确性”

SQL Server不支持以任何方式对列进行排序的任何t-SQL命令。因此,T-SQL中没有语法来实现这一点


改变这种情况的唯一方法是在SSMS中使用可视化表格设计器,它可以从头开始重新创建整个表格,当您在列的中间移动或插入列时,

我所看到的模式比较工具将创建一个具有所需排序的新表,然后将旧表中的数据复制到新表中(用一些重命名魔术使新的类似于旧表)。考虑到akward的这种方法,我认为没有一个t-SQL语句可以在特定位置添加一个新列。

技术上,或者我应该说,学术上,列添加到表中的顺序,或者它们在数据库内部存储模型中的存储顺序,不应该引起您的任何关注。您可以简单地在SQL查询的Select子句中列出列,以控制列或计算表达式在运行的任何查询的输出中的显示顺序。在内部,数据库可以自由地以其认为合适的任何方式存储实际数据,以优化存储,或帮助将数据元素与磁盘和/或内存边界对齐。

您应该始终只在末尾添加字段。您应该按照所需的顺序选择字段,但决不能重新构造现有表以在中间添加列。这可能会破坏一些事情(人们在没有指定列的情况下做了一些愚蠢的事情,比如选择*或插入,但人们不应该做这些事情,但他们确实做了)


重新创建表格可能是一个漫长而毫无收获的过程,并且在进行过程中可能会导致大量用户投诉和锁定。

你不能这样做

例如,如果你有一张这样的桌子

create table TestTable(id1 int,id3 int)
如果您想在id1和id3之间添加另一列id2,那么如果您使用设计器,SQL Server会在后台执行以下操作

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_TestTable
    (
    id1 int NULL,
    id2 int NULL,
    id3 int NULL
    )  ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_TestTable SET (LOCK_ESCALATION = TABLE)
GO
IF EXISTS(SELECT * FROM dbo.TestTable)
     EXEC('INSERT INTO dbo.Tmp_TestTable (id1, id3)
        SELECT id1, id3 FROM dbo.TestTable WITH (HOLDLOCK TABLOCKX)')
GO
DROP TABLE dbo.TestTable
GO
EXECUTE sp_rename N'dbo.Tmp_TestTable', N'TestTable', 'OBJECT' 
GO
COMMIT
正如您所看到的,如果您有大量的数据,这可能会有问题,为什么列的位置很重要?只用

select col1,col2,col3 from table

从函数数据库的角度来看,元组可以以任何顺序出现是正确的

然而,真空中不存在数据库。总有人想读取表模式(DBA、DEV),然后直接访问它,并维护或编写针对它的查询

在过去,我对表的列使用约定,例如使用

  • 首先是主键
  • 然后是外键
  • 然后是常用列
  • 然后是其他栏目
  • 最后审核相关栏目
  • 当扫描一张桌子时,这些工具会很有帮助。不幸的是,为了维持秩序,你似乎必须跳转,所以现在我不得不质疑是否值得拥有和维持这些惯例。我的新规则是把它加到最后

    如果您真的从可读性的角度担心顺序,那么您应该按照自己喜欢的顺序创建自己的“可读性”视图(可能在不同的模式中)。同一个表可以有多个视图(一个仅用于核心列,另一个包含通常不相关的内容)

    能够对SQL Server数据库关系图中的列重新排序(仅作为显示内容)会很好,但这是不可能的。

    这是一种安全的解决方法,无需使用临时表。在将列添加到末尾后,只需转到SQL Server Management Studio。单击表格,选择->设计(或修改)并将最后一列拖动到所需的位置

    这样,您就不必担心丢失数据和索引。唯一的另一种选择是重新创建表,如果您有大数据,这可能会有问题


    这个答案是为了帮助其他人,而不是被接受为答案

    自发布此问题以来,已经过了相当长的一段时间,但值得注意的是,虽然用于按特定顺序放置列的底层原始SQL代码没有改变生成脚本的过程,但如果您选择在Visual Studio中使用SQL Server数据工具来管理您的数据库,那么就需要处理生成脚本的过程。您部署到的数据库中的列将始终按照您在项目中指定的顺序排列。

    这主要是为了便于管理器中的可读性,不过您是对的。我不需要它井然有序,我只是好奇它是否可以做到。谢谢你清楚地说明了事情的真相。谢谢你迟来的回复。:)不幸的是,我需要一个脚本的方式来做这件事。同样从我记忆中可以看出,这有效地完成了在接受的答案中解释的临时表复制过程,就在幕后。谢谢你表现出兴趣:)哦,我不想让这个答案被接受。我只是想帮助那些可能遇到同样情况的人。被接受的答案是正确的。谢谢你的反馈!我认为这个答案虽然值得赞赏,但可能会误导人!关于这一点,VisualStudio的模式比较就是这样做的。