web-dev-qa-db-ja.com

Microsoft SQL Serverの特定の順序位置に新しいテーブル列を追加します

Microsoft SQL Serverの特定の順序位置でテーブルに列を追加することは可能ですか?

たとえば、テーブルの各テーブル定義の「終わり」には、常にCreatedOn、CreatedBy、LastModifiedOn、LastModifiedBy列がありますか?新しい列をこれらの列の上にあるSSMSに表示したいと思います。

データベースのすべての変更をスクリプト化する場合、表の最後でこの順序を保持する方法はありますか?

ちなみに、もしこれが行われるべきならば、私は火炎戦争を開始しようとはしていません。すぐに退化するスレッドについて読みたい場合は、ここに良いものがあります:

http://www.developersdex.com/sql/message.asp?p=581&r=501451

41
Even Mien

元のテーブルのスキーマをミラーリングする一時テーブルを作成する必要がありますが、必要な列の順序を使用して、元のコンテンツを一時にコピーする必要があります。オリジナルを削除し、tempの名前を変更します。

これは、SQL Management Studioが舞台裏で行うことです。

スキーマ同期ツールを使用すると、これらのスクリプトを自動的に生成できます。

29
Jose Basilio

sQL Server Management Studioに移動し、既存のテーブルを「設計」します。中央に列を挿入し、空の領域で右クリックして変更スクリプトの生成...を選択します

次に、作成するスクリプトを見てください。基本的に、適切な列順序で一時テーブルを作成し、元のテーブルからデータを挿入し、元のテーブルを削除して、一時テーブルの名前を変更します。これはおそらくあなたがする必要があることです。

enter image description here

変更スクリプトの作成を許可するには、このオプションをオフにする必要がある場合もあります

enter image description here

14
KM.

答えは「はい」です。技術的には可能ですが、そうすることで頭痛がし、実行とセットアップに時間がかかります。

1つ:作成/コピー/ドロップ/名前変更

これは、SQL Serverがグラフィカルインターフェイスで実際に実行していることです。新しい列をテーブルの先頭に追加した後、[保存]ボタンをクリックしたときに生成および実行されるスクリプトの例を次に示します。

/* 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_SomeTable
    (
    MyNewColumn int NOT NULL,
    OriginalIntColumn int NULL,
    OriginalVarcharColumn varchar(100) NULL
    )  ON [PRIMARY]
     TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_SomeTable SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_SomeTable ON
GO
IF EXISTS(SELECT * FROM dbo.SomeTable)
     EXEC('INSERT INTO dbo.Tmp_SomeTable (OriginalIntColumn, OriginalVarcharColumn FROM dbo.SomeTable WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_SomeTable OFF
GO
DROP TABLE dbo.SomeTable
GO
EXECUTE sp_rename N'dbo.Tmp_SomeTable', N'SomeTable', 'OBJECT' 
GO

GO
COMMIT

2つ:列の追加/更新/列の削除/名前の変更

この方法では、基本的に、新しい列の「右側」に追加する既存の列のコピーを作成し、データを新しい列に転送してから、元の列を削除して新しい列の名前を変更します。これは、インデックスや制約を再ポイントする必要があるため、インデックスや制約を破壊します。技術的には可能ですが、開発と実行の両方の面で時間がかかります。

CREATE TABLE MyTest (a int, b int, d int, e int)

INSERT INTO MyTest (a,b,d,e) VALUES(1,2,4,5)

SELECT * FROM MyTest -- your current table

ALTER TABLE MyTest ADD c int -- add a new column
ALTER TABLE MyTest ADD d_new int -- create copies of the existing columns you want to move
ALTER TABLE MyTest ADD e_new int

UPDATE MyTest SET d_new = d, e_new = e -- transfer data to the new columns

ALTER TABLE MyTest DROP COLUMN d -- remove the originals
ALTER TABLE MyTest DROP COLUMN e

EXEC SP_RENAME 'MyTest.d_new', 'd'; -- rename the new columns
EXEC SP_RENAME 'MyTest.e_new', 'e';

SELECT * FROM MyTest 

DROP TABLE MyTest -- clean up the sample

:一緒に暮らす

これは私の秩序の感覚を著しく傷つけます...しかし、時には、それは単に改造する価値がないだけです。

7
AHiggins

私の知る限り、列の順序を変更する既知の方法はありません。舞台裏では、SQL Management Studioがホセバシリオの言ったことを実行します。また、大きなテーブルがある場合、このように列の順序を変更することは実用的ではありません。

「ビュー」を使用できます。 SQLビューを使用すると、テーブル列の変更の影響を受けることなく、好きな順序で使用できます。

3
tbaskan

汚いとシンプル。
テーブルをcsvにエクスポートします。
新しいデータを目的の位置に挿入します。
ドロップテーブル。
目的の列仕様で新しいテーブルを作成します。
csvから新しいテーブルに列をロードします。

0
BioDeveloper

スレッドがまだアクティブかどうかはわかりません。 MySQLデータベースで同じクエリを実行していました。テーブルを右クリックして「変更」を選択すると、以下のコードが自動生成されました。 sakila dbからサンプルが提供され、動作しました。新しい列を配置する後の列を見つけて、「AFTER」キーワードを使用します

ALTER TABLE `sakila`.`actor` 
CHANGE COLUMN `middle_name` `middle_name` VARCHAR(50) NULL DEFAULT NULL AFTER `first_name`; 

TFS 2013はこれを自動的に行います

必要に応じて新しい列をテーブルに追加し、変更をTFSにコミットします。そこからVisual Studioでテーブルのsqlファイルを開き、T-SQL CREATEスクリプトで列の順序を手動で移動できます。次に、[ツール]> [SQL Server]> [新しいスキーマ比較]にあるVSのスキーマ比較ツールを使用して、ターゲットデータベースを更新できます。変更をソースとしてデータベースプロジェクトを選択し、更新するデータベースをターゲットとして選択します。比較し、テーブルのスクリプトを選択して、更新します。 VSは自動的に削除および追加されます。すべてのデータが安全になり、インデックスも作成されます。

0
Rickest Rick

一時テーブルのすべての列を選択し、古いテーブルを削除する新しい列を使用して新しいテーブルを作成し、一時テーブルからすべての列を選択し、列に新しい列を挿入します。データが失われることなく

select * FROM TEMP
select * from originaltbl
select * from #Stagintbl 



declare @ColumnName nvarchar(max);
set @ColumnName=(select
   distinct  
    stuff((
        select ',' + a.COLUMN_NAME
        from (select Column_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME='originaltbl') a

        for xml path('')
    ),1,1,'') as ColumnName)

declare @Sqlquery nvarchar(max)
set @Sqlquery='select '+@ColumnName+' from  #Stagintbl'+'';
Insert into originaltbl
Execute(@Sqlquery)
0
suraj sharma

シンプルだと思うのは、列ALTER TABLE table1 ADD ..を追加してから、select SELECT col1,col2,col5,col3,col4 into tmp_table1 from table1;次に、table1をドロップし、tmp_table1の名前をtable1に変更します。私はそれが誰かを助けることを願っています

0