这是防止DB提交失败的最佳方法吗?

时间:2013-03-27 22:50:58

标签: c# transactions compact-framework sql-server-ce windows-ce

我有一个继续抛出异常的遗留方法。它有一个嵌套的try | catch。这是编码这类事物的最佳方式:

public void DBCommand(string dynSQL, bool Silent)
{
    checkConnection(); //Despite the name, this "returns" void, not bool
    SqlCeCommand cmd = objCon.CreateCommand();
    SqlCeTransaction trans = GetConnection().BeginTransaction();
    cmd.Transaction = trans;

    try
    {
        cmd.CommandText = dynSQL;
        cmd.ExecuteNonQuery();
        trans.Commit();
    }
    catch (Exception ex)
    {
        try 
        {
            trans.Rollback();
        }
        catch (SqlCeException sqlceex) 
        {
            MessageBox.Show(string.Format("SqlCeException ({0})", sqlceex.Message));
            CCR.LogMsgs.Append(string.Format("SqlCeException exception: {0}\r\n", sqlceex.Message));
            // Handle possible Rollback exception here
        }
        MessageBox.Show(string.Format("DBCommand Except ({0})", ex.Message));
        CCR.LogMsgs.Append(string.Format("DBCommand exception: {0}\r\n", ex.Message));
    }
}

我想重构它以至少使用至少SqlCeCommand的语句,但是现在上面是“原样”代码。我正在看一般的异常消息 (“DBCommand Except”),绝不是“SqlCeException”

更新

通过添加一些MessageBox.Show()调用(由于某种原因不再编写调试日志文件),我发现这是抛出异常的DDL:

ALTER TABLE CCR032713190114 ADD salvationId nvarchar(19), salvation float

注意:“CCR032713190114”已被证明是代码中此时的有效表名(它存在)。

这个DDL有问题会导致问题吗?

更新2

我改变了代码:

ddl = string.Format("ALTER TABLE {0} ADD salvationID nvarchar(19) ", tablename);
dbconn.DBCommand(ddl,false);
ddl = string.Format("UPDATE {0} SET salvationID = {1}", tablename, string.Empty);

......对此:

ddl = string.Format("ALTER TABLE {0} ADD salvationID nvarchar(19) NOT NULL WITH DEFAULT", tablename);
dbconn.DBCommand(ddl,false);

...但是现在,紧接着“ ALTER TABLE BLA ADD salvation float NOT NULL with DEFAULT ”我看到这个错误的消息,“ DBCommand Except(解析时出错)查询。 [令牌行号,令牌行偏移,令牌错误,])

Azure braziers在这里发生了什么?

我是否需要在“WITH DEFAULT”之后指定一个默认值(不会'或'string.empty自动成为nvarchar列的默认值,0.0表示浮点数等)?

2 个答案:

答案 0 :(得分:2)

你不能在同一个ALTER TABLE语句中添加两列,必须一次添加一个,也好主意指定NULL或NOT NULL(如果NOT NULL,可能需要DEFAULT)

答案 1 :(得分:1)

如果你没有看到SqlCeException,那么它真的是特殊的。为了让它“不受阻碍”,我会做以下事情:

public void DBCommand(string dynSQL, bool Silent) {
    checkConnection(); //Despite the name, this "returns" void, not bool
    SqlCeCommand cmd = objCon.CreateCommand();
    SqlCeTransaction trans = GetConnection().BeginTransaction();
    cmd.Transaction = trans;

    var doRollback = false;
    try {
        cmd.CommandText = dynSQL;
        cmd.ExecuteNonQuery();
        trans.Commit();
    }
    catch (Exception ex) {
        doRollback = true
        MessageBox.Show(string.Format("DBCommand Except ({0})", ex.Message));
        CCR.LogMsgs.Append(string.Format("DBCommand exception: {0}\r\n", ex.Message));
    }
    finally {
        if(doRollback) }
            DoRollback();
        }
    }
}

void DoRollback(){
    try {
        trans.Rollback();
    }
    catch (SqlCeException sqlceex)  {
        MessageBox.Show(string.Format("SqlCeException ({0})", sqlceex.Message));
        CCR.LogMsgs.Append(string.Format("SqlCeException exception: {0}\r\n", sqlceex.Message));
        // Handle possible Rollback exception here
    }
}

}