停止嵌套尝试捕获

时间:2014-01-03 17:58:53

标签: c# try-catch

我有一个嵌套的Try / Catch用于库存的来龙去脉。

如果重复序列号,则无法更新库存以将输入的数量相加。

含义: 如果我的产品“X”的序列号为“12345”并且我输入了该产品,则系统会检查“X”产品中是否存在序列号。

第一次尝试插入序列号,第二次尝试更新库存。

F / E: 我有7个“X”产品,其中7个产品是“12345”。 如果我插入“12345”,则第一个捕获表示“12345”已经存在,但在此之前更新库存并将+1与“X”产品相加而留下8“X”产品时不应该这样。

以下是一些代码:

try
{
  MySqlCommand cmdc = new MySqlCommand( "insert into mov ( folio, clave, descr, total, timo ) VALUES ( '"
    + textBox1.Text
    + "'  ,'"
    + comboBox1.Text
    + "'  ,'"
    + textBox3.Text
    + "'  ,"
    + r1
    + ",'S');" ,
    conn
    ) ;

  MySqlDataAdapter dataadapc = new MySqlDataAdapter(cmdc);
  System.Data.DataTable datatabc = new System.Data.DataTable();
  dataadapc.Fill(datatabc);

  foreach (DataRow row in datatabc.Rows)
  {
    string rows = string.Format("{0}", row.ItemArray[0]);
    aux = rows;
  }

  try
  {
    MySqlCommand command = new MySqlCommand("update inventario SET can = can - "
      + numericUpDown1.Value
      + " WHERE cla = '"
      + comboBox1.Text
      + "';" ,
      conn
      ) ;

    command.ExecuteNonQuery();
    j++;

  }
  catch (Exception ex)
  {
    MessageBox.Show("Error: No se puede modificar el inventario.");
    MessageBox.Show(ex.Message);
  }

  try
  {
    MySqlCommand command = new MySqlCommand("update inventario SET lin = 'CMI', dias = 0 WHERE cla = '"
      + comboBox1.Text
      + "';" ,
      conn
      ) ;

    command.ExecuteNonQuery();

  }
  catch (Exception ex)
  {
    MessageBox.Show("Error: No se puede modificar el inventario.");
    MessageBox.Show(ex.Message);
  }

}
catch (Exception ex)
{
  MessageBox.Show("Error: No se puede modificar el inventario.");
  MessageBox.Show(ex.Message);
}

}

如果第一个异常激活,如何停止系统,因此不执行第二个查询?

8 个答案:

答案 0 :(得分:4)

将两个操作放在一个try块中

try
{
    MySqlCommand command = new MySqlCommand("update inventario SET can = can - " + numericUpDown1.Value + " WHERE cla = '" + comboBox1.Text + "';", conn);
    command.ExecuteNonQuery();
    j++;

    MySqlCommand command = new MySqlCommand("update inventario SET lin = 'CMI', dias = 0 WHERE cla = '" + comboBox1.Text + "';", conn);
    command.ExecuteNonQuery();
}
catch (Exception ex)
{
    MessageBox.Show("Error: No se puede modificar el inventario.");
    MessageBox.Show(ex.Message);
}

答案 1 :(得分:0)

根据你的描述,我假设你想要一个例外以继续向上移动。

你可以通过再次抛出异常来做到这一点

    catch (Exception ex)
    {
      //Log the error or whatever
    throw;
    }

这将向上抛出异常,并且代码的第二部分将不会被执行。

答案 2 :(得分:0)

你能做这样的事吗:

try{

    try{
        // insert serial number
    }

    catch{
         //handle exception
        throw;
    }

    try{
        // update inventory
    }
    catch{
        // handle inventory exception
    }

}
catch{
    // handle other exceptions
}

答案 3 :(得分:0)

在catch中放置一个“return”,以便后面的任何代码都不会被执行。

try
{
    // Do something
}
catch
{
    // Do something
    return;
}

答案 4 :(得分:0)

  

如果第一个异常激活,如何停止系统,因此不执行第二个查询?

首先不使用控制流的例外。您正在检查的条件似乎是可能发生的有效事情。因此,使用简单的条件表达式来检查它们。您可以相应地嵌套这些条件。

所以不要这样:

try
{
    InsertID();
}
catch
{
    // nothing exceptional happened
}
try
{
    UpdateInventory();
}
catch
{
    // this is a lot of try/catch for no reason
}

你会做这样的事情:

if (IDExists())
    HandleIDExistsError();
InsertID();
UpdateInventory();

或许这个:

if (!IDExists())
{
    InsertID();
    UpdateInventory();
}

回顾您的更新问题,您有一个很多的try / catch块,它们只是处理逻辑流程。 catch块正在假设发生的错误的性质,这可能是不正确的。然后他们丢弃了有关异常的有用信息,可用于纠正问题。

异常不适用于正常的逻辑流程。不要用它们来代替条件。

编辑:更好的是,请查看使用交易。由于您有两个数据修改应该作为单个原子进程发生,因此您可以将 包装在异常处理程序中。类似的东西:

if (!IDExists())
{
    try
    {
        BeginTransaction();
        InsertID();
        UpdateInventory();
        CommitTransaction();
    }
    catch
    {
        HandleError();
        RollBackTransaction();
    }
}

答案 5 :(得分:0)

首先,您应该在程序中使用一个try块和一个catch块来查找和更新产品。

那就是说,你的代码揭示了许多可能的错误。您应该在异常之后使用自定义例外导航程序流程(并非所有异常都应以相同的方式处理)。

这意味着MySqlCommand应该抛出有意义的异常来解释异常是什么,就像命名变量一样。例如,您可以使用ProductNotFoundExceptionUpdateProductException等名称。

你可以这样做,扩展课程Exception

例如,如果您尝试查找产品并且失败,您可以使用相关的“catch”子句并做出相应的反应。如果您尝试更新产品并失败,则可以采取不同的反应。最后,可以使用一般例外(类型为Exception)来发现您没有想到的案例并向您报告。

考虑这个例子:

try{
    // try and find the product
    MySqlCommand.findProduct(serial);
    // if all is well, try and update the product
    // not executed unless findProduct didn't throw an error
    MySqlCommand.updateProduct(serial);
} catch (ProductNotFoundException pnfe){
    // error while finding product
    System.err.println("Product " + serial + " was not found!");
    // .. code to handle product that does not exist
} catch (UpdateProductException upe){
    // error while updating the product
    System.err.println("Product " + serial + " could not be updated!");
    // .. code to handle a failed product update
} catch (Exception e){
    System.err.println("I have no idea why, but something went wrong!");
    e.printStackTrace();
    // handle a general exception
}

MySqlCommand看起来应该更像这样:

public class MySqlCommand {

    public void findProduct(int serial) throws ProductNotFoundException{
        // .. code to find product
    }

    public void updateProduct(int serial) throws UpdateProductException{
        // ... code to update product
    }

}

ProductNotFoundException类(UpdateProductException类似):

public class ProductNotFoundException extends Exception {

    public ProductNotFoundException(String message){
        super(message);
    }
}

我也强烈推荐阅读SQL Injectionhow to prevent it in Java

详细了解exceptions,使用原因及方法。

答案 6 :(得分:0)

在第一个结尾处包含第二个try-catch块。这样第二个块将在第一个成功的情况下执行。

try
{
  //first

  try
  {
    //secodn
  }
  catch
  {
  }

catch
{
}

答案 7 :(得分:0)

我认为您可以定义在每个第一个尝试段中初始化的标志,如果在第一个Catch中弹出了异常,您可以使用值设置该标志(例如,False) 在第二次尝试时,检查此标志是否未设置为异常值(False)

bool foundException = false;
Try
{
    // Reset the variable in the first Try
    foundException = false;
}
Catch(Exception)
{
    foundException = true;
}
End Try

Try
{
    if(foundException)
    {
        break;
    }
}
Catch(Exception)
{

}