【问题标题】:Insert/Update in asp.net and SQL SERVER 2008在 asp.net 和 SQL SERVER 2008 中插入/更新
【发布时间】:2016-10-09 18:27:03
【问题描述】:

如果请求的prodName 在数据库中不存在,我正在尝试插入一条记录。如果存在,我想更新 quantity 属性的值。我使用了以下它既不插入也不更新任何记录。我得到以下异常:

ExecuteScalar requires an open and available Connection. The connection's current state is closed

这是代码

public static void manageStock(CompanyStock stock)
    {
        ///// Check if record exists/////////
        cmd = new SqlCommand("select count(*) from tblStock where prodName=@prodName", con);
        cmd.Parameters.AddWithValue("@prodName", stock.prodName);
        con.Open();
        Int32 count = (Int32)cmd.ExecuteScalar(); //returns null if doesnt exist
        con.Close();

        if (count > 0)
        {
            cmd = new SqlCommand("update tblStock set quantity = @quantity where prodName=@prodName", con);
            cmd.Parameters.AddWithValue("@prodName", stock.prodName);
            cmd.Parameters.AddWithValue("@quantity", stock.quantity);
        }
        else
        {
            cmd = new SqlCommand("insert into tblStock(prodName,quantity) values (@prodName, @quantity)", con);
            cmd.Parameters.AddWithValue("@prodName",stock.prodName);
            cmd.Parameters.AddWithValue("@quantity",stock.quantity);
        }

        try
        {
            con.Open();
            cmd.ExecuteNonQuery();
        }

        finally
        {
            con.Close();
        }
    }
}

已编辑 我编辑了我的代码。它现在工作正常。在执行ExecuteScalar 之前,我必须打开我的连接,但我想知道编写这个打开和关闭内容的标准方式。看起来有点随意。我该如何改进?

【问题讨论】:

  • 我相信您需要在执行第一个命令对象之前打开连接。我不确定你的代码是如何执行的。如果这确实是代码,它将始终执行 INSERT into tblStock 命令。
  • 你的代码有什么问题是你没有处理你的异常,所以你看不到可能告诉你问题到底是什么的错误消息。
  • @Pleun 如果没有catch,他们不会冒泡吗?虽然听起来堆栈中可能还有其他东西正在吞噬某处。
  • 编辑了我的问题。请再看一遍

标签: c# asp.net sql-server insert-update


【解决方案1】:

您可以使用 Convert.ToInt32() 方法将结果转换为整数值。

如果值为null,则将其转换为0。

试试这个:

int count = Convert.ToInt32(cmd.ExecuteScalar());

【讨论】:

    【解决方案2】:

    考虑在 sql-server 中使用 MERGE 子句。这是一个很好的Microsoft article,您可以使用。

    【讨论】:

      【解决方案3】:

      单步执行代码时它会做什么?

      在某些 SQL 排序规则(例如,Latin1_General_BIN)中,变量区分大小写。在您的第一个 select 语句中,您的查询中有 @ProdName,参数集合中有 @prodName。如果您有区分大小写的排序规则,那么您永远不会超过这一部分。在 Management Studio 中右键单击数据库,然后单击“属性”以查找排序规则。

      【讨论】:

      • 在重新阅读您的编辑后,在您的 SELECT 行上,您为其提供了 con 连接,但我没有看到它已打开。
      • 我打开了它。问题现在解决了,但看起来并不整洁。请检查
      • 这就是它的工作方式。也许考虑写一个数据库包装器stackoverflow.com/questions/3553846/…
      【解决方案4】:

      错误说没有连接。你可以先检查一下这个问题吗

      检查连接,如果不为空并且此时存在,请检查它 con.State = Open 或任何其他值。我的连接状态是关闭打开它。但首先连接声明在哪里?我在您的代码中没有看到它。

      试试这个:

      //USING THE STATEMNET USING IT WILL TAKE CARE TO DISPOSE CONNECTION AND PLACE TRY CATCH WITHIN PROCS
      
      {
      using (SqlConnection cnn = new SqlConnection(ConfigurationManager.AppSettings("connectionString"))) {
          if (cnn.State == System.Data.ConnectionState.Closed)
              cnn.Open();
          using (SqlCommand cmd = new SqlCommand()) {
              try {
                  cmd.Connection = cnn;
                  cmd.CommandText = "YOUR SQL STATEMENT";
                  int I = Convert.ToInt32(cmd.ExecuteNonQuery);
      
                  if (I > 0)
                  {
                      cmd.CommandText = "YOUR SQL STATEMENT";
                  //ADDITIONAL PARAMTERES
                  } 
                  else
                  {
                      cmd.CommandText = "YOUR SQL STATEMENT";
                      //ADDITIONAL PARAMETERS
                  }
                  cmd.ExecuteNonQuery();
                  } 
                    catch (Exception ex) 
                  {
                  Response.Write(ex.Message);
                  }
              }
          }
      }
      

      【讨论】:

      • 看看我的解决方案,它更简单、更安全。永远不要离开连接打开记住:)。如果它符合您的目标,请将此作为答案
      【解决方案5】:

      你可以试试这个代码。先写一个存储过程:

      CREATE PROCEDURE sprocquanupdateinsert
          @prodName nvarchar(250),
          @quantity int
      AS
      BEGIN
          UPDATE tblStock 
          SET quantity = @quantity 
          WHERE prodName = @prodName
      
          IF @@ROWCOUNT = 0
              INSERT INTO tblStock(prodName, quantity) 
              VALUES (@prodName, @quantity)
      END
      GO
      

      然后在后面的代码中你可以使用这个

      using (conn)
      {
          SqlCommand cmd = new SqlCommand("sprocquanupdateinsert", conn);
          cmd.CommandType = CommandType.StoredProcedure;
      
          cmd.Parameters.AddWithValue("@prodName", stock.prodName);
          cmd.Parameters.AddWithValue("@quantity", stock.quantity);
      
          conn.Open();
          cmd.ExecuteNonQuery();
          conn.Close();
      }
      

      【讨论】:

        猜你喜欢
        • 2013-06-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多