c# loop through Access DB - c#

I have folowing code of c# in which I am making connection with access db and and using some conditions.I call a single row from db by using where clause in query.When I Logged into the page it gets data accurately.But after some time when i refresh the page it shows the folowing error
"There is No Row at position 0"
My code is is Bellow
protected void Page_Load(object sender, EventArgs e)
{
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=|DataDirectory|OID.mdb;Persist Security Info=False;");
//OleDbConnection con = new OleDbConnection("Data Source=sml; User ID=sml; Password=sml; provider=OraOLEDB.Oracle");
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = "Select * from EMAILS WHERE EMAIL= '" + GlobalData.Email + "'";
//cmd.CommandText = "Select * from EMAILS";
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
String email = ds.Tables[0].Rows[0][1].ToString();
if (email == GlobalData.Email)
{
Label2.Text = GlobalData.Email;
Label1.Text = GlobalData.Name;
Label3.Text = GlobalData.LastName;
Label1.Visible = false;
Label3.Visible = false;
Label4.Text = Label1.Text + ' ' + Label3.Text;
}
}
I am querying data from DB and using where cluse with Global Variable to retrive a single row
Can Any one Please tell me that how can i Remove this issue or can i loop through the DB that evry time when user login it gets data using loop and then follow the condtion

That means your query is not returning anything and therefore when you call this line:
String email = ds.Tables[0].Rows[0][1].ToString();
You get an exception because there's no Row[0]
If you want to avoid that error do something like:
if (ds.Tables[0].Rows.Count>0)
{
String email = ds.Tables[0].Rows[0][1].ToString();
///...
}
Don't do select * ever in your code. Get used to list the exact columns you want to select from the table. For example:
select email_address from Emails where id= 5
Extra comment: Your query above is kind of pointless; it seems that you are trying to select an email address from a table using the same email address in the where clause. Why do you need to select it from the database if you already know the email? Judging by the variable name (GlobalData.Email) it seems that this is a predefined value...

Related

C# and MySql changing column var

I'm making mysql register/login system in c#. I'm able to register and login with it.
I'm verify account with:
MySqlConnection conn = new MySqlConnection(db_creds);
try { conn.Open(); }
catch { throw new Exception("Can't access database"); }
MySqlDataAdapter adapter;
DataTable table = new DataTable();
string query = "SELECT `Nickname`, `Password` FROM `" + db_table + "` WHERE `Nickname` = '" + nickname + "' AND `Password` = '" + password + "'";
adapter = new MySqlDataAdapter(query, conn);
adapter.Fill(table);
conn.Close();
if(table.Rows.Count <= 0)
{
return false;
}
else { return true; }
After Nickname and Password I have varchar named active. My question is:
How can I change "active" (only for this user) to 1 when user succesfully logged in? and when logoff change it to 0?
To alter a single row in the table, you need to get it's ID(unique identifier for this table). Let the name for this unique column be str_Id, then retrieve this id for the particular user name and password. Then you can update the active state based on this unique identifier.
Another important advise for you is, don't use this type of plain-text queries, which will opens a wide door for SQL Injection. So i strongly recommend you to use parameterized queries as follows;
string query = "SELECT Nickname,str_Id FROM your_table_name" +
" WHERE Nickname =#nickname AND Password = #password";
MySqlConnection con = new MySqlConnection();
// Creating parameterized command
MySqlCommand cmd = new MySqlCommand(query, con);
cmd.Parameters.Add("#nickname", MySqlDbType.VarChar).Value = nickname;
cmd.Parameters.Add("#password", MySqlDbType.VarChar).Value = password;
MySqlDataAdapter adapter = new MySqlDataAdapter(cmd);
DataTable table = new DataTable();
// Collect the details to a DataTable
adapter.Fill(table);
if (table.Rows.Count>0) // Means there is some record found
{
// Get theUnique ID for the matching record
string uniqueId = table.Rows[0]["str_Id"].ToString();
// Update active state for that particular user
query = "Update your_table_name set active='0' Where str_Id=#str_Id";
cmd = new MySqlCommand(query, con);
cmd.Parameters.Add("#str_Id", MySqlDbType.VarChar).Value = uniqueId;
// Execute command here
}
else
{
// Print message thet no user found
}
When you verify if user exists and if password is correct and return message there you need to add update command for your database.
With that update command you need to update column ACTIVE to 1 but to that user, so you need to use this:
UPDATE table_name
SET column1=value1
WHERE some_column=some_value;
So in your case
UPDATE db_table SET active = 1 WHERE nickname = ' + nickname + '
So user now have status of ACTIVE.
Now you need to set it to inactive when he log off, so you do that when he press log off button or when he close the program, but with same principle
UPDATE db_table SET active = 0 WHERE nickname = ' + nickname + '

How to prevent adding same data to SQL from C# program

This is our code to prevent the same data from being added into SQL from our C# program but only the first same data will not be added in. The remaining ones adds the same data into SQL despite our prevention in our C# program. Can somebody help us troubleshoot?
in order not to duplicate data in database usually you set some constraints to your database. By having a unique field in database you can prevent multiple addition to your db.
Currently you are also fetching data from db to check if it exist already and that creates extra cost, just manipulate the design of db so that it won't accept the same column input twice
Count the value of data that is inserted
string constr = ConfigurationManager.ConnectionStrings["connstr"].ToString();
SqlConnection con = new SqlConnection(constr);
string sql1 = "SELECT COUNT (client_id) FROM client WHERE client_id = '" + txtid.Text + "' ";
SqlCommand cmd = new SqlCommand(sql1, con);
con.Open();
int temp = Convert.ToInt32(cmd.ExecuteScalar().ToString());
if (temp >0)
{
//show error message
}
You could check for the record you want to add, and if it doesn't exists, then add it to the table:
SqlConnection _cnt = new SqlConnection();
_cnt.ConnectionString = "Your Connection String";
SqlCommand _cmd = new SqlCommand();
_cmd.Connection = _cnt;
_cmd.CommandType = System.Data.CommandType.Text;
_cmd.CommandText = "SELECT id FROM myTable where Category=#Name";
_cmd.Parameters.Add("#Name", string);
_cmd.Parameters["#Name"].Value = newCatTitle;
_cnt.Open();
var idTemp = _cmd.ExecuteScalar();
_cmd.Dispose();
_cnt.Close();
_cnt.Dispose();
if (idTemp == null)
{
//Insert into table
}
else
{
//Message it already exists
}

Login form for website using web service in asp.net

I am trying to log in to a web service from a website. I have an access database with table USERS (id, user, pass, int admin(1 if it is, 0 if it isn't).
In the web service I have this webmethod:
[WebMethod]
public DataSet login(string u, string p)
{
OleDbConnection CNN = null;
OleDbCommand CMD = null;
string sql = "select * from users where username ='" + u + "' and pass='" + p + "' ";
CNN = new OleDbConnection(conn);
CMD = new OleDbCommand(sql, CNN);
CMD.Connection.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(CMD);
DataSet ds = new DataSet();
adapter.Fill(ds, "logged");
CNN.Close();
return ds;
}
And, in the web site I have this code:
protected void Button1_Click(object sender, EventArgs e)
{
db.Service Login = new db.Service();
Login.login(lUser.Text, lPass.Text);
}
So my question is how can I see if the logged user is admin or no ?
I was thinking somehow to read it from the DataSet ds - since it is filled with all the information that I need, but how to do that ?
Thanks,
dnisko
First of all please avoid passing user typed values to the database directly using sql strings. You are open to SQL Injection attacks and it is error prone as well
//Parametrize your following query.
string sql = "select * from users where username ='" + u + "' and pass='" + p + "' ";
Here is an example on how to parametrize OleDbCommand.
Answer to your question:
Your login() method returns a DataSet object, so you need to assign the return vale of login() method to a DataSet.
db.Service Login = new db.Service();
DataSet ds = Login.login(lUser.Text, lPass.Text);
bool isAdmin = false;
//Check if there is a record for the username and password
if(ds.Tables[0].Rows.Count == 1)
{
//now check if user is an admin or not
isAdmin = Convert.ToBoolean(ds.Tables[0].Rows[0]["admin"]);
if(isAdmin)
{
//User is an admin
}
}else{
//User does not exist in the database
}

loop through all values in sql table using sql data reader

I want to fetch all rows that related to the query below, my problem that only one row retrived not all rows , iam using asp.net with c# and ado.net and my code logic is
if (!IsPostBack)
{
string username = Session["username"].ToString();
con.Open();
string strqryScript = "select * from dbo.teachers where user_id = '" + username + "'";
SqlCommand cmd = new SqlCommand(strqryScript, con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Read();
string name = rdr["teach_id"].ToString();
rdr.Close();
string query = "select * from dbo.teacher_classes where teach_id = '" + name + "' ORDER BY class_id";
SqlCommand cmd2 = new SqlCommand(query, con);
SqlDataAdapter da2 = new SqlDataAdapter(cmd2);
SqlDataReader rdr2 = cmd2.ExecuteReader();
while (rdr2.Read())
{
classname.Text = rdr2["class_id"].ToString();
}
con.Close();
}
extra note that i can use gridview to bind data but i want to fill my table with custom information from many tables , so i want to use an html table and fill it with my custom data. any help please! and thanks ..
While looping on the second reader, you write the value extracted from the reader on the Text property of the classname label. This will overwrite the previous text and leave you with the name of the last teacher retrieved. You need to add to the previous text or use a List.
classname.Text += rdr2["class_id"].ToString();
Said that, let me point you to a big problem in your code. String concatenation is really bad when you build sql commands. It gives you back syntax errors (if your input text contains single quotes) or Sql Injection as explained here
You should use parameterized queries like this (just for your first command)
string strqryScript = "select * from dbo.teachers where user_id = #id";
SqlCommand cmd = new SqlCommand(strqryScript, con);
cmd.Parameters.AddWitValue("#id", username);
....
This is the issue you need to fix:
classname.Text = rdr2["class_id"].ToString(); <== always setting the same text!!
You need to make sure, you fill a list, a dataset or whatever, when reading the data!

What would cause the SelectedValue control not to work?

I am having an issue with the SelectedValue control. I have first created a comboBox, and tied to it is the following method:
private void Form1_Load(object sender, EventArgs e)
{
SqlCeConnection cn = new SqlCeConnection(#"Data Source = \Program Files\ParkSurvey\ParkSurvey.sdf; Persist Security Info = False; Password = *");
cn.Open();
SqlCeCommand cmd = cn.CreateCommand();
cmd.CommandText = "SELECT Name FROM Cities ORDER BY Name ASC";
SqlCeDataAdapter da = new SqlCeDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
cn.Close();
cboCities.ValueMember = "CityId";
cboCities.DisplayMember = "Name";
cboCities.DataSource = ds.Tables[0];
cboCities.SelectedIndex = -1;
}
Assuming this is the only code I have present in my form, the comboBox (cboCities) populates accordingly. My issue arises when I try to fill a second comboBox (cboParks) with the corresponding parks associated with that city. This method looks as follows:
private void cboCities_SelectedIndexChanged(object sender, EventArgs e)
{
if (cboCities.SelectedIndex > -1)
{
SqlCeConnection cn = new SqlCeConnection(#"Data Source = \Program Files\ParkSurvey\ParkSurvey.sdf; Persist Security Info = False; Password = *");
cn.Open();
SqlCeCommand cmd = cn.CreateCommand();
cmd.CommandText = "SELECT Name FROM [Parks] WHERE CityId =" + cboCities.SelectedValue + " ORDER BY Name ASC";
SqlCeDataAdapter da = new SqlCeDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
cn.Close();
cboParks.ValueMember = "ParkId";
cboParks.DisplayMember = "Name";
cboParks.DataSource = ds.Tables[0];
cboParks.SelectedIndex = -1;
}
}
When I load up my Mobile Application, the first comboBox does not populate correctly and is in fact displaying data along the lines of: "System32.Data....", and when selecting any of them, I am brought to the runtime error that states “There was an error parsing the query. [Token line number = 1, Token line offset = 52,Token in error = Data]”. I have been lead to believe the issue itself is from the SELECT statement here:
cmd.CommandText = "SELECT Name FROM [Parks] WHERE CityId =" + cboCities.SelectedValue + " ORDER BY Name ASC";
When I change the cboCities.SelectedValue to cboCities.SelectedItem, the comboBox cboParks populates appropriately minus the filtering (it brings back ALL the data). I can also change it to simply CityId (for testing purposes) and the SELECT statement works.
I have also tried to paramertize it as such, but am brought to an entirely different error: "No mapping exists from DbType System.Data.DataRowView to a known SqlCeType."
cmd.CommandText = "SELECT Name FROM [Parks] WHERE CityId = #CityId ORDER BY Name ASC";
cmd.Parameters.AddWithValue("#CityId", cboCities.SelectedValue);
Basically, what is causing SelectedValue NOT to work and bring back the appropriate CityId ValueMember of the first method? I am pulling my hair out trying to figure this out. Also, if anyone has another method of binding selected data to comboBoxes, then please do share! I'm new to the C# world so any help is much appreciated. Thank you.
As from MSDN,
The SelectedValue return the value of the member of the data source specified by the **ValueMember** property.
You specify as ValueMember the field CityID, but in your query this field is not present.
Therefore the SelectedValue returns the result of the ToString() method of the object.
that happens to be a System.Data.DataRowView.
I think you could resolve your problem simply adding that field to your query
So change your code in this way
using(SqlCeConnection cn = new SqlCeConnection(#"Data Source = \Program Files\ParkSurvey\ParkSurvey.sdf; Persist Security Info = False; Password = *"))
{
cn.Open();
SqlCeCommand cmd = cn.CreateCommand();
cmd.CommandText = "SELECT CityID, Name FROM Cities ORDER BY Name ASC";
SqlCeDataAdapter da = new SqlCeDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
}
....
then you will be able to use parameters on the second query.
Your Select Statement that fills the Combobox is wrong
cmd.CommandText = "SELECT Name FROM Cities ORDER BY Name ASC";
Should be
cmd.CommandText = "SELECT Name, CityID FROM Cities ORDER BY Name ASC";

Categories