I have a ListView. It has 6 columns:
question_id | question_text | start_time | end_time | status | repeat
respectively. Right now I am able to display the data from the database. This is my code:
private void Voting_Editor_Tool_Load(object sender, EventArgs e)
{
GetData();
}
public void GetData()
{
try
{
now = DateTime.Now;
String time_date = now.ToString();
myConnection = new SqlConnection(#"User ID=sa;Password=password123;Initial Catalog=dishtv;Persist Security Info=True;Data Source=ENMEDIA-EA6278E\ENMEDIA");
//myConnection.Open();
//SqlDataReader dr = new SqlCommand("SELECT question_text,question_id FROM otvtbl_question ", myConnection).ExecuteReader();
// listView1.Columns.Clear();
listView1.Items.Clear();
myConnection.Open();
String MyString1 = string.Format("SELECT question_id,question_text,start_time,end_time,status,repeat FROM otvtbl_question");
com = myConnection.CreateCommand();
com.CommandText = MyString1;
dr = com.ExecuteReader();
ListViewItem itmX;
//Adding the Items To The Each Column
while (dr.Read())
{
itmX = new ListViewItem();
itmX.Text = dr.GetValue(0).ToString();
var word = itmX.Text;
for (int i = 1; i < 6; i++)
{
itmX.SubItems.Add(dr.GetValue(i).ToString());
}
if (dr.GetDateTime(2) < now && dr.GetDateTime(3) > now)
{
itmX.SubItems[4].Text = "Broadcasting";
}
else if (dr.GetDateTime(3) < now)
{
string a=Convert.toString(dr.GetDateTime(3));
itmX.SubItems[4].Text = "Expired";
String broadcast = string.Format("UPDATE otvtbl_question SET status='EXPIRED' where start_time='{6}'",a );
//Execute the SqlCommand
com = new SqlCommand(broadcast, myConnection);
com.ExecuteNonQuery();
}
else
{
itmX.SubItems[4].Text = "Not Expired";
}
listView1.Items.Add(itmX);
}
dr.Close();
myConnection.Close();
}
catch (Exception ex)
{
//Error Message While Fetching
MessageBox.Show("Error While Fetching the data From the DataBase" + ex);
}
finally
{
//Closing The Connection
if (dr != null)
dr.Close();
if (myConnection.State == ConnectionState.Open)
myConnection.Close();
}
}
In this code the status column has to be updated every time the user load the form. While the form is loading it has to check the whether the start_time is greater than current time. If it is greater than the status column has to display NOT EXPIRED otherwise it has to show EXPIRED. The problem is that I am able to show the EXPIRED and NOT EXPIRED values in Status column by comparing the time, but I want to save the EXPIRED and NOT EXPIRED values in the database while it shows the values in the status column. I have tried to update it using following command:
String broadcast = string.Format("UPDATE otvtbl_question SET status='EXPIRED' where start_time='{6}'",a );
//Execute the SqlCommand
com = new SqlCommand(broadcast, myConnection);
com.ExecuteNonQuery();
But it says:
DataReader has to be closed before Updating the data.
I even tried to close the datareader and tried to update and it says different errors as:
Index (zero based) must be greater than or equal to zero and less than size of the argument list
Any suggestions?
You should implement the using statement. This will resolve the issue. Following are the blocks where the using statement should be implemented.
Sql Connection
DataReader
Moreover we should use parameterized queries. Below is the sample code.
using (System.Data.SqlClient.SqlConnection con = new SqlConnection("YourConnection string")) {
con.Open();
SqlCommand cmd = new SqlCommand();
string expression = "Parameter value";
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Your Stored Procedure";
cmd.Parameters.Add("Your Parameter Name",
SqlDbType.VarChar).Value = expression;
cmd.Connection = con;
using (IDataReader dr = cmd.ExecuteReader())
{
if (dr.Read())
{
}
}
}
Here is the IDisposable example as requested by you.
IDisposable
Related
I have a code that I use to login.
I call the data I get from textbox with a method and check the records with select query in the
database.
I call to relevant method , when I press the button.
private void btnGiris_Click(object sender, EventArgs e)
{
LoginBilgiler lb = new LoginBilgiler();
bool sonuc = lb.GirisKontrol(txtAd.Text, txtSifre.Text);
}
But I encounter errors in cmd.ExecuteReader the below.
public bool GirisKontrol(string ad,string sifre)
{
using (OracleConnection con = new OracleConnection(connectionString))
{
string query = String.Format("SELECT count(*) from Z_LABEL_USER where USERNAME=({0}) and PASSWORD=({1})", ad,sifre);
OracleCommand cmd = new OracleCommand(query, con);
con.Open();
OracleDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
kAdi = ad;
con.Close();
return true;
}
else
con.Close();
return false;
}
}
The table I use for the select query.
Oracle.ManagedDataAccess.Client.OracleException: 'ORA-01722: invalid
number'
Please, don't hardcode parameters in SQL; parametrize it instead:
public bool GirisKontrol(string ad, string sifre) {
//DONE: validate public methods' input
if (string.IsNullOrEmpty(ad))
return false; // or throw exception
else if (string.IsNullOrEmpty(sifre))
return false; // or throw exception
using (OracleConnection con = new OracleConnection(connectionString)) {
con.Open();
//DONE: no need to count all the entires, just check if there's at least one
//DONE: keep query readable
//DONE: paramterize queries
string query =
#"select 1
from Z_LABEL_USER
where USERNAME = :prm_UserName
and PASSWORD = :prm_Password";
using (OracleCommand cmd = new OracleCommand(query, con)) {
//TODO: this syntax can vary from library to library you use to work with Oracle
cmd.Parameters.Add(":prm_UserName", OracleType.VarChar).Value = ad;
cmd.Parameters.Add(":prm_Password", OracleType.VarChar).Value = sifre;
using (OracleDataReader dr = cmd.ExecuteReader()) {
if (dr.Read()) {
//TODO: Side effect : it changes instance's state. Do you really want it?
kAdi = ad;
return true;
}
}
}
}
return false;
}
I've been trying to create a function that will set up an order for all the items that are lacking in my inventory.
RequiredStockForAllOrders basically assigns a value to each object in stockItems which lets me know how many items I need to order.
I checked with a messagebox which does the change in values (both ID and quantity) but when I run the loop that is supposed to insert each product with its respective quantity I only insert 1 product n times where n is the amount of items in the list.
private void AddAllRequiredItems_Click(object sender, EventArgs e)
{
var stockItems = new List<MyData>();
//MyData is an object with a productID int and a productQuantity int
RequiredStockForAllOrders(stockItems);
//determining the quantity required for each item
OleDbConnection con = new OleDbConnection(DatabaseConnectionString);
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = con;
con.Open();
string sql2 = "INSERT INTO restockingDetails(RestockingID,ProductID,Quantity,Shop_ID) values (#restockingID,#productID,#quantity,#shop_id)";
cmd.CommandText = sql2;
int i = 0;
while (i < stockItems.Count)
{
try
{
MessageBox.Show(stockItems[i].productId.ToString()); //For testing
cmd.Parameters.AddWithValue("#restockingID", restockingOrder);
cmd.Parameters.AddWithValue("#productID", stockItems[i].productId);
cmd.Parameters.AddWithValue("#quantity", stockItems[i].productQuantity);
cmd.Parameters.AddWithValue("#shop_id", shopIDGlobal);
cmd.ExecuteNonQuery();
MessageBox.Show(" Item added to list"); //for testing
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
i = i + 1;
}
con.Close()
}
Just add this line before adding the parameters
MessageBox.Show(stockItems[i].productId.ToString()); //For testing
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#restockingID", restockingOrder);
You actual code continues to add parameters to the command collection, but the query uses only the first four. With other providers this code will result in an error (too many parameters) but OleDb is somebit limited in this point. Probably because it doesn't recognize parameters by their name, but by their position
A better approach could be to define the parameters just once and then updating their values inside the loop
private void AddAllRequiredItems_Click(object sender, EventArgs e)
{
var stockItems = new List<MyData>();
RequiredStockForAllOrders(stockItems);
string sql2 = "INSERT INTO restockingDetails(RestockingID,ProductID,Quantity,Shop_ID) values (#restockingID,#productID,#quantity,#shop_id)";
using(OleDbConnection con = new OleDbConnection(DatabaseConnectionString))
using(OleDbCommand cmd = new OleDbCommand(sql2, con))
{
con.Open();
cmd.Parameters.Add("#restockingID", OleDbType.Integer);
cmd.Parameters.Add("#productID", OleDbType.Integer);
cmd.Parameters.Add("#quantity", OleDbType.Integer);
cmd.Parameters.Add("#shop_id", OleDbType.Integer);
foreach(MyData item in stockItems)
{
try
{
cmd.Parameters["#restockingID"].Value = restockingOrder;
cmd.Parameters["#productID"].Value = item.productId;
cmd.Parameters["#quantity"].Value = item.productQuantity;
cmd.Parameters["#shop_id"].Value = shopIDGlobal;
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
create the command into the while loop :
OleDbConnection con = new OleDbConnection(DatabaseConnectionString);
OleDbCommand cmd;
string sql2 = "INSERT INTO restockingDetails(RestockingID,ProductID,Quantity,Shop_ID) values (#restockingID,#productID,#quantity,#shop_id)";
int i = 0;
while (i < stockItems.Count)
{
try
{
MessageBox.Show(stockItems[i].productId.ToString()); //For testing
cmd = new OleDbCommand();
cmd.Connection = con;
con.Open();
cmd.CommandText = sql2;
cmd.Parameters.AddWithValue("#restockingID", restockingOrder);
cmd.Parameters.AddWithValue("#productID", stockItems[i].productId);
cmd.Parameters.AddWithValue("#quantity", stockItems[i].productQuantity);
cmd.Parameters.AddWithValue("#shop_id", shopIDGlobal);
cmd.ExecuteNonQuery();
MessageBox.Show(" Item added to list"); //for testing
con.Close()
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
i = i + 1;
}
I have a textbox which will take the input from user and search whether the inserted data is available in SQL database table or not. If the data is in table then it will update two column(time_out and day_out) of the same row.
Or else it will show an error message. This code below is not working. Please help.
try
{
SqlConnection con3 = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=db-ub;Integrated Security=True");
con3.Open();
SqlCommand cmd2 = new SqlCommand(#"SELECT Count(*) FROM Visitors WHERE Id=#id",con3);
cmd2.Parameters.AddWithValue("#id", textBox_VIex.Text);
SqlCommand cmd3 = new SqlCommand("UPDATE Visitors SET Day_Out=#dO,Time_Out=#tO WHERE Id=#id", con3);
cmd3.Parameters.AddWithValue("#id", 1);
cmd3.Parameters.AddWithValue("#dO", DateTime.Now);
cmd3.Parameters.AddWithValue("#tO", DateTime.Now);
int o = cmd3.ExecuteNonQuery();
MessageBox.Show("Good Bye!");
this.Close();
FormCheck f2 = new FormCheck();
f2.Show();
}
catch
{
MessageBox.Show("Error!");
textBox_VIex.Clear();
}
Please refer to my changes to your code,
int o = cmd3.ExecuteNonQuery();
Returns the count of number of rows affected by the Query. If it is zero it means that id was not in the database.
try
{
SqlConnection con3 = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=db-ub;Integrated Security=True");
con3.Open();
SqlCommand cmd2 = new SqlCommand(#"SELECT Count(*) FROM Visitors WHERE Id=#id",con3);
cmd2.Parameters.AddWithValue("#id", textBox_VIex.Text);
SqlCommand cmd3 = new SqlCommand("UPDATE Visitors SET Day_Out=#dO,Time_Out=#tO WHERE Id=#id", con3);
cmd3.Parameters.AddWithValue("#id", int.Parse(textBox_VIex.Text));
cmd3.Parameters.AddWithValue("#dO", DateTime.Now);
cmd3.Parameters.AddWithValue("#tO", DateTime.Now);
int o = cmd3.ExecuteNonQuery();
if(o > 0)
MessageBox.Show("Good Bye!");
else
MessageBox.Show("Error!");
this.Close();
FormCheck f2 = new FormCheck();
f2.Show();
}
catch
{
MessageBox.Show("Error!");
textBox_VIex.Clear();
}
Look into comments in code.
First, this is good way to deal with connection, etc
int? result = null; // note nullable int
try
{
Using (SqlConnection con = New SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=db-ub;Integrated Security=True"))
{
con.Open();
// You don't really care to check up front if the record with id=xx exists because
// if it doesn't, you get 0 records updated
// unless you do something with the result of that query
Using (SqlCommandcmd As New SqlCommand("UPDATE Visitors SET Day_Out=#dO,Time_Out=#tO WHERE Id=#id", con))
{
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("#id", 1); // <<-- Are you always passing "1"?????
cmd.Parameters.AddWithValue("#dO", DateTime.Now);
cmd.Parameters.AddWithValue("#tO", DateTime.Now);
result = cmd.ExecuteNonQuery();
}
con.Close()
}
}
catch
{
// optionally, log error or show error msg in second msgBox below. Save it to a variable here
}
// Separate query and result processing
// Check the result. If result is still null, your query failed. If not 0 - you updated your records
if (result != null && (int)result > 0)
{
MessageBox.Show("Updated record OK");
}
else
{
if (result == null)
{
MessageBox.Show("The construct failed"); // optionally add error msg here
}
else
{
MessageBox.Show("The record I was looking for is not in DB");
}
}
// I don't know what you do with your form logic
this.Close();
I am trying to change password option with ms access database....
please help me folks....
here the code:
default.aspx.cs
protected void Button1_Click(object sender, EventArgs e)
{
try
{
OleDbConnection myCon = new OleDbConnection(ConfigurationManager.ConnectionStrings["vhgroupconnection"].ConnectionString);
myCon.Open();
string userid = txtuserid.Text;
string oldpass = txtoldpass.Text;
string newPass = txtnewpass.Text;
string conPass = txtconfirmpass.Text;
string q = "select user_id,passwd from register where user_id = #userid and passwd = #oldpass";
OleDbCommand cmd = new OleDbCommand(q, myCon);
OleDbDataReader reader = new OleDbDataReader();
cmd.Parameters.AddWithValue("#userid", txtuserid.Text);
cmd.Parameters.AddWithValue("#oldpass", txtoldpass.Text);
reader = cmd.ExecuteReader();
reader.Read();
if (reader["user_id"].ToString() != String.Empty && reader["passwd"].ToString() != String.Empty)
{
if (newPass.Trim() != conPass.Trim())
{
lblmsg.Text = "New Password and old password does not match";
}
else
{
q = "UPDATE register SET passwd = #newPass WHERE user_id =#userid";
cmd = new OleDbCommand(q, myCon);
cmd.Parameters.AddWithValue("#newPasss", txtnewpass.Text);
cmd.Parameters.AddWithValue("#userod", txtuserid.Text);
cmd.Parameters.AddWithValue("#passwd", txtoldpass.Text);
int count = cmd.ExecuteNonQuery();
if (count > 0)
{
lblmsg.Text = "Password changed successfully";
}
else
{
lblmsg.Text = "password not changed";
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
also check pls.....
Compilation Error Description: An error occurred during the
compilation of a resource required to service this request. Please
review the following specific error details and modify your source
code appropriately.
Compiler Error Message: CS0143: The type
'System.Data.OleDb.OleDbDataReader' has no constructors defined
Source Error:
Line 36: OleDbCommand cmd = new OleDbCommand(q, myCon);
Line 37:
Line 38: OleDbDataReader reader = new OleDbDataReader();
Line 39:
Line 40:
As error message says; OleDbDataReader has no constructor.
From documentation of OleDbDataReader;
To create an OleDbDataReader, you must call the ExecuteReader method
of the OleDbCommand object, instead of directly using a constructor.
You can use ExecuteReader method that returns OleDbDataReader
OleDbDataReader dr = cmd.ExecuteReader();
And you need add your parameter values before you call ExecuteReader method.
Also use using statement to dispose your OleDbConnection, OleDbCommand and OleDbDataReader like;
using(OleDbConnection myCon = new OleDbConnection(conString))
using(OleDbCommand cmd = myCon.CreateCommand())
{
//Define your sql query and add your parameter values.
using(OleDbDataReader dr = cmd.ExecuteReader())
{
//
}
}
And as Steve mentioned, OleDbDataReader.Read method returns boolean value (true of false) and it reads your OleDbDataReader results row by row. You might need to consider to use the result of this method like in a while statement. For example;
while(reader.Read())
{
//Reads your results until the last row..
}
As a final words, I strongly suspect you store your passwords as plain text. Don't do that! Use SHA-512 hash.
As MSDN clearly states, To create an OleDbDataReader, you must call the ExecuteReader method of the OleDbCommand object, instead of directly using a constructor.
You cannot instantiate it using new, which is what you are doing and which is why you get the error. Remove the offending line and change it to this to get rid of the error:
OleDbDataReader reader = cmd.ExecuteReader();
Also, remember to use using blocks to ensure resources get properly disposed.
using(OleDbConnection myCon = new OleDbConnection(ConfigurationManager.ConnectionStrings["vhgroupconnection"].ConnectionString))
{
OleDbCommand cmd = new OleDbCommand(q, myCon);
//Add parameters etc
OleDbDataReader reader = cmd.ExecuteReader();
//Rest of the processing
}
Problem: You try to make new instance of OleDbDataReader by calling new OleDbDataReader() instead you should create a reader using OleDbCommand.ExecuteReader().
In the following code notice use of using statement (this should ensure connection closing or reader closing for the case of OleDbDataReader).
protected void Button1_Click(object sender, EventArgs e)
{
try
{
string sConnString = ConfigurationManager.ConnectionStrings["vhgroupconnection"].ConnectionString;
using(OleDbConnection myCon = new OleDbConnection(sConnString))
{
myCon.Open();
string userid = txtuserid.Text;
string oldpass = txtoldpass.Text;
string newPass = txtnewpass.Text;
string conPass = txtconfirmpass.Text;
string q = "select user_id,passwd from register where user_id = #userid and passwd = #oldpass";
OleDbCommand cmd = new OleDbCommand(q, myCon);
cmd.Parameters.AddWithValue("#userid", txtuserid.Text);
cmd.Parameters.AddWithValue("#oldpass", txtoldpass.Text);
string sUserId = string.Empty;
string sPass = string.Empty;
using(OleDbDataReader reader = cmd.ExecuteReader())
{
if(reader.Read()) //assumption: one record returned
{
sUserId = reader["user_id"].ToString();
sPass = reader["passwd"].ToString();
}
}
if (sUserId != string.Empty && sPass != string.Empty)
{
if (newPass.Trim() != conPass.Trim())
lblmsg.Text = "New Password and old password does not match";
else
{
q = "UPDATE register SET passwd = #newPass WHERE user_id =#userid";
cmd = new OleDbCommand(q, myCon);
cmd.Parameters.AddWithValue("#newPass", txtnewpass.Text);
cmd.Parameters.AddWithValue("#userid", txtuserid.Text);
int count = cmd.ExecuteNonQuery();
if (count > 0)
lblmsg.Text = "Password changed successfully";
else
lblmsg.Text = "password not changed";
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
I am trying to use a SqlDataReader to run a query and then display the results in a messagebox, but I keep getting the error
Invalid attempt to read when no data is present.
Here is my code.
public void button1_Click(object sender, EventArgs e)
{
string results = "";
using (SqlConnection cs = new SqlConnection(#"Server=100-nurex-x-001.acds.net;Database=Report;User Id=reports;Password=mypassword"))
{
cs.Open();
string query = "select stationipaddress from station where stationname = #name";
using (SqlCommand cmd = new SqlCommand(query, cs))
{
// Add the parameter and set its value --
cmd.Parameters.AddWithValue("#name", textBox1.Text);
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
label3.Text = dr.GetSqlValue(0).ToString();
results = dr.GetValue(0).ToString();
//MessageBox.Show(dr.GetValue(0).ToString());
//MessageBox.Show(results);
}
MessageBox.Show(results);
}
}
}
}
That's correct.
When you exit from the while loop the DataReader has reached the end of the loaded data and thus cannot be used to get the value of a non-existant current record.
The Read method advances the SqlDataReader (dr) to the next record and it returns true if there are more rows, otherwise false.
If you have only one record you could use the results variable in this way
MessageBox.Show(results);
Now, this will work because you have a TOP 1 in your sql statement, but, if you have more than one record, it will show only the value of the last record.
Also as noted by marc_s in its comment, if your table is empty, your code doesn't fall inside the while loop, so probably you could initialize the results variable with a message like:
results = "No data found";
EDIT: Seeing your comment below then you should change your code in this way
.....
// Use parameters **ALWAYS** -- **NEVER** cancatenate/substitute strings
string query = "select stationipaddress from station where stationname = #name";
using (SqlCommand cmd = new SqlCommand(query, cs))
{
// Add the parameter and set its value --
cmd.Parameters.AddWithValue("#name", textBox1.Text);
using (SqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
label3.Text = dr.GetSqlValue(0).ToString();
results = dr.GetValue(0).ToString();
}
}
}
.....
I ran into a similar issue trying to get a GUID I knew was there - I could run the same SQL directly in SQL Management Studio and get my result. So instead of trying to bring it back as a GUID (it was saved in a char(35) field, even though it really was a GUID!), I brought it back as a string, instead:
SqlConnection sqlConn = null;
string projId = String.Empty;
string queryString = "SELECT * FROM project WHERE project_name='My Project'";
try
{
sqlConn = new SqlConnection(connString);
SqlCommand cmd = new SqlCommand(queryString, sqlConn);
sqlConn.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
projId = reader.GetSqlValue(0).ToString(); // <-- safest way I found to get the first column's parameter -- increment the index if it is another column in your result
}
}
reader.Close();
sqlConn.Close();
return projId;
}
catch (SqlException ex)
{
// handle error
return projId;
}
catch (Exception ex)
{
// handle error
return projId;
}
finally
{
sqlConn.Close();
}