web-dev-qa-db-ja.com

列の順序を変更するにはどうすればよいですか?

SQL Server 2008 R2で列の順序を変更するにはどうすればよいですか?

例:テーブルの順序はEid ------ Ename ----- Esalaryです

Eid --- Salary ---- Enameのようなこのフォーマットが必要であることを知っている

ありがとう。

5
user36326

テーブル内の物理的な列の順序を気にする必要はありません。これが問題になる唯一のケースは、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);

次に、オブジェクトエクスプローラーでテーブルを右クリックし、[デザイン]を選択します。並べ替える列名の左側にあるボックスを選択します。列をテーブル内の別の場所にドラッグします。 abの上に移動しました。これは、OCDであり、列をアルファベット順にしたいためです。

enter image description here

次に、[Generate Change Script]ボタンをクリックします。これは、作成した怪物です(これは、キー、制約、トリガーなどのないヒープです。この再作成はかなり複雑になる可能性があります)。

/*
   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のアプローチと同じくらい混乱する(またはさらに悪い)可能性があり、複数の列を移動する場合は非常に複雑になります。

さて、本当に列の順序を変更する必要がありますか

9
Aaron Bertrand

テーブルを削除して再作成しないと、SSMSでの物理的な列の順序を変更できません。

別の順序で列を選択するようにクエリを変更しないのはなぜですか?

から:

SELECT Eid, Ename, Esalary FROM Table

に:

SELECT Eid, Esalary, Ename FROM Table
2
Mark Sinkinson

基になるテーブルを変更しますか、それとも結果を変更しますか?

結果だけの場合は、selectステートメントを並べ替えるだけです。

例えば。の代わりに

SELECT Eid, Ename, Esalary FROM ThatTable;

使用する

SELECT Eid, ESalary, EName FROM ThatTable;

また、そのテーブルに基づいて、希望の順序で選択するビューを設定することもできます。

もちろん、本当に必要な場合は、テーブルを削除して再作成するだけです。データを保持したい場合は、データのエクスポートとインポートに注意してください。

1
Mark

ツール>オプション>デザイナ>テーブルおよびデータベースデザイナ>変更を保存しないようにする...

設定を保存した後、フィールドの移動など、デザインビューで行った変更を保存できるようになりました

1

「簡単」ではありません。しかし、別のデータを作成して、同じデータを希望どおりに再度挿入することができます。操作ステートメントの順序を変更する最も簡単な方法。お気に入り:
SELECT Eid, Salary, Ename FROM TABLE;

0
Jann Claude