ExecuteNonQuery需要一个开放的可用连接。连接的当前状态已关闭

时间:2015-06-21 02:06:52

标签: c# .net ado.net

我想检查发票表中的发票编号是否存在,然后在invoicedetails表中添加新的发票编号和填写发票详细信息,否则如果发票表中存在,只是我想更新总计字段,以防万一发票有多个项目, 在课堂上:

StockClass stk = new StockClass();

stk.Quantity = txtQuantity.Text;
stk.StockID = txtStockID.Text;
stk.QtyUpdate();
MessageBox.Show("Stock record has been Successfully updated ");

InvoiceClass invclass = new InvoiceClass();

try
{
OleDbConnection myConnection = default(OleDbConnection);
myConnection = new OleDbConnection(cs);

OleDbCommand myCommand = default(OleDbCommand);

myCommand = new OleDbCommand("SELECT InvoiceNo FROM Invoices WHERE InvoiceNo = @InvoiceNo", myConnection);
OleDbParameter invono = new OleDbParameter("@username", OleDbType.VarChar);
invono.Value = txtInvoiceNo.Text;
myCommand.Parameters.Add(invono);


myCommand.Connection.Open();

OleDbDataReader myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

if (myReader.Read() == true)
{
invclass.InvoiceNo = txtInvoiceNo.Text;
invclass.Total = txtGrandTotal.Text;
invclass.Date = InvDate.Text;

invclass.updateinvoNumber();
}
else
{
invclass.InvoiceNo = txtInvoiceNo.Text;
invclass.Total = txtGrandTotal.Text;
invclass.Date = InvDate.Text;

invclass.AddNewinvoNumber();

invclass.InvoiceID = txtInvoiceNo.Text;
invclass.ProductID = txtProdID.Text;
invclass.ProName = txtProdName.Text;
invclass.ProType = txtProdType.Text;
invclass.ProSize = txtProdSize.Text;
invclass.Quantity = textQty.Text;
invclass.UnitPrice = txtPrice.Text;
invclass.Total = textTotal.Text;
invclass.Date = InvDate.Text;
invclass.CustName = txtCustName.Text;
invclass.EmpName = txtEmpName.Text;

invclass.AddNew();
}
if (myConnection.State == ConnectionState.Open)
{
myConnection.Dispose();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}


OleDbDataAdapter ad = new OleDbDataAdapter("Select ProName, ProType, ProSize, Quantity, UnitPrice, Total, CustName, EmpName, date From InvoiceDetails WHERE [InvoiceID] = ?", cs);

ad.SelectCommand.Parameters.Add("@InvoiceID", OleDbType.VarChar);
ad.SelectCommand.Parameters["@InvoiceID"].Value = txtInvoiceNo.Text;

DataSet ds = new DataSet();
ad.Fill(ds, "Invo");
DGV1.DataSource = ds.Tables["Invo"];
DGV1.DataSource = ds.Tables[0];
}

当它不存在时它运作良好,但当它存在时我面临错误

  

ExecuteNonQuery需要一个开放的可用连接。连接的当前状态已关闭

public void updateinvoNumber()
{
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|StoreSys.mdb"))
using (OleDbCommand cmd = new OleDbCommand("UPDATE [invoices] SET [InvoiceNo]=?, [Total] = ?,[Date] = ? WHERE [InvoiceNo] = ?", conn))
{
cmd.Parameters.AddWithValue("p0", InvoiceNo);
cmd.Parameters.AddWithValue("p1", Total);
cmd.Parameters.AddWithValue("p2", Date);



cmd.ExecuteNonQuery();
conn.Close();
}
}

2 个答案:

答案 0 :(得分:4)

我想我应该发布这个作为答案......

你没有打开你的联系,简单明了。

而不是......

using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|StoreSys.mdb"))
using (OleDbCommand cmd = new OleDbCommand("UPDATE [invoices] SET [InvoiceNo]=?, [Total] = ?,[Date] = ? WHERE [InvoiceNo] = ?", conn))
{
    cmd.Parameters.AddWithValue("p0", InvoiceNo);
    cmd.Parameters.AddWithValue("p1", Total);
    cmd.Parameters.AddWithValue("p2", Date);

    cmd.ExecuteNonQuery();
    conn.Close();
}

你需要......(注意conn.Open();

using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|StoreSys.mdb"))
{
    conn.Open(); // <-- You forgot this.
    using (OleDbCommand cmd = new OleDbCommand("UPDATE [invoices] SET [InvoiceNo]=?, [Total] = ?,[Date] = ? WHERE [InvoiceNo] = ?", conn))
    {
        cmd.Parameters.AddWithValue("p0", InvoiceNo);
        cmd.Parameters.AddWithValue("p1", Total);
        cmd.Parameters.AddWithValue("p2", Date);

        cmd.ExecuteNonQuery();
        // conn.Close(); <-- you don't need this btw. This will happen automatically as you exit the "using" block.
    }
}

答案 1 :(得分:4)

好的,我看到了问题。错误消息中完美地描述了该问题:您没有打开连接。

您可以使用myCommand对象进行操作:myCommand.Connection.Open();

但是,对于名为“ad”的OleDbDataAdapter对象,即使您指定了连接字符串,也必须明确打开连接。

我刚刚访问了Microsofts页面,找到了您正在使用的OleDbDataAdapter构造函数重载(有两个字符串的那个)位于https://msdn.microsoft.com/en-us/library/2f8y4737.aspx,并且在备注部分有这样的说法。

  

OleDbDataAdapter构造函数的这个重载使用selectConnectionString参数来设置SelectCommand属性。 但是,它不会打开连接。您仍然必须明确打开连接。

查看您的代码,我相信您可以做的最小改变就是添加代码:

ad.SelectCommand.Connection.Open();

在设置SqlParameters和填充DataSet之间:

ad.SelectCommand.Parameters["@InvoiceID"].Value = txtInvoiceNo.Text;

**ad.SelectCommand.Connection.Open();** // <- HERE

DataSet ds = new DataSet();
ad.Fill(ds, "Invo");

但是,我并不是100%确定它会如图所示,因为我从未以这种方式打开连接,我通常会显式创建一个连接对象,并在设置命令之前打开它。此外,您将要使用'using'语句来确保数据库连接被关闭和处理,否则您将与SQL服务器保持打开连接,并且只有有限数量的连接。我见过通过在短时间内创建并且无法关闭太多连接而使服务器受损的应用程序。

因此,如果代码ad.SelectCommand.Connection.Open();不起作用,请尝试像上面那样显式创建连接对象,然后您可以设置连接对象与其构造函数中的OleDbDataAdapter相关联以代替连接字符串: / p>

using(OleDbConnection myConnection2 = new OleDbConnection(cs))
{
    myConnection2.Open();

    using(OleDbDataAdapter ad = new OleDbDataAdapter(/*truncated*/, myConnection2))
    {
        [...]