6 database-design sql-server sql-server-2008-r2 alter-table ddl
如何更改 sql server 2008 R2 中的列顺序?
例如:我的餐桌顺序是开斋节------Ename-----Esalary
知道我想要这种格式,例如 Eid---Salary----Ename
谢谢。
Aar*_*and 10
您不应该足够关心现有表的物理列顺序,因为您可能希望在更改它时带来风险。这可能是一个问题的唯一情况是,如果您正在使用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);
Run Code Online (Sandbox Code Playgroud)
现在,在对象资源管理器中,右键单击表并选择设计。选择要重新排序的列名称左侧的框。将该列拖到表中的另一个位置。我移到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
Run Code Online (Sandbox Code Playgroud)
为了好玩,让我们创建一些更复杂的东西:
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;
Run Code Online (Sandbox Code Playgroud)
现在我们尝试同样的事情:
'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
Run Code Online (Sandbox Code Playgroud)
是的,这看起来真的很像我想在生产中运行的东西,即使表很小。
另一种选择是完全手动执行此操作。假设你有这张表:
CREATE TABLE dbo.Employee
(
EmployeeID INT,
Name NVARCHAR(255),
Salary INT
);
INSERT ...
Run Code Online (Sandbox Code Playgroud)
从理论上讲,如果不考虑由键、约束、触发器和模式绑定对象引起的复杂情况,您可以通过以下方式“更改”列的顺序 - 对于要移动的列左侧的每一列 - 创建一个新列,移动数据,删除旧列,并重命名新列。这是有效的,因为新列始终添加到表的“末尾”。忽略错误处理和任何其他复杂情况:
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;
Run Code Online (Sandbox Code Playgroud)
这当然有可能与 Management Studio 仅仅交换整个表的方法一样具有破坏性(或更糟),并且如果您想要移动多个列,则变得非常复杂。
现在,您真的需要更改列顺序吗?
如果不删除并重新创建表,则无法更改 SSMS 中看似物理列的顺序。
为什么不直接更改查询以按不同的顺序选择列呢?
从:
SELECT Eid, Ename, Esalary FROM Table
Run Code Online (Sandbox Code Playgroud)
到:
SELECT Eid, Esalary, Ename FROM Table
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
51180 次 |
| 最近记录: |