ExecuteNonQuery需要一个打开的可用连接.连接的当前状态为关闭

本文关键字:连接 状态 一个 ExecuteNonQuery | 更新日期: 2023-09-27 17:57:33

我想检查发票表中的发票编号是否不存在,然后添加新的发票编号并在发票详细信息表中填写发票详细信息,否则,如果发票表中存在,我只想更新合计字段,以防发票有多个项目,在类中:

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();
}
}

ExecuteNonQuery需要一个打开的可用连接.连接的当前状态为关闭

我想我应该把它作为一个答案发布。。。

你没有打开你的连接,简单明了。

而不是。。。

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.
    }
}

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

您可以使用myCommand对象在顶部执行此操作:myCommand.Connection.Open();

但是,对于名为"ad"的OleDbDataAdapter对象,即使指定了连接字符串,也必须显式打开连接。

我刚刚访问了微软的页面,了解您正在使用的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 server的连接,而且这些语句的数量有限。我见过一些应用程序通过创建并未能在短时间内关闭太多连接来破坏服务器。

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

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