在发行一本之前检查 SQL 是否有 Book_Availability (BookAvailability-1)

Check SQL for Book_Availability before issuing one (BookAvailability-1)

如果我输入 "if, foreach, and else statement under comment //",程序会运行并从 SQL 数据库中减少 1 本书的数量。但我想检查是否至少有 1 本书可以赠送。如果我这样离开,这段代码会一直向我显示 "else" 语句中的消息。需要快速帮助,这是我的最终项目,需要在 23.07 之前完成。 :(

            int book_qty = 0;
            SqlCommand cmd2 = connection.CreateCommand();
            cmd2.CommandType = CommandType.Text;
            cmd2.CommandText = "SELECT * FROM Book_list WHERE BookName = '" + TextBoxBookName + "'";
            cmd2.ExecuteNonQuery();
            DataTable dt2 = new DataTable();
            SqlDataAdapter da2 = new SqlDataAdapter(cmd2);
            da2.Fill(dt2);


            foreach (DataRow dr2 in dt2.Rows)
            {
                book_qty = Convert.ToInt32(dr2["book_qty"].ToString());
            }

            if (book_qty > 0)
            {



                SqlCommand cmd = connection.CreateCommand();
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = "INSERT INTO Issue_book VALUES(" + TextBoxSearchMembers.Text + ",'" + TextBoxMemberName.Text + "','" + TextBoxMemberContact.Text + "','" + TextBoxMemberEmail.Text + "','" + TextBoxBookName.Text + "', '" + DateTimePicker1.Text + "')";
                cmd.ExecuteNonQuery();


                SqlCommand cmd1 = connection.CreateCommand();
                cmd1.CommandType = CommandType.Text;
                cmd1.CommandText = "UPDATE Book_list SET BookAvailability = BookAvailability-1 WHERE BookName ='" + TextBoxBookName.Text + "'";
                cmd1.ExecuteNonQuery();


                MessageBox.Show("successful issue");
                this.Close();


            else
            {
                    MessageBox.Show("Book not available");
            }

您只检查结果集中最后一行的 book_qty,而不是检查所有行的 BookAvailability。你可能想做这样的事情:

            SqlCommand cmd2 = connection.CreateCommand();
            cmd2.CommandType = CommandType.Text;
            cmd2.CommandText = "SELECT BookAvailability FROM Book_list WHERE BookName = '" + TextBoxBookName + "'";
            var result = cmd2.ExecuteScalar();
            book_qty = Convert.ToInt32(result);

您需要确保只有一本具有给定书名的书可用。

在那种情况下,只需更正代码中的这一行也会有所帮助:

            book_qty = Convert.ToInt32(dr2["book_qty"].ToString());

            book_qty = Convert.ToInt32(dr2["BookAvailability"].ToString());

否则你需要查询SUM(BookAvailability),但是下面的代码会同时减少多本书的图书数量,这样不太好。

未经测试的代码。我没有你的数据库。在线评论和解释。

private void OPCode()
        {
            try
            {
                //keep your connections close to the vest (local)
                using (SqlConnection connection = new SqlConnection())
                //a using block ensures that your objects are closed and disposed 
                //even if there is an error
                {
                    using (SqlCommand cmd2 = new SqlCommand("SELECT BookAvailability  FROM Book_list WHERE BookName = @BookName", connection))
                    {
                        //Always use parameters to protect from sql injection
                        //Also it is easier than fooling with the single quotes etc.
                        //If you are referring to a TextBox you need to provide what property is
                        //being accessed. I am not in a WPF right now and not sure if .Text
                        //is correct; may be .Content
                        //You need to check your database for correct data type and field size
                        cmd2.Parameters.Add("@BookName", SqlDbType.VarChar, 100).Value = TextBoxBookName.Text;
                        //A select statement is not a non-query
                        //You don't appear to be using the data table or data adapter
                        //so dump them extra objects just slow things dowm
                        connection.Open();
                       //Comment out the next 2 lines and replaced with
                       //Edit Update
                        //var returnVal = cmd2.ExecuteScalar() ?? 0;
                        //if ((int)returnVal > 0)




               //*************************************************************
                            //Edit Update
                            //*************************************************************
                            //in case the query returns a null, normally an integer cannot
                            //hold the value of null so we use nullable types
                            // the (int?) casts the result of the query to Nullable of int
                            Nullable<int> returnVal = (int?)cmd2.ExecuteScalar();
                            //now we can use the .GetValueOrDefault to return the value
                            //if it is not null of the default value of the int (Which is 0)
                            int bookCount = returnVal.GetValueOrDefault();
                            //at this point bookCount should be a real int - no cast necessary
                            if (bookCount > 0)

 //**************************************************************
                           //End Edit Update
                           //**************************************************************
                                {
                                    using (SqlCommand cmd = new SqlCommand("INSERT INTO issue_book VALUES(@SearchMembers etc", connection))
                                    {
                                        //set up the parameters for this command just like the sample above
                                        cmd.Parameters.Add("@SearchMembers", SqlDbType.VarChar, 100).Value = TextBoxSearchMembers.Text;
                                        cmd.ExecuteNonQuery();
                                    }
                                    using (SqlCommand cmd1 = new SqlCommand("UPDATE Book_list SET BookAvailability = BookAvailability-1 WHERE BookName = @BoxBookName;", connection))
                                    {
                                        cmd1.Parameters.Add("@BoxBookName", SqlDbType.VarChar, 100);
                                        cmd1.ExecuteNonQuery();
                                    }
                                    MessageBox.Show("success");
                                    this.Close();
                                }
                                else
                                {
                                    MessageBox.Show("Book not available");
                                }
                            }
                        }
                    }
                    catch (Exception exc)
                    {
                        MessageBox.Show(exc.ToString());
                    }
                }