Sql-Server

如何更改列順序?

  • March 29, 2021

如何更改 sql server 2008 R2 中的列順序?

例如:我的餐桌順序是 Eid—–Ename—–Esalary

知道我想要這種格式,例如 Eid—Salary—-Ename

謝謝。

您不應該太在意現有表的物理列順序,因為您可能希望引入更改它所涉及的風險。這可能是一個問題的唯一情況是,如果您正在使用SELECT *並希望以某種方式排列輸出 -您不應該這樣做,您應該明確列出列名(然後您可以放置​​列以您想要的任何順序,或創建一個執行此操作的視圖)。

就像其他人所說的那樣,您可以刪除並重新創建表格,並按照您的首選順序排列列。但是,如果您的表很大,這將非常具有破壞性(阻塞、I/O),因為系統上的所有其他使用者都必須等待它完成。如果您想確切了解 Management Studio 的功能,請創建此表:

CREATE TABLE dbo.foo(b INT, a INT, r INT);

INSERT dbo.foo(b,a,r) VALUES(1,2,3),(4,5,6);

現在,在對象資源管理器中,右鍵點擊表並選擇設計。選擇要重新排序的列名稱左側的框。將該列拖到表中的另一個位置。我移到a上面b是因為我是強迫症並且想要按字母順序排列的列:

在此處輸入圖像描述

然後我點擊“生成更改腳本”按鈕,這是它創建的怪物(請注意,這是一個沒有鍵、約束、觸發器等的堆 - 這種重新創建可能會變得非常複雜)。

/*
  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_foo
   (
   a int NULL,
   b int NULL,
   r int NULL
   )  ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_foo SET (LOCK_ESCALATION = TABLE)
GO
IF EXISTS(SELECT * FROM dbo.foo)
    EXEC('INSERT INTO dbo.Tmp_foo (a, b, r)
       SELECT a, b, r FROM dbo.foo WITH (HOLDLOCK TABLOCKX)')
GO
DROP TABLE dbo.foo
GO
EXECUTE sp_rename N'dbo.Tmp_foo', N'foo', 'OBJECT' 
GO
COMMIT

為了好玩,讓我們創建一些更複雜的東西:

CREATE TABLE dbo.flarb
(
 a INT PRIMARY KEY, 
 b INT NOT NULL CHECK (b>1), 
 c ROWVERSION, 
 d DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
 e UNIQUEIDENTIFIER NOT NULL DEFAULT NEWSEQUENTIALID()
);

CREATE TABLE dbo.blarf
(
 a INT NOT NULL FOREIGN KEY REFERENCES dbo.flarb(a)
);
GO

CREATE TRIGGER dbo.flarb_tr
ON dbo.flarb
FOR UPDATE
AS
 SELECT 1;
GO

CREATE VIEW dbo.flarb_v
WITH SCHEMABINDING
AS
 SELECT a FROM dbo.flarb;

現在我們嘗試同樣的事情:

‘flarb’ 表

  • 驗證列 ’e’ 的預設值時出錯。

  • 警告:以下架構綁定對象將被修改:

  • 查看“dbo.flarb_v”:架構綁定將被刪除。

哎呀。值得慶幸的是,我們仍然可以繼續查看腳本的外觀:

/* 
 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 VIEW dbo.flarb_v

AS
 SELECT a FROM dbo.flarb;GO
ALTER TABLE dbo.flarb
   DROP CONSTRAINT DF__flarb__d__1B7E091A
GO
ALTER TABLE dbo.flarb
   DROP CONSTRAINT DF__flarb__e__1C722D53
GO
CREATE TABLE dbo.Tmp_flarb
   (
   a int NOT NULL,
   b int NOT NULL,
   d datetime NOT NULL,
   c timestamp NOT NULL,
   e uniqueidentifier NOT NULL
   )  ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_flarb SET (LOCK_ESCALATION = TABLE)
GO
ALTER TABLE dbo.Tmp_flarb ADD CONSTRAINT
   DF__flarb__d__1B7E091A DEFAULT (getdate()) FOR d
GO
ALTER TABLE dbo.Tmp_flarb ADD CONSTRAINT
   DF__flarb__e__1C722D53 DEFAULT (newsequentialid()) FOR e
GO
IF EXISTS(SELECT * FROM dbo.flarb)
    EXEC('INSERT INTO dbo.Tmp_flarb (a, b, d, e)
       SELECT a, b, d, e FROM dbo.flarb WITH (HOLDLOCK TABLOCKX)')
GO
ALTER TABLE dbo.blarf
   DROP CONSTRAINT FK__blarf__a__1E5A75C5
GO
DROP TABLE dbo.flarb
GO
EXECUTE sp_rename N'dbo.Tmp_flarb', N'flarb', 'OBJECT' 
GO
ALTER TABLE dbo.flarb ADD CONSTRAINT
   PK__flarb__3BD0198EF8B8CFAF PRIMARY KEY CLUSTERED 
   (
   a
   ) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
       ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

GO
ALTER TABLE dbo.flarb ADD CONSTRAINT
   CK__flarb__b__1A89E4E1 CHECK (([b]>(1)))
GO
CREATE TRIGGER dbo.flarb_tr
ON dbo.flarb
FOR UPDATE
AS
 SELECT 1;
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.blarf ADD CONSTRAINT
   FK__blarf__a__1E5A75C5 FOREIGN KEY
   (
   a
   ) REFERENCES dbo.flarb
   (
   a
   ) ON UPDATE  NO ACTION 
    ON DELETE  NO ACTION 

GO
ALTER TABLE dbo.blarf SET (LOCK_ESCALATION = TABLE)
GO
COMMIT

是的,這看起來真的像我想在生產中執行的東西,即使桌子很小。

另一種選擇是完全手動執行此操作。假設你有這張桌子:

CREATE TABLE dbo.Employee
(
 EmployeeID INT,
 Name NVARCHAR(255),
 Salary INT
);
INSERT ...

從理論上講,除了鍵、約束、觸發器和模式綁定對象引起的複雜性之外,您可以“更改”列的順序 - 對於要移動的列左側的每一列 - 創建一個新列,移動數據、刪除舊列並重命名新列。這是有效的,因為新列總是添加到表的“末尾”。忽略錯誤處理和任何其他並發症:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
ALTER TABLE dbo.Employee ADD Nametmp NVARCHAR(255);
UPDATE dbo.Employee SET Nametmp = Name;
ALTER TABLE dbo.Employee DROP COLUMN Name;
EXEC sp_rename N'dbo.Employee.Nametmp', N'Name', N'COLUMN';
COMMIT TRANSACTION;

這當然有可能像 Management Studio 的方法一樣具有破壞性(或更糟),即只換出整個表,如果您想移動多個列,則會變得非常複雜。

現在,您真的需要更改列順序嗎?

如果不刪除並重新創建表,則無法更改 SSMS 中的物理列順序。

為什麼不只是更改查詢以以不同的順序選擇列?

從:

SELECT Eid, Ename, Esalary FROM Table

到:

SELECT Eid, Esalary, Ename FROM Table

引用自:https://dba.stackexchange.com/questions/61978