簡體   English   中英

僅嘗試並在SQL Server數據庫中添加一列並捕獲異常就可以了嗎?

[英]Is it OK to just TRY and add a column to an SQL Server database and catch the exception?

值得一提的是在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)
{
}

並讓它一直都失敗(在舊數據庫上運行時除外)...還是那調皮/慢/等?

與規則的例外一樣,例外應為“例外”。 您是否計划運行此代碼,並且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

只是不要以這種方式捕獲Exception異常:您永遠不會知道它是否被拋出:

  • 因為該表不存在
  • 因為該列已經存在
  • 因為連接字符串錯誤
  • 由於網絡錯誤
  • 任何其他原因

如果您只想創建不存在的列,請在添加列之前編寫用於檢查該列是否存在的SQL。

在這種情況下,速度真的重要嗎? 您多久更新一次數據庫?

但是,您真的確定要靜默地吃掉所有異常嗎? 問題可能是您沒有DDL(修改數據庫)權限,或者該列存在但具有不同的列類型。

在腳本中執行這種類型的檢查是很標准的,因為腳本可能需要運行多次。 例如,其他表更改可能會添加到其中。 如果有人必須重新運行腳本,則不希望腳本引起錯誤。

正如其他人指出的那樣,應該為真正的例外情況保留例外。

但是在C#代碼中執行此操作還有另一個問題:您正在將數據庫維護內容混入(大概是)您的應用程序代碼中。 如果遵循關注點分離的原則,您的代碼將更具可讀性和可維護性。

您的C#代碼流只是后端的淺薄填充, 真正的工作在此發生。 因此,出現了明顯的問題:

為什么引發例外?

原因包括但不限於:

  • 您無權更改表格
  • 您超時嘗試在桌子上獲取SCH-M鎖
  • 新列會觸發數據量操作 ,該操作將耗盡日志空間
  • 自定義DDL觸發器阻止執行
  • 基於策略的聲明式管理規則會阻止執行
  • IO子系統剛剛崩潰,數據庫處於脫機狀態
  • 該列已存在(這似乎是您想到的唯一一種情況)

您願意默默地吞下並使異常保持沉默,因為您只能考慮一種可能的失敗原因。 在處理數據庫時,您總是需要認真記錄日志,否則,您將陷入困境。

例外是免費的嗎?

關於SEH是否便宜,人們爭論不休,但這完全超出了談論數據庫中的DDL的意義。 您正在請求對對象進行SCH-M鎖定,因此將阻塞所有人,直到您獲得它為止。 即使您的DDL拋出並處理了異常,在等待授予超級鎖定時,您的吞吐量也已降至0( )。 而且您可能已經等了幾個小時 ,您知道...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM