是否可以尝试并将列添加到SQL Server数据库并捕获异常?

时间:2013-03-11 13:12:38

标签: c# sql sql-server

在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)
{
}

然后让它一直失败(除了在旧数据库上运行时)... 还是顽皮/慢/等?

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:7)

只是不要以这种方式捕获Exception异常:你永远不会知道它是否被抛出:

  • 因为表不存在
  • 因为列已存在
  • 因为连接字符串错误
  • 由于网络错误
  • 任何其他原因

如果只想创建一个列,如果它尚不存在,请在添加之前编写检查列存在的SQL。

答案 2 :(得分:2)

在这种情况下,速度真的很重要吗?您多久更新一次数据库?

但是,你真的确定你想要默默地吃掉所有例外吗?问题可能是您没有DDL(修改数据库)权限或列存在但具有不同的列类型。

答案 3 :(得分:0)

在脚本中执行此类检查非常标准,因为脚本可能需要多次运行。例如,可能会向其添加其他表更改。如果有人必须重新运行它,您不希望脚本导致错误。

正如其他人所指出的那样,应该为真正特殊情况保留例外情况。

但是在C#代码中执行此操作还有一个问题:您正在将数据库维护内容混合到(大概)您的应用程序代码中。如果您遵循separation of concerns原则,那么您的代码将更具可读性和可维护性。

答案 4 :(得分:0)

你的C#代码流只是后端的一个浅垫片,真正的工作正在发生。因此,出现了明显的问题:

为什么是一个例外?

原因包括但不限于:

你愿意默默地吞下并使异常沉默,因为你只能想到一个可能的失败原因。在处理数据库时,你总是需要认真记录,否则你只是在脚下射击。

免除异常吗?

关于SEH是否便宜还存在很长时间的争论,但在数据库中谈论DDL时,这完全超出了这一点。 您正在请求对象的SCH-M锁定,因此会阻止所有人,直到您获得它为止。即使您的DDL抛出并处理异常,在等待授予超级锁定时,您已经将吞吐量降低到0()。你可能已经等了小时,你知道......