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

If I put "if, foreach, and else statement under comment //", the program works and Reduces book count by 1 from SQL database. But I want to check IF there is at least 1 available book to give. This code keeps showing me the message in "else" statement if I leave it like this. Help is needed fast, it's my final project, that is needed to be done before 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");
}

You are only checking book_qty from the last row in your result set instead of BookAvailability for all rows. You probably want to do something like:
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);
You need to make sure that there is only one book with the given bookname available.
In that case just correcting this one line in your code would help as well:
book_qty = Convert.ToInt32(dr2["book_qty"].ToString());
to
book_qty = Convert.ToInt32(dr2["BookAvailability"].ToString());
Otherwise you'd need to query SUM(BookAvailability), but the following code would decrease the amount of books for multiple books at once, that wouldn't be good.

Untested code. I don't have your database. Comments and explanation in line.
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());
}
}

Related

Invalid attempt to call read when reader is closed when inserting data

i have a button that when clicked inserts data from textbox and combobox fields into database tables, but every time i insert it gives me "Invalid attempt to call read when reader is closed". How can i get rid of this error. And tips on optimising the code are welcome, because i know im a total noob. thanks
private void btnSave_Click(object sender, RoutedEventArgs e)
{
try
{
SqlConnection sqlCon = new SqlConnection(#"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query1 = "insert into location(Storage, Shelf, columns, rows) values(" + txtWarehouse.Text + ", " + txtShelf.Text + ", " + txtColumn.Text + ", " + txtRow.Text + ")";
SqlCommand sqlCmd = new SqlCommand(Query1, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
sqlCon.Close();
}
catch (Exception er)
{
MessageBox.Show(er.Message);
}
try
{
SqlConnection sqlCon = new SqlConnection(#"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query3 = "SELECT LOCATION_ID FROM LOCATION WHERE storage='" + txtWarehouse.Text + "' AND shelf='" + txtShelf.Text + "' AND columns='"
+ txtColumn.Text + "' AND rows='" + txtRow.Text + "'";
SqlCommand sqlCmd1 = new SqlCommand(Query3, sqlCon);
SqlDataReader dr = sqlCmd1.ExecuteReader(); ;
while (dr.Read())
{
string LocationId = dr[0].ToString();
dr.Close();
string Query2 = "insert into product(SKU, nimetus, minimum, maximum, quantity,location_ID,category_ID,OrderMail_ID) values ('" + txtSku.Text + "','" + txtNimetus.Text + "', '"
+ txtMin.Text + "', '" + txtMax.Text + "', '" + txtQuan.Text + "', '" + LocationId + "', '" + (cbCat.SelectedIndex+1) + "', '" + (cbMail.SelectedIndex+1) + "')";
SqlCommand sqlCmd = new SqlCommand(Query2, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
}
sqlCon.Close();
}
catch (Exception ed)
{
MessageBox.Show(ed.Message);
}
}
Let's try to make some adjustments to your code.
First thing to consider is to use a parameterized query and not a
string concatenation when you build an sql command. This is mandatory
to avoid parsing errors and Sql Injections
Second, you should encapsulate the disposable objects in a using statement
to be sure they receive the proper disposal when you have finished to
use them.
Third, you can get the LOCATION_ID from your table without running a
separate query simply adding SELECT SCOPE_IDENTITY() as second batch to your first command. (This works only if you have declared the LOCATION_ID field in the first table as an IDENTITY column)
Fourth, you put everything in a transaction to avoid problems in case
some of the code fails unexpectedly
So:
SqlTransaction tr = null;
try
{
string cmdText = #"insert into location(Storage, Shelf, columns, rows)
values(#storage,#shelf,#columns,#rows);
select scope_identity()";
using(SqlConnection sqlCon = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(cmdText, sqlCon))
{
sqlCon.Open();
using( tr = sqlCon.BeginTransaction())
{
// Prepare all the parameters required by the command
cmd.Parameters.Add("#storage", SqlDbType.Int).Value = Convert.ToInt32(txtWarehouse.Text);
cmd.Parameters.Add("#shelf", SqlDbType.Int).Value = Convert.ToInt32(txtShelf.Text);
cmd.Parameters.Add("#columns", SqlDbType.Int).Value = Convert.ToInt32(txtColumn.Text );
cmd.Parameters.Add("#rows", SqlDbType.Int).Value = Convert.ToInt32(txtRow.Text);
// Execute the command and get back the result of SCOPE_IDENTITY
int newLocation = Convert.ToInt32(cmd.ExecuteScalar());
// Set the second command text
cmdText = #"insert into product(SKU, nimetus, minimum, maximum, quantity,location_ID,category_ID,OrderMail_ID)
values (#sku, #nimetus,#min,#max,#qty,#locid,#catid,#ordid)";
// Build a new command with the second text
using(SqlCommand cmd1 = new SqlCommand(cmdText, sqlCon))
{
// Inform the new command we are inside a transaction
cmd1.Transaction = tr;
// Add all the required parameters for the second command
cmd1.Parameters.Add("#sku", SqlDbType.NVarChar).Value = txtSku.Text;
cmd1.Parameters.Add("#nimetus",SqlDbType.NVarChar).Value = txtNimetus.Text;
cmd1.Parameters.Add("#locid", SqlDbType.Int).Value = newLocation;
.... and so on for the other parameters required
cmd1.ExecuteNonQuery();
// If we reach this point the everything is allright and
// we can commit the two inserts together
tr.Commit();
}
}
}
}
catch (Exception er)
{
// In case of exceptions do not insert anything...
if(tr != null)
tr.Rollback();
MessageBox.Show(er.Message);
}
Notice that in the first command I use parameters of type SqlDbType.Int because you haven't used single quotes around your text. This should be verified against the real data type of your table columns and adjusted to match the type. This is true as well for the second command where you put everything as text albeit some of those fields seems to be integer (_location_id_ is probably an integer). Please verify against your table.

DataReader exception in C#

Let me first explain my code.
fetch fare for selected destination(reader1)
fetch * for selected user id(reader2)
insert data to process new balance(cmd3)
retrieve new balance as calculated field (reader3)
update travel account (cmd5)
clear calc_tb for next customer input(cmd6)
My problem is while running, I get this error:
There is already an open DataReader associated with this Command which must be closed first.
How can I handle more than one DataReader accessing different tables?
Is DataReader similar to resultset in Java ?
I'm a beginner in coding.
string id,
destin, num;
id = txt_id.Text;
destin = cb_destin.Text;
num = cb_num.Text;
string sql1 = "SELECT fare FROM route_info WHERE route_name='" +destin + "' ";
string sql2 = "SELECT * FROM trav_acc WHERE user_id='" + id + "'";
con.Open();
cmd1 = new SqlCommand(sql1, con);
reader1 = cmd1.ExecuteReader();
while(reader1.Read())
{
string fare = (string)reader1["fare"];
cmd2 = new SqlCommand(sql2, con);
reader2 = cmd2.ExecuteReader();
string cur_bal = (string)reader2["cur_bal"];
reader2.Close();
string calc1 = "INSERT INTO calc_tb VALUES('" + cur_bal + "','" + num + "','" + fare + "')";
string calc2 = "SELECT cur_bal - (nof_tickets * fare) AS new_bal FROM calc_tb";
cmd3 = new SqlCommand(calc1, con);
cmd3.ExecuteNonQuery();
cmd4 = new SqlCommand(calc2, con);
reader3 = cmd4.ExecuteReader();
while(reader3.Read())
{
string new_bal = (string)reader3["new_bal"];
string update = "UPDATE trav_acc SET cur_bal='" + new_bal + "',last_bal='" + cur_bal + "' WHERE user_id='" + id + "' ";
cmd5 = new SqlCommand(update, con);
cmd5.ExecuteNonQuery();
string clear = "DELETE FROM calc_tb";
cmd6 = new SqlCommand(clear, con);
cmd6.ExecuteNonQuery();
}
}
con.Close();
MessageBox.Show("Thank you for using EasyTravel.Come again soon!");
}
It seems that reader3 and cmd4 are defined outside of the code you are showing us, but at least they are defined outside the loop for reader1. So if your reader1 contains more than one row, reader3 and cmd4 will be assigned again, but the "old" reader3 is never closed. Close reader3 when it's finished reading. Or use a using statement, which will take care of the closing automatically.
using (DataReader reader1 = cmd1.ExecuteReader()) {
....
while (reader1.Read()) {
....
using (DataReader reader3 = cmd4.ExecuteReader()) {
while (reader3.Read()) {
}
} //reader3 is closed here automatically
}
} //reader1 is closed here automatically
Furthermore, I'm not sure if I remember correctly, but I think it's not possible to have two open readers on the same connection. I may be wrong with this, though.

The variable name '#VarName' has already been declared Issue

I am inserting multiple items into table based on a selection from drop down list. When I select one item from the drop down then everything works fine but when I select multiple items then I get this error
The variable name '#CompName' has already been declared. Variable names must be unique within a query batch or stored procedure.
what am i doing wrong? thanks
here is my code
protected void DV_Test_ItemInserting(object sender, DetailsViewInsertEventArgs e)
{
foreach (ListItem listItem in cblCustomerList.Items)
{
if (listItem.Selected)
{
string Name= listItem.Value;
sqlcon.Open();
string CompName= ((TextBox)DV_Test.FindControl("txtCompName")).Text.ToString();
string Num = ((TextBox)DV_Test.FindControl("txtNum")).Text.ToString();
SqlCommand cmd = new SqlCommand("select CompNamefrom MyTable where CompName= '" + CompName+ "' and Num = '" + Num + "' and Name= '" + Name+ "' ", sqlcon);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
lblmsg.Text = "Not Valid";
}
else
{
dr.Close();
sqlcmd.CommandText = "INSERT INTO MyTable(CompName, Num, Name) VALUES(#CompName, #Num, #Name)";
sqlcmd.Parameters.Add("#CompName", SqlDbType.VarChar).Value = CompName;
sqlcmd.Parameters.Add("#Num", SqlDbType.VarChar).Value = Num;
sqlcmd.Connection = sqlcon;
sqlcmd.ExecuteNonQuery();
DV_Test.ChangeMode(DetailsViewMode.Insert);
sqlcon.Close();
}
sqlcon.Close();
}
}
}
You are adding the paramters #CompName and #Num to your query every time through the loop.
You need to move the call to Add outside the loop and use the following to update them:
sqlcmd.Parameters["#CompName"].Value = CompName;
sqlcmd.Parameters["#Num"].Value = Num;
So your code becomes:
sqlcmd.CommandText = "INSERT INTO MyTable(CompName, Num, Name) VALUES(#CompName, #Num, #Name)";
sqlcmd.Parameters.Add("#CompName", SqlDbType.VarChar);
sqlcmd.Parameters.Add("#Num", SqlDbType.VarChar);
foreach (ListItem listItem in cblCustomerList.Items)
{
if (....)
{
....
}
else
{
dr.Close();
sqlcmd.Parameters["#CompName"].Value = CompName;
sqlcmd.Parameters["#Num"].Value = Num;
sqlcmd.Connection = sqlcon;
sqlcmd.ExecuteNonQuery();
DV_Test.ChangeMode(DetailsViewMode.Insert);
sqlcon.Close();
}
}
Add sqlcmd.Parameters.Clear(); at the end. This way every parameter will not exist at the end of each loop.
Example:
// ...
sqlcmd.CommandText = "INSERT INTO MyTable(CompName, Num, Name) VALUES(#CompName, #Num, #Name)";
sqlcmd.Parameters.Add("#CompName", SqlDbType.VarChar).Value = CompName;
sqlcmd.Parameters.Add("#Num", SqlDbType.VarChar).Value = Num;
sqlcmd.Connection = sqlcon;
sqlcmd.ExecuteNonQuery();
DV_Test.ChangeMode(DetailsViewMode.Insert);
sqlcon.Close();
sqlcmd.Parameters.Clear();
//...
My assumption here is because you've declared sqlcmd outside of the scope of the loop; so when you iterate over it, you could potentially be adding in the same parameter name multiple times.
And please please please fix this line: SqlCommand cmd = new SqlCommand("select CompNamefrom MyTable where CompName= '" + CompName+ "' and Num = '" + Num + "' and Name= '" + Name+ "' ", sqlcon); as it's SQL injection waiting to happen.
Just add this:
SqlCmd.Parameters.Clear();
in your code, before parameter adding. It will clear already added parameters list and consider your parameters as new.

How to run multiple SQL commands in a single SQL connection?

I am creating a project in which I need to run 2-3 SQL commands in a single SQL connection.
Here is the code I have written:
SqlConnection con = new SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\project.mdf;Integrated Security=True");
con.Open();
SqlCommand cmd = new SqlCommand("select * from " + mytags.Text + " ", con);
SqlDataReader rd = cmd.ExecuteReader();
if (rd.Read())
{
con.Close();
con.Open();
SqlCommand cmd1 = new SqlCommand("insert into " + mytags.Text + " values ('fname.lname#gmail.com','" + TextBox3.Text + "','" + TextBox4.Text + "','" + TextBox5.Text + "','"+mytags.Text+"')", con);
cmd1.ExecuteNonQuery();
label.Visible = true;
label.Text = "Date read and inserted";
}
else
{
con.Close();
con.Open();
SqlCommand cmd2 = new SqlCommand("create table " + mytags.Text + " ( session VARCHAR(MAX) , Price int , Description VARCHAR(MAX), Date VARCHAR(20),tag VARCHAR(10))", con);
cmd2.ExecuteNonQuery();
con.Close();
con.Open();
SqlCommand cmd3 = new SqlCommand("insert into " + mytags.Text + " values ('" + Session + "','" + TextBox3.Text + "','" + TextBox4.Text + "','" + TextBox5.Text + "','" + mytags.Text + "')", con);
cmd3.ExecuteNonQuery();
label.Visible = true;
label.Text = "tabel created";
con.Close();
}
I have tried to remove the error and I got that the connection is not going to else condition. Please review the code and suggest if there is any mistake or any other solution for this.
Just change the SqlCommand.CommandText instead of creating a new SqlCommand every time. There is no need to close and reopen the connection.
// Create the first command and execute
var command = new SqlCommand("<SQL Command>", myConnection);
var reader = command.ExecuteReader();
// Change the SQL Command and execute
command.CommandText = "<New SQL Command>";
command.ExecuteNonQuery();
The following should work. Keep single connection open all time, and just create new commands and execute them.
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (SqlCommand command1 = new SqlCommand(commandText1, connection))
{
}
using (SqlCommand command2 = new SqlCommand(commandText2, connection))
{
}
// etc
}
Just enable this property in your connection string:
sqb.MultipleActiveResultSets = true;
This property allows one open connection for multiple datareaders.
I have not tested , but what the main idea is: put semicolon on each query.
SqlConnection connection = new SqlConnection();
SqlCommand command = new SqlCommand();
connection.ConnectionString = connectionString; // put your connection string
command.CommandText = #"
update table
set somecol = somevalue;
insert into someTable values(1,'test');";
command.CommandType = CommandType.Text;
command.Connection = connection;
try
{
connection.Open();
}
finally
{
command.Dispose();
connection.Dispose();
}
Update:
you can follow
Is it possible to have multiple SQL instructions in a ADO.NET Command.CommandText property? too
This is likely to be attacked via SQL injection by the way. It'd be worth while reading up on that and adjusting your queries accordingly.
Maybe look at even creating a stored proc for this and using something like sp_executesql which can provide some protection against this when dynamic sql is a requirement (ie. unknown table names etc). For more info, check out this link.
No one has mentioned this, but you can also separate your commands using a ; semicolon in the same CommandText:
using (SqlConnection conn = new SqlConnection(connString))
{
using (SqlCommand comm = new SqlCommand())
{
comm.Connection = conn;
comm.CommandText = #"update table ... where myparam=#myparam1 ; " +
"update table ... where myparam=#myparam2 ";
comm.Parameters.AddWithValue("#myparam1", myparam1);
comm.Parameters.AddWithValue("#myparam2", myparam2);
conn.Open();
comm.ExecuteNonQuery();
}
}
Multiple Non-query example if anyone is interested.
using (OdbcConnection DbConnection = new OdbcConnection("ConnectionString"))
{
DbConnection.Open();
using (OdbcCommand DbCommand = DbConnection.CreateCommand())
{
DbCommand.CommandText = "INSERT...";
DbCommand.Parameters.Add("#Name", OdbcType.Text, 20).Value = "name";
DbCommand.ExecuteNonQuery();
DbCommand.Parameters.Clear();
DbCommand.Parameters.Add("#Name", OdbcType.Text, 20).Value = "name2";
DbCommand.ExecuteNonQuery();
}
}
Here you can find Postgre example, this code run multiple sql commands (update 2 columns) within single SQL connection
public static class SQLTest
{
public static void NpgsqlCommand()
{
using (NpgsqlConnection connection = new NpgsqlConnection("Server = ; Port = ; User Id = ; " + "Password = ; Database = ;"))
{
NpgsqlCommand command1 = new NpgsqlCommand("update xy set xw = 'a' WHERE aa='bb'", connection);
NpgsqlCommand command2 = new NpgsqlCommand("update xy set xw = 'b' where bb = 'cc'", connection);
command1.Connection.Open();
command1.ExecuteNonQuery();
command2.ExecuteNonQuery();
command2.Connection.Close();
}
}
}
using (var connection = new SqlConnection("Enter Your Connection String"))
{
connection.Open();
using (var command = connection.CreateCommand())
{
command.CommandText = "Enter the First Command Here";
command.ExecuteNonQuery();
command.CommandText = "Enter Second Comand Here";
command.ExecuteNonQuery();
//Similarly You can Add Multiple
}
}
It worked for me.

Need help with database connection and query code

In my code below, the cmdquery works but the hrquery does not. How do I get another query to populate a grid view? Do I need to establish a new connection or use the same connection? Can you guys help me? I'm new to C# and asp. Here's some spaghetti code I put together. It may all be wrong so if you have a better way of doing this feel free to share.
if (Badge != String.Empty)
{
string cmdquery = "SELECT * from Employees WHERE Badge ='" + Badge + "'";
string hrquery = "SELECT CLOCK_IN_TIME, CLOCK_OUT_TIME FROM CLOCK_HISTORY WHERE Badge ='" + Badge + "'";
OracleCommand cmd = new OracleCommand(cmdquery);
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
conn.Open();
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
this.xUserNameLabel.Text += reader["EMPLOYEE_NAME"];
this.xDepartmentLabel.Text += reader["REPORT_DEPARTMENT"];
}
OracleCommand Hr = new OracleCommand(hrquery);
Hr.Connection = conn;
Hr.CommandType = CommandType.Text;
OracleDataReader read = Hr.ExecuteReader();
while (read.Read())
{
xHoursGridView.DataSource = hrquery;
xHoursGridView.DataBind();
}
}
conn.Close();
Your data access code should generally look like this:
string sql = "SELECT * FROM Employee e INNER JOIN Clock_History c ON c.Badge = e.Badge WHERE e.Badge = #BadgeID";
using (var cn = new OracleConnection("your connection string here"))
using (var cmd = new OracleCommand(sql, cn))
{
cmd.Parameters.Add("#BadgeID", OracleDbType.Int).Value = Badge;
cn.Open();
xHoursGridView.DataSource = cmd.ExecuteReader();
xHoursGridView.DataBind();
}
Note that this is just the general template. You'll want to tweak it some for your exact needs. The important things to take from this are the using blocks to properly create and dispose your connection object and the parameter to protect against sql injection.
As for the connection question, there are exceptions but you can typically only use a connection for one active result set at a time. So you could reuse your same conn object from your original code, but only after you've completely finished with it from the previous command. It is also okay to open up two connections if you need them. The best option, though, is to combine related queries into single sql statement when possible.
I'm not even going to get into how you should be using usings and methods :p
if (Badge != String.Empty)
{
string cmdquery = "SELECT * from Employees WHERE Badge ='" + Badge + "'";
string hrquery = "SELECT CLOCK_IN_TIME, CLOCK_OUT_TIME FROM CLOCK_HISTORY WHERE Badge ='" + Badge + "'";
OracleCommand cmd = new OracleCommand(cmdquery);
cmd.Connection = conn;
cmd.CommandType = CommandType.Text;
conn.Open();
OracleDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
this.xUserNameLabel.Text += reader["EMPLOYEE_NAME"];
this.xDepartmentLabel.Text += reader["REPORT_DEPARTMENT"];
}
OracleCommand Hr = new OracleCommand(hrquery);
Hr.Connection = conn;
Hr.CommandType = CommandType.Text;
OracleDataReader read = Hr.ExecuteReader();
//What's this next line? Setting the datasource automatically
// moves through the data.
//while (read.Read())
//{
//I changed this to "read", which is the
//datareader you just created.
xHoursGridView.DataSource = read;
xHoursGridView.DataBind();
//}
}
conn.Close();

Categories