web-dev-qa-db-ja.com

トランザクション内(SQL Server内)で複数のDDLステートメントを実行することは可能ですか?

トランザクション内で複数のDDLステートメントを実行できるかどうか疑問に思っています。他のデータベース(少なくともOracle、PostgreSQL)での回答も興味深いかもしれませんが、私はSQLServerに特に興味があります。

トランザクション内で作成されたテーブルに対して「CREATETABLE」と「CREATEVIEW」を実行してきましたが、いくつかの不整合があるようで、トランザクション内でDDLを実行すべきではないかと思います...

おそらくトランザクションの外にDDLを移動することもできますが、これについての参照を取得したいと思います。私がこれまでに見つけたもの:

  • MSDNページ データベースエンジンの分離レベル は、スナップショット分離で実行されている明示的なトランザクションで実行できるDDL操作に制限があることを明確に示しています-しかし、スナップショットアイソレーションを使用していないため、エラーが発生するはずです。
    • これは、DDL操作をさまざまな分離レベルで明示的なトランザクションで実行できるように解釈できますか?
  • Oracle®DatabaseGatewayfor SQL Serverユーザーズガイド#DDLステートメント は、特定のトランザクションで実行できるDDLステートメントは1つだけであると述べています -これは、SQL Serverを直接使用する場合にも有効ですか?

Oracleの場合:

重要な場合は、JTDSJDBCドライバーを介してJavaでこれを実行しています。

b.r.とうこ

29
Touko

ほとんどのデータベースに制限があることは知っていますが、Postgresにはありません。トランザクションでは、任意の数のテーブルの作成、列の変更、およびインデックスの変更を実行できます。変更は、COMMITが成功した他のユーザーには表示されません。それがデータベースのあり方です! :-)

SQL Serverの場合、トランザクション内でDDLを実行できますが、 SQL Serverはメタデータをバージョン管理しない であるため、トランザクションがコミットされる前に変更が他のユーザーに表示されます。ただし、 トランザクション中にある場合は一部のDDLステートメントをロールバックできます ただし、どのステートメントに対して機能し、どのステートメントに対して機能しないかについては、いくつかのテストを実行する必要があります。

13
David Roussel

テーブルやビューなどをその場で作成している場合(テーブル変数や一時テーブルを除く)、本当にデザインを再考する必要があるかもしれません。これは、通常ユーザーインターフェイスから発生するはずのことではありません。カスタマイズを許可する必要がある場合でも、トランザクションの挿入/更新/削除の実行と同時にDDLステートメントを実行しないでください。これらの機能を分離することをお勧めします。

これは、2人のユーザーが同じテーブルの構造を同時に変更し、トランザクションを実行してデータを挿入しようとするとどうなるかについて、十分な検討とテストが必要なことでもあります。ユーザーがデータベース構造を調整できるようにすると、本当に恐ろしいことが起こります。

また、一部のDDLステートメントは、常にバッチの最初のステートメントである必要があります。あなたがそれらを実行しているときもそれを探してください。

4
HLGEM

一般的なケースとIIRCの場合、DDLステートメントがトランザクションであると想定するのは安全ではありません。

つまり、スキーマの変更がトランザクション内でどのように相互作用するかについては、かなりの余裕があります(それがまったく相互作用すると仮定します)。これは、ベンダーによるものでも、特定のインストール(つまり、dbaまで)によるものでもかまいません。したがって、少なくとも、1つのDBMSを使用して、他のDBMSがDDLステートメントを処理すると想定しないでください。

編集:MySqlは、DDLトランザクションをまったくサポートしないDBMSの例です。また、データベースのレプリケーション/ミラーリングがある場合は、レプリケーションサービス(Sybaseのレプリケーションが標準ですが、信じられないかもしれませんが)が実際にDDLステートメントをレプリケートすることに十分注意する必要があります。

1
hythlodayr

MS SQLでは、DDLおよびDMLステートメントが実行されると暗黙的なトランザクションがトリガーされる可能性があります。これをオフに切り替えると、これが役立ちます。SETIMPLICIT_TRANSACTIONSを使用してください

編集:別の可能性-CREATEVIEWを同じバッチ内の他のステートメントと組み合わせることはできません。 CREATETABLEは大丈夫です。 GOでバッチを分離します。

EDIT2:GOで区切られている限り、トランザクションで複数のDDLを使用して異なるバッチを作成できます。

1
Stuart