代码之家  ›  专栏  ›  技术社区  ›  Russell Steen

SQL Server列显示顺序

  •  0
  • Russell Steen  · 技术社区  · 15 年前

    通过脚本创建表时,它似乎只是按创建顺序列出列。这是一个小麻烦,但我喜欢某种方法来对付这种疯狂。当我稍后添加列时 ALTER TABLE ,在企业管理器等交互式工具中查看表时,如何使其显示在特定位置?

    前任:

    Table Foo
    ---------
    FooID  
    BarID  
    Name  
    Address  
    Worth  
    

    我想

    ALTER TABLE Foo  
    ADD BazID INT NULL 
    

    并拥有 BazID 列出之间 BarID Name 当我使用管理工作室时。

    2 回复  |  直到 15 年前
        1
  •  3
  •   marc_s    15 年前

    你不能这么做——一个SQL Server表真的不知道列的顺序——元组代数中没有顺序,这是关系数据库系统的基础。

    SQL Server Management Studio向您展示的只是它自己的显示“优化”——您可以在那里更改它,但是标准的SQL数据定义语言(DDL)语句没有“列顺序”的概念——您不能更改表以将列移动到其他位置。

    如果在SSMS中更改列的显示顺序,则在后台执行的操作是将旧表重命名为临时名称,使用指定顺序的列创建新表,然后围绕数据进行复制。这就是为什么修改一个大表上的列顺序几乎要花上一辈子的时间——这不仅仅是一个简单的要执行的DDL语句——这是一项重大的任务。

    马克

        2
  •  0
  •   gjutras    15 年前

    SQL Server Management Studio和其他大名鼎鼎的工具(如Redgate)的做法是创建新的临时表,复制信息,然后删除旧表(先删除约束和唯一索引),将临时表重命名为旧表名,然后重新添加任何约束和索引。你真的不能重新订购已经存在的东西。

    下面是一个例子:

    -- here's a sales table
    CREATE TABLE [dbo].[Sales](
        [SalesId] [int] IDENTITY(1,1) NOT NULL,
        [Month] [int] NOT NULL,
        [Year] [int] NOT NULL,
        [InvoiceAmount] [decimal](15, 2) NOT NULL,
        [SalesRepId] [int] NOT NULL,
        [BranchId] [int] NOT NULL,
     CONSTRAINT [PK_Sales] PRIMARY KEY CLUSTERED 
    (
        [SalesId] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    
    
    --Here's the sales table adding a column called description between SalesId & Month
    
    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_Sales
        (
        SalesId int NOT NULL IDENTITY (1, 1),
        Description varchar(MAX) NULL,
        Month int NOT NULL,
        Year int NOT NULL,
        InvoiceAmount decimal(15, 2) NOT NULL,
        SalesRepId int NOT NULL,
        BranchId int NOT NULL
        )  ON [PRIMARY]
         TEXTIMAGE_ON [PRIMARY]
    GO
    SET IDENTITY_INSERT dbo.Tmp_Sales ON
    GO
    IF EXISTS(SELECT * FROM dbo.Sales)
         EXEC('INSERT INTO dbo.Tmp_Sales (SalesId, Month, Year, InvoiceAmount, SalesRepId, BranchId)
            SELECT SalesId, Month, Year, InvoiceAmount, SalesRepId, BranchId FROM dbo.Sales WITH (HOLDLOCK TABLOCKX)')
    GO
    SET IDENTITY_INSERT dbo.Tmp_Sales OFF
    GO
    DROP TABLE dbo.Sales
    GO
    EXECUTE sp_rename N'dbo.Tmp_Sales', N'Sales', 'OBJECT' 
    GO
    ALTER TABLE dbo.Sales ADD CONSTRAINT
        PK_Sales PRIMARY KEY CLUSTERED 
        (
        SalesId
        ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    
    GO
    COMMIT