data reader has rows but comparison of its values is never true - c#

I am creating a module for booking rooms in hotel.After selecting the rooms, the room numbers appear in a label. On clicking the OK button, the following code executes. When I am checking the availability of rooms, even if it is "No", flag does'nt get initialized to 1. Can anyone guide me where am I going wrong.
protected void ok_room(object sender, EventArgs e)
{
if (Label1.Text != "")
{
int result = 0;
int flag = 0;
string[] room = Label1.Text.Split(new char[] { ' ' });
cmd = new SqlCommand();
cmd1 = new SqlCommand();
cmd1.Connection = con;
cmd.Connection = con;
for (int i = 0; i < room.Length; i++)
{
cmd1.CommandText = "select room_availability from rooms where room_num='" + room[i] + "' ";
dr = cmd1.ExecuteReader();
while (dr.Read())
{
if (dr[0].ToString().Equals("No"))//this is not working
flag = 1;
}
dr.Close();
}
Response.Write(flag);
if (flag == 0)
{
for (int i = 0; i < room.Length; i++)
{
cmd.CommandText = "update rooms set room_availability='No' where room_num='" + room[i] + "'";
cmd.ExecuteNonQuery();
result = 1;
}
}
else
{
Label2.Text = "Some of the selected rooms are not available. Kindly try again";
Label1.Visible=false;
}
if (result == 1)
{
isRoomAvailable = true;
Label2.Text = " Room(s) " + Label1.Text + " is/are booked";
Label1.Visible = false;
}
}
else
Response.Write("<script>alert('Select a room first.')</script>");
}

I would do more of the logic in SQL, this would simplify the code:
// Create a condition looking like this: room_num IN('1', '2', '3')
string roomsCondition = "room_num IN (' + Label1.Text.Replace(" ", "', '") + "')";
cmd1.CommandText =
#"SELECT SUM(CASE WHEN room_availability='Yes' THEN 1 ELSE 0 END) As available,
SUM(CASE WHEN room_availability='No' THEN 1 ELSE 0 END) As not_available
FROM rooms WHERE " + roomsCondition;
This query returns the number of available and non available rooms. It should then be easier to formulate the logic than by the use of flags.
Also have a look at the ExecuteScalar method. It makes it even easier than with the query I have shown above:
using (SqlConnection conn = new SqlConnection(connString)) {
string sql = "SELECT COUNT(*) FROM rooms WHERE room_availability='Yes' AND " +
roomsCondition;
SqlCommand cmd = new SqlCommand(sql, conn);
conn.Open();
int availableRooms = (int)cmd.ExecuteScalar();
if (availableRooms > 0) {
cmd.CommandText =
#"UPDATE rooms
SET room_availability='No'
WHERE availability='Yes' AND " + roomsCondition;
cmd.ExecuteNonQuery();
} else {
...
}
}

Related

Execute Scalar can't return the existing row

I have faced a problem regarding mark duplicate data. In my project, the record which already exists can't be recorded twice. I have followed multiple posts of stackoverflow and come to know that I have to use executescalar to do that.. I have used executescalar but it can't handle the existing data. Would you please help me to sort it out.
Here is my part of code:
{
appointmentdate = dtappointmentdate.Value;
today = DateTime.Now;
String prob = txtproblemdefination.Text;
String rec = "";
if (appointmentdate < today)
{
MessageBox.Show("Please Enter Correct Date.");
}
else
{
SqlCommand check_User_Name = new SqlCommand("SELECT count(*) FROM appointmentTable WHERE PatientName = '" + patientname + "'And (DoctorName = '" + docname + "'And AppointmentDateSet = '" + appointmentdate + "')", sqlCon);
check_User_Name.Parameters.AddWithValue("#patname", patientname);
check_User_Name.Parameters.AddWithValue("#docname", docname);
check_User_Name.Parameters.AddWithValue("#appointmentdate", appointmentdate);
if (sqlCon.State != ConnectionState.Open)
{
sqlCon.Open();
}
int UserExist = (Int32)check_User_Name.ExecuteScalar();
if (UserExist > 0)
{
MessageBox.Show("You can't make appointment twice a day. ");
}
else
{
SqlCommand insertCommand = new SqlCommand("insert into appointmentTable(PatientName,DoctorName,ClinicLocation,AppointmentDateSet,Problem,Recommendation) values(#docname, #patname, #doclocation, #appointmentdate,#prob,#rec)");
insertCommand.Parameters.AddWithValue("#patname", patientname);
insertCommand.Parameters.AddWithValue("#docname", docname);
insertCommand.Parameters.AddWithValue("#doclocation", doclocation);
insertCommand.Parameters.AddWithValue("#appointmentdate", appointmentdate);
insertCommand.Parameters.AddWithValue("#prob", prob);
insertCommand.Parameters.AddWithValue("#rec", rec);
int row = objdbaccess.executeQuery(insertCommand);
if (row == 1)
{
MessageBox.Show("Appointment is Successfully Done.");
}
else
{
MessageBox.Show("Error!Please try again later.");
}
sqlCon.Close();
}
}
You should change your code to:
I am assuming appointmentdate is of type DateTime if not you can choose the correct type from here
using(var check_User_Name= SqlCommand("SELECT count(*) FROM appointmentTable WHERE PatientName = #patname And DoctorName = #docname And AppointmentDateSet = #appointmentdate )", sqlCon)
{
check_User_Name.Parameters.Add("#patname", DbType.String).Value = patientname;
check_User_Name.Parameters.Add("#docname", DbType.String).Value = docname;
check_User_Name.Parameters.Add("#appointmentdate", DbType.DateTime).Value = appointmentdate;
con.Open();
int UserExist = (int)check_User_Name.ExecuteScalar();
// Followed by your code
}

Insert multiple generated value into table

First thing, my question is quite complicated and I am not really proficient to explain it in details, so I would like to say sorry in advance.
Ok, here is the thing. I execute this query
string count = "SELECT Count(*) FROM Student WHERE IntakeID = 'MYVALUE'"
And it would return the number of 10. So I continue with this code:
SqlCommand cmd = new SqlCommand(count, conn);
int temp = Convert.ToInt32(cmd.ExecuteScalar().ToString());
for (int x = 0; x < temp; x++)
{
string query = "INSERT INTO Docket (DocketNo, StudentID) VALUES ('" + getUniqueKey() + "','(SELECT StudentID FROM Student WHERE IntakeID = 'MYVALUE')')
}
PS: getUniqueKey() is a method to get my generated unique key.
Is this piece of code technically correct? The result I want to have is something like below:
+-----------+-------------+
| DocketNo | StudentID |
+-----------+-------------+
| 18590394 | TP123456 |
| 09141563 | TP012457 |
| 58293495 | TP049185 |
+-----------+-------------+
If you are unclear of my question, I will try my best to make it clearer. Sorry for inconvenience.
UPDATE (ANSWER):
With the help from Paparazzi (Thanks!) for his code, I modified and come up with my own solution.
string count = "SELECT StudentID FROM Student WHERE IntakeID = 'MYVALUE'"
SqlCommand cmd = new SqlCommand(count, conn);
string query = "INSERT INTO Docket (DocketNo, StudentID) VALUES ";
conn.Open();
SqlDataReader rdr = cmd.ExecuteReader();
if (rdr.HasRows)
{
var loop = true;
while (loop)
{
loop = rdr.Read();
if (!loop)
{
//When end of rows and no more data to be retrieve, it removes the last "," from the query.
char[] trimChar = { ',' };
string newQuery = query.TrimEnd(trimChar);
cmd.CommandText = newQuery;
}
else {
query += "('" + GetUniqueKey() + "','" + rdr.GetString(0) + "')";
query += ",";
}
}
}
cmd.ExecuteNonQuery();
conn.Close();
So actually while looping on the SqlDataReader, the query would generate in the background something like:
INSERT INTO Docket(DocketNo, StudentID) VALUES ('1562456','TP028800'), ('1465446','TP028801'),..........('4939104','TP028810'),
Take note there will be a "," comma at the end of the query because of the query += ",";. And when the SqlDataReader returns no more rows, it would execute the if(!loop) statement to remove the last "," (comma) from the query.
If you are unclear what is the += for, read more at https://msdn.microsoft.com/en-us/library/sa7629ew.aspx
UPDATE 2:
#Paparazzi has come up with a much more efficient and performance-wise method if you are managing a huge data. Look for his code in his own post. :)
string count = "SELECT StudentID FROM Student WHERE IntakeID = 'MYVALUE'"
SqlCommand cmd = new SqlCommand(count, conn);
string query = "INSERT INTO Docket (DocketNo, StudentID) VALUES ";
conn.Open();
bool first = true;
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
if (first)
first = false;
else
query += ", "
query += "('" + getUniqueKey() + "', '" + rdr.GetString(0) + "')";
}
}
if (!first)
{
cmd.CommandText = query + ";";
cmd.ExecuteNonQuery();
}
conn.Close();
StringBuilder is faster than += on string
And multiple values is limited to 1000 (I think) but WAY more efficient than individual inserts
So if you can get more than 1000 then need to add a counter and fire off the insert
string getID = "SELECT StudentID FROM Student WHERE IntakeID = 'MYVALUE'"
SqlCommand cmd = new SqlCommand(getID , conn);
string insert = "INSERT INTO Docket (DocketNo, StudentID) VALUES ";
Int32 count = 0;
StringBuiler sb = new StringBuiler();
conn.Open();
using (SqlDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
if (count == 0)
{
sb.Clear();
sb.AppendLine(insert);
}
else
sb.Append(", ")
sb.Append("('" + getUniqueKey() + "', '" + rdr.GetString(0) + "')");
count++;
if(count > 800)
{
count = 0;
cmd.CommandText = sb.ToString() + ";";
cmd.ExecuteNonQuery();
// most likely need a separate cmd here has a open reader
// will leave that as an exercise for you
// could even go asynch if you want to get faster
// or you could just build up multiple inserts on sb
}
}
}
if (count > 0)
{
cmd.CommandText = sb.ToString() + ";";
cmd.ExecuteNonQuery();
}
conn.Close();
SqlCommand cmd = new SqlCommand(count, conn);
int temp = Convert.ToInt32(cmd.ExecuteScalar().ToString());
for (int x = 0; x < temp; x++)
{
string query += "INSERT INTO Docket (DocketNo, StudentID) VALUES ('" + getUniqueKey() + "','(SELECT StudentID FROM Student WHERE IntakeID = 'MYVALUE')');";
}
SqlCommand cmd = new SqlCommand(query, conn);
cmd.ExecuteQuery();

Error: object type cannot be compared with an int

This is my table:
roomtype, number of rooms
Ac 10
I want to retrieve the value from the table and subtract the rooms by 1 and update the above table. How do I write the retrieval code in ASP.NET using C#?
This is the updated code. It is showing errors in dt.Rows[0]["no_of_rooms"] > 1 saying that an object type cannot be compared with an int. But on parsing this no_of_rooms to int the error remains the same.
public partial class Book_Room : System.Web.UI.Page
{
protected void Button1_Click(object sender, EventArgs e)
{
string type = DropDownList1.SelectedItem.ToString();
string name = TextBox2.Text;
string nop = DropDownList2.SelectedItem.ToString();
int num = int.Parse(nop);
string connectionString = WebConfigurationManager.ConnectionStrings["HMSConnectionString"].ConnectionString;
SqlConnection connection = new SqlConnection(connectionString);
string qry3 = "select * from availiability where RoomType=#type";
SqlCommand cmd3 = new SqlCommand(qry3, connection);
cmd3.Parameters.AddWithValue("#type", type);
cmd3.ExecuteReader();
SqlDataAdapter ad = new SqlDataAdapter(cmd3);
DataTable dt = new DataTable();
if (dt.Rows.Count > 0)
{
if (dt.Rows[0]["no_of_rooms"] > 1)
{
string qry = "insert into RoomType values('" + type + "','" + name + "','" + num + "') ";
SqlCommand cmd = new SqlCommand(qry, connection);
connection.Open();
int g = cmd.ExecuteNonQuery();
if (g != 0)
Label5.Text = "Reserved for" + name;
connection.Close();
string qry2 = "update availiability set RoomType=#type ,availiable_rooms=#av";
SqlCommand cmd2 = new SqlCommand(qry2, connection);
cmd2.Parameters.AddWithValue("#type", type);
cmd2.Parameters.AddWithValue("#av", dt.Rows[0]["no_of_rooms"] - 1);
connection.Open();
cmd2.ExecuteNonQuery();
connection.Close();
}
}
else
{
label5.Text = "No Rooms Availiable in " + type;
}
}
}
Change it to this (int)dt.Rows[0]["no_of_rooms"] > 1.
Or you can try
dt.Rows[0].Field<int>("no_of_rooms")>1
You are not using any of the other values returned from your query, so creating a SqlDataAdapater and filling a Table is a bit much.
I would recommend using ExecuteScalar instead. This returns a single value from the database.
string qry3 = "select * from availiability where RoomType=#type";
SqlCommand cmd3 = new SqlCommand(qry3, connection);
cmd3.Parameters.AddWithValue("#type", type);
object objCount = command.ExecuteScalar();
int count = objCount == null ? 0 : (int)objCount;
if (count > 0)
{
// Do other things
}

Input string was not in a correct format in Sales Order

I am having this problem
Input string was not in a correct format.
highlighted to the part of:
DisplayOrder(Convert.ToInt16(txtOrderNo.Text));
DisplayOrderDetails(Convert.ToInt16(txtOrderNo.Text));
I am having a hard time figuring out what is the error, can you help me? Thank you very much.
Here is my set codes:
private void displayNavigate()
{
DisplayOrder(Convert.ToInt16(txtOrderNo.Text));
DisplayOrderDetails(Convert.ToInt16(txtOrderNo.Text));
double dTotal = 0;
try
{
for (int nRow = 0; nRow <= grdDetails.Rows.Count - 1; nRow++)
{
dTotal = dTotal + Convert.ToDouble((grdDetails.Rows[nRow].Cells["Amount"].Value.ToString()));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
lblTotal.Text = string.Format("{0:#,##00.00}", dTotal);
}
//================================================================================
//================================================================================
private void DisplayOrder(int nOrderNo)
{
try
{
OpenConnection();
SqlCommand cmdSelect = new SqlCommand();
cmdSelect.Connection = cn;
cmdSelect.CommandType = CommandType.Text;
cmdSelect.Transaction = trnOrder;
cmdSelect.CommandText = "SELECT " +
"B.OrderNo, B.OrderDate, A.CustomerNo, " +
"A.CustomerName, A.CustomerAddress, B.PurchaseOrderNo, B.AgentName, B.Status " +
"FROM Customers AS A, Orders AS B " +
"WHERE A.CustomerNo = B.CustomerNo " +
"AND B.OrderNo ='" + nOrderNo + "'";
SqlDataReader dr = cmdSelect.ExecuteReader(CommandBehavior.CloseConnection);
while (dr.Read())
{
txtOrderNo.Text = dr["OrderNo"].ToString();
dtpOrderDate.Value = Convert.ToDateTime(dr["OrderDate"].ToString());
txtCustomerNo.Text = dr["CustomerNo"].ToString();
txtCustomerName.Text = dr["CustomerName"].ToString();
txtCustomerAddress.Text = dr["CustomerAddress"].ToString();
txtPONo.Text = dr["PurchaseOrderNo"].ToString();
cboAgentName.Text = dr["AgentName"].ToString();
txtOrderStatus.Text = dr["Status"].ToString();
}
dr.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
//================================================================================
//================================================================================
private void DisplayOrderDetails(int nOrderNo)
{
OpenConnection();
SqlCommand cmdSelect = new SqlCommand();
cmdSelect.Connection = cn;
cmdSelect.CommandType = CommandType.Text;
cmdSelect.Transaction = trnOrder;
cmdSelect.CommandText =
"SELECT PackagingOutside, Quantity, Unit, ProductNo, ProductName, ProductSize, PackagingInside, " +
"SellingDiscount, SellingPrice, Amount FROM OrderDetails WHERE OrderNo = '"
+ nOrderNo + "'";
SqlDataAdapter daDetail = new SqlDataAdapter();
daDetail.SelectCommand = cmdSelect;
DataSet ds = new DataSet();
daDetail.Fill(ds, "OrderDetails");
grdDetails.DataSource = null;
grdDetails.DataSource = ds.Tables["OrderDetails"];
}
when you use Convert.ToInt16 you will get this exception if value does not consist of an optional sign followed by a sequence of digits (0 through 9)
Do a validation for inputs before proceed like below.
int orderNo;
if (int.TryParse(txtOrderNo.Text, out orderNo))
{
DisplayOrder(orderNo);
DisplayOrderDetails(orderNo);
}
Side Note :
don't share the SqlConnection create new instant when you need it and wrap it with using block like below
using (SqlConnection con = new SqlConnection(connectionString))
{
}
Use SQL Parameters
cmdSelect.CommandText = "SELECT * FROM Orders WHERE OrderNo = #OrderNo";
cmdSelect.Parameters.AddWithValue("#OrderNo", nOrderNo);
This means that the value in txtOrderNo.Text is not considered an integer. You will get this error if your textbox is empty.
Either check that the textbox contains data, or use the TryParse (http://msdn.microsoft.com/en-us/library/f02979c7.aspx) method
There are two things to consider,
Values entered in the textbox should be an integer in the range of 16 bit, if it can be bigger value, then you have to think of going to long, int32 etc.
Validate the textbox using TryParse() which will tell you whether it has valid value entered.

updating column value in Ms-Access 2010 using c# and oledb query

I am struggling for updating record/columnvalue in MS-ACCESS database... help would be appreciated a lot..!
I am displaying a list of partnumbers retrieved from a table in Ms-access using Datagridview in which I am supposed to update/change partnumber. ( 'partno' is 3rd column of my datagridview.)
But I am unable to Update a single record in database..no exceptions.. everything is going fine.!
But no rows are effected!
Here is my code:
private void UpdateDetails_Click(object sender, EventArgs e)
{
try
{
con = new OleDbConnection();
con.ConnectionString = Helper.MyConnectionString;
con.Open();
for (int i = 0; i <= datagridview1.Rows.Count-1; i++)
{
int j = i + 1; // j is the serial number corresponding to partnumber
string partno = dgv1.Rows[i].Cells[2].Value.ToString(); //getting part number from Datagridview
String partquery = "";
if (partno == null || partno == "") //checking whether part number updated or not
{
partquery = "update Vendor SET PartNo=NULL where Vendor.Sno=" + j + " ";
}
else
partquery = "update Vendor SET PartNo='" + partno + "' where Vendor.Sno=" + j + " ";
//Vendor is the table name containg 'partno' list
cmd = new OleDbCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.CommandText = partquery;
cmd.ExecuteNonQuery();
}
}
catch(Exception ex)
{
//exception handler
}
}
As #Soner suggested you should use parameters. Something like this.
Modified the code did you do something like this?
private void UpdateDetails_Click(object sender, EventArgs e)
{
try
{
con = new OleDbConnection();
con.ConnectionString = Helper.MyConnectionString;
con.Open();
for (int i = 0; i <= datagridview1.Rows.Count - 1; i++)
{
int j = i + 1; // j is the serial number corresponding to partnumber
string partno = dgv1.Rows[i].Cells[2].Value.ToString(); //getting part number from Datagridview
//String partquery = "";
//if (partno == null || partno == "") //checking whether part number updated or not
//{
// partquery = "update Vendor SET PartNo=NULL where Vendor.Sno=" + j + " ";
//}
//else
// partquery = "update Vendor SET PartNo='" + partno + "' where Vendor.Sno=" + j + " ";
OleDbCommand cmd = new System.Data.OleDb.OleDbCommand("update Vendor SET PartNo='#partno' where Vendor.Sno=#vndid");
OleDbParameter parameter = new System.Data.OleDb.OleDbParameter("#partno", partno);
cmd.Parameters.Add(parameter);
parameter = new System.Data.OleDb.OleDbParameter("#vndid", j);
cmd.Parameters.Add(parameter);
cmd.Connection = con;
cmd.CommandType = CommandType.Text;
cmd.ExecuteNonQuery();
}
}
catch (Exception ex)
{
//exception handler
}
}

Categories