如何更改列順序?
如何更改 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