【问题标题】:How to add columns between fields or change existing ones in SQL?如何在字段之间添加列或更改 SQL 中的现有列?
【发布时间】:2011-08-16 23:38:46
【问题描述】:

是否有人知道如何在 SQL 2005/2008 中的特定字段之间或特定字段之后向表中添加列?还有,如何更改现有列的位置?

例子:

AHADRS, AHCITY, AHZIPC

我想在AHCITYAHZIPC之间添加状态

这是我迄今为止尝试过的,但它们不起作用

ALTER TABLE AHASNF00 ADD AHZIPC varchar(max) AFTER AHCITY
ALTER TABLE AHASNF00 ADD AHZIPC varchar(max) FIRST AHZIPC

任何帮助将不胜感激,谢谢。

【问题讨论】:

    标签: asp.net sql sql-server-2008


    【解决方案1】:

    SqlServer 在存储列时没有“位置”的概念。

    如果您需要不同的列顺序,请更改 select 语句中的位置。

    【讨论】:

    • 同意。我不知道有任何专门依赖于字段顺序的 RDBMS - 这是模型的基本原则之一,即列是专门无序
    【解决方案2】:

    通常可以通过创建一个临时表来解决这个问题,该表具有一个临时名称,其中的列按您希望的顺序排列。然后将数据从一个当前表复制到另一个,之后旧表被销毁,临时表重命名为原始表。

    当然,这一切都必须与删除和读取主键和外键引用相协调。

    例如,当我尝试在名为“Term”的真实示例表的其他列的中间添加一列时,SQL Server Management Studio 生成的更改脚本。

    /* 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
    ALTER TABLE dbo.Term
        DROP CONSTRAINT FK_Term_TermUnit
    GO
    ALTER TABLE dbo.TermUnit SET (LOCK_ESCALATION = TABLE)
    GO
    COMMIT
    BEGIN TRANSACTION
    GO
    CREATE TABLE dbo.Tmp_Term
        (
        Id int NOT NULL IDENTITY (1, 1),
        Label varchar(50) NOT NULL,
        TermUnitId int NOT NULL,
        NewColumnInTheMiddle bit NULL,
        UnitCount int NOT NULL
        )  ON [PRIMARY]
    GO
    ALTER TABLE dbo.Tmp_Term SET (LOCK_ESCALATION = TABLE)
    GO
    SET IDENTITY_INSERT dbo.Tmp_Term ON
    GO
    IF EXISTS(SELECT * FROM dbo.Term)
         EXEC('INSERT INTO dbo.Tmp_Term (Id, Label, TermUnitId, UnitCount)
            SELECT Id, Label, TermUnitId, UnitCount FROM dbo.Term WITH (HOLDLOCK TABLOCKX)')
    GO
    SET IDENTITY_INSERT dbo.Tmp_Term OFF
    GO
    ALTER TABLE dbo.TreasuryIndexRate
        DROP CONSTRAINT FK_TreasuryIndexRate_Term
    GO
    ALTER TABLE dbo.TreasuryIndexField
        DROP CONSTRAINT FK_TreasuryIndexField_Term
    GO
    DROP TABLE dbo.Term
    GO
    EXECUTE sp_rename N'dbo.Tmp_Term', N'Term', 'OBJECT' 
    GO
    ALTER TABLE dbo.Term ADD CONSTRAINT
        PK_Term PRIMARY KEY CLUSTERED 
        (
        Id
        ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    
    GO
    ALTER TABLE dbo.Term ADD CONSTRAINT
        FK_Term_TermUnit FOREIGN KEY
        (
        TermUnitId
        ) REFERENCES dbo.TermUnit
        (
        Id
        ) ON UPDATE  NO ACTION 
         ON DELETE  NO ACTION 
    
    GO
    COMMIT
    BEGIN TRANSACTION
    GO
    ALTER TABLE dbo.TreasuryIndexField ADD CONSTRAINT
        FK_TreasuryIndexField_Term FOREIGN KEY
        (
        TermId
        ) REFERENCES dbo.Term
        (
        Id
        ) ON UPDATE  NO ACTION 
         ON DELETE  NO ACTION 
    
    GO
    ALTER TABLE dbo.TreasuryIndexField SET (LOCK_ESCALATION = TABLE)
    GO
    COMMIT
    BEGIN TRANSACTION
    GO
    ALTER TABLE dbo.TreasuryIndexRate ADD CONSTRAINT
        FK_TreasuryIndexRate_Term FOREIGN KEY
        (
        TermId
        ) REFERENCES dbo.Term
        (
        Id
        ) ON UPDATE  NO ACTION 
         ON DELETE  NO ACTION 
    
    GO
    ALTER TABLE dbo.TreasuryIndexRate SET (LOCK_ESCALATION = TABLE)
    GO
    COMMIT
    

    【讨论】:

    • 我正在为客户创建仪表板应用程序,而 db 表超出逻辑位置
    • 取决于您是想以编程方式执行此操作,还是利用 SSMS 的功能为您完成工作。但正如其他人所说,SQL Server 不在乎您的列的顺序——如果您希望它们以不同的顺序出现,请将您的 SQL 包装在一个视图中,或者只是更改 SELECT 语句中列的顺序。
    【解决方案3】:

    不幸的是,我不相信有一种简单的方法可以使用 T-SQL 完成此任务。您必须按照您希望列的顺序创建一个新表,将旧表中的数据插入新表,删除旧表,重命名新表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-24
      • 2011-06-11
      • 1970-01-01
      • 2011-03-23
      • 1970-01-01
      • 2017-12-25
      • 1970-01-01
      • 2011-07-16
      相关资源
      最近更新 更多