0

C# で SQL Server を使用すると、次のように言う価値があります。

IF COL_LENGTH('MyTable','MyColumn') IS NULL
 BEGIN
 ALTER TABLE MyTable ADD MyColumn INT
 END

呼び出しの周りにキャッチを簡単に配置できるためです。

try
{
Db.ExecuteNonQuery("ALTER TABLE MyTable ADD MyColumn INT");
}
catch(Exception)
{
}

そして、常に失敗する場合はそのままにしておきます(古いデータベースで実行している場合を除く)...またはそれはいたずら/遅い/などですか?

4

5 に答える 5

9

例外は、規則の例外のように「例外的」であるべきです。このコードを実行する予定はありますか? 90% の確率で列が存在しますか?

それでは「例外的」ではありません。

通常のロジック フローとして例外キャッチを使用しないでください。

私よりも賢い人によるいくつかの指針を次に示します。

http://blogs.msdn.com/b/kcwalina/archive/2005/03/16/396787.aspx

「通常の制御フローに例外を使用しないでください。」


これが私の典型的な冪等追加列 tsql です。

IF EXISTS (    SELECT TABLE_SCHEMA , TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Categories' and TABLE_SCHEMA = 'dbo'    )
    BEGIN

        IF NOT EXISTS 
        (
            SELECT * 
                FROM [INFORMATION_SCHEMA].[COLUMNS] 
            WHERE   
                TABLE_NAME = 'Categories' 
                AND TABLE_SCHEMA = 'dbo'
                AND COLUMN_NAME = 'CategoryName'
        )
            BEGIN
                print 'Adding the column dbo.Categories.*CategoryName*'

                ALTER TABLE [dbo].[Categories] ADD [CategoryName] nvarchar(15) NOT NULL

            END
        ELSE
            BEGIN
                print 'The column dbo.Categories.*CategoryName* already exists.'
            END

    END
于 2013-03-11T13:16:21.397 に答える
7

この方法で例外をキャッチしないでExceptionください。例外がスローされたかどうかはわかりません。

  • テーブルが存在しないため
  • 列が既に存在するため
  • 接続文字列が間違っているため
  • ネットワークエラーのため
  • その他の理由

まだ存在しない場合にのみ列を作成する場合は、追加する前に列の存在を確認する SQL を記述してください。

于 2013-03-11T13:16:02.847 に答える
2

この場合、速度は本当に重要ですか?データベースをどのくらいの頻度で更新しますか?

ただし、すべての例外を黙って食べたいと本当に確信していますか? 問題は、DDL (データベースの変更) 権限がないこと、または列が存在するが異なる列タイプであることが考えられます。

于 2013-03-11T13:16:36.857 に答える
0

C# コード フローは、実際の作業が行われるバックエンド周辺の浅いシムにすぎません。そのため、明らかな疑問が生じます。

例外が発生したのはなぜですか?

理由には以下が含まれますが、これらに限定されません。

  • テーブルを変更する権限がありません
  • テーブルで SCH-M ロックを取得しようとしてタイムアウトしました
  • 新しい列は、ログ領域を使い果たすサイズのデータ​​操作をトリガーします
  • カスタムDDL トリガーが実行を妨げる
  • ポリシーベースの宣言型管理ルールにより、実行が防止されます
  • IO サブシステムが崩壊し、データベースがオフラインになっている
  • 列は既に存在します(これはあなたが考えた唯一のケースのようです)

失敗する可能性のある理由は1 つしか考えられないため、例外を静かに飲み込んで黙らせようとします。データベースを扱うときは、常に本格的なログ記録が必要です。

例外は無料ですか?

SEH が安価かどうかについては長い議論がありますが、データベースの DDL について話すとき、これは完全に的外れです。オブジェクトの SCH-M ロックを要求しているため、それを取得するまで全員がブロックされます。DDL がスローし、例外を処理したとしても、uber ロックが付与されるのを待っている間、スループットは既に 0 (ゼロ) に低下しています。そして、あなたは何時間も待っていたかもしれません、あなたは知っています...

于 2013-03-11T13:33:57.317 に答える
0

スクリプトは複数回実行する必要がある場合があるため、スクリプトでこのタイプのチェックを実行するのは非常に標準的です。たとえば、他のテーブルの変更がそれに追加される場合があります。誰かがスクリプトを再実行する必要がある場合に、スクリプトでエラーが発生するのは望ましくありません。

他の人が指摘したように、例外は真に例外的な条件のために予約する必要があります。

しかし、C# コードでこれを行うには、別の問題があります。(おそらく) アプリケーション コードにデータベース メンテナンスの要素が混在しているということです。関心の分離の原則に従えば、コードははるかに読みやすく保守しやすくなります。

于 2013-03-11T13:26:46.683 に答える