2012-02-24 7 views
2

古いデータテーブルから新しいテーブルにデータを移行しています。このプロセスで私はいくつかの問題に遭遇しました。IF内でCREATE/DROPテーブルを使用する方法

私はテーブルを作成し、古いテーブルから新しいものにいくつかのデータをコピーしてから古いテーブルを削除する必要があります。これを達成するには、移行したデータベースで実行してもエラーを表示しないスクリプトを作成する必要があります。つまり、古いテーブルが存在しない場合でも、エラーは表示されず、プロセスをスキップする必要があります。 、ここで

IF NOT EXISTS(SELECT * FROM sys.objects WHERE Object_ID = Object_ID('Old_Table')) 
    GOTO Migrated_Before 

    -- Drop OldTable Indexes, PK's and FK's; 
    -- CREATE newTable ....; 
    -- Add Indexes, PK's, Fk's; 
    -- INSERT INTO NewTable(someFields) FROM OldTable.Fields, OtherTable.Fields ...; 
    -- DROP OldTable; 

Migrated_Before: 

は問題であるドロップおよび作成する前に、それ以外の場合は次のステージに進み、次のコマンドは、しかし、GOを入れて、失敗する変更をコミットするためにGO必要が:後

は、私が今までに思い付いたものですGOTOとLabelの間でGOTOのラベルが未定義になります。

IFを複数回書き込まずに次のプロセスに進む前に、各プロセスを強制的に実行するにはどうすればよいですか?

解決策:解決策は他の人の参考にしておきます。 次のステートメントに進む前に、必要なすべてのステートメントの前にbeginトランザクションを追加しました。たとえば、create tableまたはdrop FKです。また、gotoとlabelをbegin end(私の最初の解)に置き換えました。

+0

、私はGOTO' 'の使用を再考したいです。結局のところ*有害であるとみなされます* - http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html – Yuck

+0

IFを避ける特別な理由はありますか?私はよく、漸進的な変更がGOとコミット/分離される必要がある冪等でなければならないスキーマ変更スクリプトで作業し、IFはGOTOよりもうまくいくようです。 –

+0

@Yuck、良い点ですが、私は次の行を実行する前にそれぞれの行を実行し、 'begin'、' end'の中で 'GO'が動作しないようにしてください。 – Bistro

答えて

2

commitbegin transactionを使用してみてください代わりに何か他のものの前にgo

+0

コミットには対応するトランザクションが必要です。ここでは取引は行われません。 –

+2

サム、明らかにそれは私が意味していたものです:) – AaA

1

CREATE、DROP、および以下の3つのコマンドを別々のストアドプロシージャに入れ、GOTOの後にそのプロシージャを呼び出してみてください。このSPは、必要なGOステートメントと競合します。これはそのままLabelの範囲を保持することがあります。

+0

良いアイデア、それは私に良い方向を指摘、私はコマンドを実行するためにsp_executeを使用することができます。それは私のコードをちょっと乱雑にしますが – Bistro

1

私はせずに、以下のこのコードを実行することができます任意の「GO」

if object_id('abc') is not null 
    drop table abc 
create table abc (asdf varchar(10)) 

if object_id('abc') is not null 
    drop table abc 
create table abc (asdf varchar(10)) 

if object_id('abc') is not null 
    drop table abc 
create table abc (asdf varchar(10)) 

また、あなただけのヌルのOBJECT_ID()の代わりに、sys.objectsテーブルを照会するためにチェックすることができます。

+0

サム、あなたの答えは正しいですし、まだ行く必要がありますが、あなたが25のテーブルとそれぞれについて同じことをしているときには、 3〜8のインデックスを持つ – Bistro

+0

「複数回繰り返す必要がある」という言葉が何であるか分かりません。 「GO」は必要ではないことを示すために繰り返されます。 –

+0

これを処理するために "GOTO"を使用すべきではありません。たぶん、これをストアドプロシージャにラップして、テーブルごとに実行する必要があります。 また、なぜテーブルを削除して再作成する必要がありますか?テーブルの定義は毎回変わるでしょうか?または、データを消去してインデックスを再作成するだけで逃げることができますか? (切り捨て)。あなたは少し混乱させようとしています...私は確かに "読みやすい"解決策があると思います。正確に何をやっているのか、理由を教えてください。より良い答えが得られます。 –

関連する問題