2

オブジェクトを削除して再度作成する前に、オブジェクトが存在するかどうかを確認するために sysobjects テーブルをクエリしている場所で実行しようとしているコードがたくさんあります。

問題は、時々私が行けば:

if not exists (select name from sysobjects o where o.name = 'my_table' and o.type =  'U') 
CREATE TABLE my_table (..)
go

それは動作します、心配する必要はありません。ただし、もう一度実行するために戻ったとき、次の素敵なエラーが発生します。

SQL Server Error on (myserver) Error:2714 at Line:10 Message:There is already an object named 'my_table' in the database.

ありがとう、SQL プログラマー。このテーブルが既に存在する場合は作成しないでください。-_-

何か案は?

4

3 に答える 3

1

あなたがやっていることの論理はまったく正しくないようです。あなたの声明に基づいて:

「オブジェクトを削除して再度作成する前に、オブジェクトが存在するかどうかを確認するために、sysobjects テーブルをクエリしている場所で実行しようとしています」

単純に削除してから作成する必要があります。テーブルが確実に更新されるため、通常はこの方法の方が適しています。テーブルが存在し、変更があった場合、おそらく必要なものが得られません。

あなたが直面している当面の問題は、実行間で一貫していない想定された db 所有権です。

以下の説明に基づいて-できることは次のとおりです。

存在する場合 (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[XXXX]') AND type in (N'U')) DROP TABLE [dbo].[XXXX] GO

CREATE TABLE [dbo].[XXXX(... GO

あなたはこれを何度も実行することができます...

于 2009-06-17T01:58:37.160 に答える
0

sybase パーサー オブジェクトの検証パスはグローバルであり、条件評価に基づいていません。コードで CREATE TABLE を実行できない場合でも、ステートメントの構文と適用可能性がチェックされますが、システムがテーブルが既に存在することを確認すると失敗します。

私が知っているこれを回避する唯一の方法は、作成ステートメントを EXEC() 内に配置することです。これは、セクションが実行された場合にのみ評価されます。

于 2009-06-17T01:52:34.160 に答える
0

はい、バッチ全体の「実行計画」を作成するために、SQL のバッチ全体が正規化およびコンパイルされます。正規化中、「可能な」「テーブルの作成」ステートメントがコンパイル時に既に存在する場合、問題になります。

私の解決策:名前を変更 -

存在する場合 (... から 1 を選択) begin drop table xyz create table xyz_zzzz ( ... ) exec sp_rename 'xyz_zzzz','xyz' end

于 2009-06-22T15:19:43.873 に答える