C# how to get two column values by ID from a datatable - c#

I don't have much knowledge about databases and SQL, so I am trying to get help here, I know this should be basic knowledge though, but as a newbie I am not sure where to start.
I am having a problem figuring out how to get a specific value from datatable, I already have the ID in form2 using this code:
cmd = new SqlCommand("select UserID from Users where UserName='" + textBox1.Text + "' and UserPassword='" + textBox2.Text + "'", cn);
object result = cmd.ExecuteScalar();
if (result != null)
{
loginresult = 1;
LoginUserID = Convert.ToInt32(result);
AdminRights = ???; //how can I get this value from datatable?
UserRights = ???; //how can I get this value from datatable?
this.Close();
}
Now in form1, I want to get the value of AdminRights or UserRights by ID, I have this code,:
private void button7_Click(object sender, EventArgs e) // Button to Form2
{
Form2 win_form2 = new Form2();
win_form2.ShowDialog();
if (win_form2.loginresult == 1)
{
label4.Text = string.Format("User ID: {0}", win_form2.LoginUserID.ToString()); // Gets and places specific user ID
if (win_form2.UserRights = 0 && win_form2.AdminRights = 1) // Check if the ID has AdminRights
label5.text = string.Format("Rights: {0}", "Admin") // If true, do the following
else if (win_form2.UserRights = 1 && win_form2.AdminRights = 0) // Check if the ID has UserRights
label5.text = string.Format("Rights: {0}", "User") // If true, do the following
}
}
My datatable:
UserID (PK 1,1)
UserName (string)
UserPassword (string)
AdminRights (int) (value could be 0 or 1, and can't be the same value as UserRights)
UserRights (int) (value could be 0 or 1, and can't be the same value as AdminRights)
So at the end, how can I access to the datatable and get UserRights and AdminRights values in form2?
NOTE: I understand that I have very dangerous code regarding passwords and SQL injection, for now I only want it to work.

You can access columns by name as you can see below, use schema or use i.e. data tables (but be aware that you should use command parameters and do not put any values in your query directly from user input)
using (SqlConnection connection = new SqlConnection(
connectionString))
{
connection.Open();
SqlCommand command = new SqlCommand($"SELECT * FROM TABLE_NAME WHERE UserID = {your_user_id}", connection);
SqlDataReader reader = command.ExecuteReader();
while (_reader.Read())
{
// get the results of each column
var adminRights = reader["AdminRights "] as string;
var userRights = reader["AdminRights "] as string;
}
}
// usage with parameters
SqlCommand command = new SqlCommand("SELECT * FROM TABLE_NAME WHERE UserID =#user", sql);
command.Parameters.AddWithValue("#user", your_user_id);

You can access SQl columns directly using the below example.
Example:
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand("Select ....", con)) //Your SQL Query here
{
con.Open();
cmd.ExecuteNonQuery();
SqlDataReader dr = cmd.ExecuteReader();
if (dr != null)
{
while (dr.Read())
{
employee.AdminRights = dr["AdminRights"].ToString(); //This basically reads the SQL column into an "active reader"
employee.UserRights = dr["UserRights"].ToString();
}
}
}
con.Close();
}
Another way is perhaps to use variables in SQL and add them as parameters in Windows Forms. Read this answer
cmd.Parameters.Add(new SqlParameter("#AdminUser", empInfo.AdminUser));
cmd.Parameters.Add(new SqlParameter("#UserRights", empInfo.UserRights));

Related

Updating records in SQL Server database using ASP.NET

I am new to ASP.NET, I am facing some difficulty in updating records inside database in ASP.NET. My code is showing no errors, but still the records are not being updated. I am using SQL Server 2012.
Code behind is as follows:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["user"] != null)
{
con.Open();
string query = "Select * from Customers where UserName ='" + Session["user"] + "'";
SqlCommand cmd = new SqlCommand(query, con);
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
txt_name.Text = reader["CustName"].ToString();
txt_phonenumber.Text = reader["Contact"].ToString();
txt_address.Text = reader["CustAddress"].ToString();
txt_cardnum.Text = reader["CustAccountNo"].ToString();
txt_city.Text = reader["CustCity"].ToString();
txt_emailaddress.Text = reader["Email"].ToString();
txt_postalcode.Text = reader["CustPOBox"].ToString();
Cnic.Text = reader["CustCNIC"].ToString();
}
con.Close();
}
else
{
Response.Redirect("Login.aspx");
}
}
protected void BtnSubmit_Click(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd2 = con.CreateCommand();
SqlCommand cmd1 = con.CreateCommand();
cmd1.CommandType = CommandType.Text;
cmd1.CommandText = "Select CustID from Customers where UserName = '" + Session["user"] + "'";
int id = Convert.ToInt32(cmd1.ExecuteScalar());
cmd2.CommandType = CommandType.Text;
cmd2.CommandText = "update Customers set CustName='" + txt_name.Text + "',CustCNIC='" + Cnic.Text + "',Email='" + txt_emailaddress.Text + "',CustAccountNo='" + txt_cardnum.Text + "',CustAddress='" + txt_address.Text + "',CustPOBox='" + txt_postalcode.Text + "' where CustID='" + id + "'";
cmd2.ExecuteNonQuery();
con.Close();
}
Help will be much appreciated. THANKS!
After debugging the result i am getting is this
cmd2.CommandText "update Customers set CustName='Umer Farooq',CustCNIC='42101555555555',Email='adada#gmail.com',CustAccountNo='0',CustAddress='',CustPOBox='0' where CustID='6'" string
Here Account Number And POBOX is 0 and address is going as empty string. But i have filled the text fields
First thing to do to fix this is to use good ADO techniques, using SqlParameters for the passed in values; and not the risky SQL Injection method of concatenating strings together.
This first portion does just that. I have added in the int sqlRA variable to read the results of the non-query, which will return Rows Affected by the query. This is wrapped in a simple try...catch routine to set the value to negative 1 on any error. Other error handling is up to you. That makes your code look something like this:
cmd1.Parameters.AddWithValue("#SessionUser", Session["User"]);
int id = Convert.ToInt32(cmd1.ExecuteScalar());
cmd2.CommandType = CommandType.Text;
cmd2.CommandText = "UPDATE Customers SET CustName = #CustName, CustCNIC = #CustCNIC, Email = #Email, CustAccountNo = #CustAccountNo, CustAddress = #CustAddress, CustPOBox = #CustPOBox WHERE (CustID = #CustID)";
cmd2.Parameters.AddWithValue("#CustName", txt_name.Text);
cmd2.Parameters.AddWithValue("#CustCNIC", Cnic.Text);
cmd2.Parameters.AddWithValue("#Email", txt_emailaddress.Text);
cmd2.Parameters.AddWithValue("#CustAccountNo", txt_cardnum.Text);
cmd2.Parameters.AddWithValue("#CustAddress", txt_address.Text);
cmd2.Parameters.AddWithValue("#CustPOBox", txt_postalcode.Text);
cmd2.Parameters.AddWithValue("#CustID", id);
int sqlRA
try { sqlRA = cmd2.ExecuteNonQuery(); }
catch (Exception ex) {
sqlRA = -1;
// your error handling
}
/* sqlRA values explained
-1 : Error occurred
0 : Record not found
1 : 1 Record updated
>1 :Multiple records updated
*/
Now reading through your code, all we are doing with the first query is mapping the Session["User"] to id, and then using that id in the second query to do the update, and that Username is not updated in the second. Waste of a query most likely, as we could use the Session["User"] to do the update. That will bring you down to this query, and still bring back that Rows Affected value back:
cmd0.CommandType = CommandType.Text;
cmd0.CommandText = "UPDATE Customers SET CustName = #CustName, CustCNIC = #CustCNIC, Email = #Email, CustAccountNo = #CustAccountNo, CustAddress = #CustAddress, CustPOBox = #CustPOBox WHERE (UserName = #SessionUser)";
cmd0.Parameters.AddWithValue("#CustName", txt_name.Text);
cmd0.Parameters.AddWithValue("#CustCNIC", Cnic.Text);
cmd0.Parameters.AddWithValue("#Email", txt_emailaddress.Text);
cmd0.Parameters.AddWithValue("#CustAccountNo", txt_cardnum.Text);
cmd0.Parameters.AddWithValue("#CustAddress", txt_address.Text);
cmd0.Parameters.AddWithValue("#CustPOBox", txt_postalcode.Text);
cmd0.Parameters.AddWithValue("#SessionUser", Session["User"]);
int sqlRA
try { sqlRA = cmd0.ExecuteNonQuery(); }
catch (Exception ex) {
sqlRA = -1;
// your error handling
}
/* sqlRA values explained
-1 : Error occurred
0 : Record not found
1 : 1 Record updated
>1 :Multiple records updated
*/
When BtnSubmit fires the event, the code in the Page_Load runs before the codes in BtnSubmit, replacing the values placed in the TextBox with the values from the Database before the Update takes place.

getting "No value given for one or more required parameters."

I have created a registration page and linked it to Access database now I'm trying to use the information stored on the Db to use on login page but keep getting this "No value given for one or more required parameters." error.
protected void loginButtn_Click(object sender, EventArgs e)
{
string connect = #"Provider=Microsoft.Jet.OleDb.4.0;Data Source=C:\Users\Wisal\Documents\Visual Studio 2012\WebSites\WebSite3\registration-Db.mdb";
string query = "Select Count(*) From client Where [name] = ? And surname = ? and [password] = ?";
int result = 1;
using (OleDbConnection conn = new OleDbConnection(connect))
{
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.AddWithValue("", nameloginBox.Text);
cmd.Parameters.AddWithValue(" ", snameloginBox.Text);
cmd.Parameters.AddWithValue(" ", passwrdloginBox.Text);
conn.Open();
Session["User"] = nameloginBox.Text;
result = (int)cmd.ExecuteScalar();
}
}
if (result > 0)
{
Response.Redirect("general.aspx");
}
else
{
Literal1.Text = "Invalid credentials";
}
}
As #Rob commented (beat me to it), you are passing 3 parameters with no name. Your code should look something like this, so Access knows what parameters correspond to what variable.
string query = "Select Count(*) From client Where Username = ? And UserPassword = ?";
int result = 1;
using (OleDbConnection conn = new OleDbConnection(connect))
{
using (OleDbCommand cmd = new OleDbCommand(query, conn))
{
cmd.Parameters.AddWithValue("Username", snameloginBox.Text); //username parameter
cmd.Parameters.AddWithValue("UserPassword", passwrdloginBox.Text); //userpassword parameter
conn.Open();
Session["User"] = nameloginBox.Text;
result = (int)cmd.ExecuteScalar();
}
}
For further information about passing parameters to Access queries, please reed here.

Delete & Update query doesn't work in ADO.NET

I am trying to DELETE a record of Access Database using OleDbCommand class of Connected Architecture
using System.Data.OleDb;
using System.Data;
protected void Button2_Click(object sender, EventArgs e)
{
String x = "Connection String...";
OleDbConnection con = new OleDbConnection(x);
con.Open();
String query = "Delete FROM TB WHERE NO=#number";
OleDbCommand cmd = new OleDbCommand(query, con);
cmd.Parameters.AddWithValue("#number", TextBox2.Text);
int res = cmd.ExecuteNonQuery();
if (res > 0)
{
Label.Text = "Deleted successfully";
}
else
{
Label.Text = "Not Deleted";
}
con.Close();
}
Every time I try deleting record Else Condition is executed which is NOT DELETED.
Same problem with UPDATE query,
protected void Button3_Click(object sender, EventArgs e)
{
String x = "Connection String..";
OleDbConnection con = new OleDbConnection(x);
con.Open();
String query = "UPDATE TB SET NM = #name WHERE NO = #TextBox_NO";
OleDbCommand cmd = new OleDbCommand(query, con);
int res = cmd.ExecuteNonQuery();
if (res > 0)
{
Label.Text = "Updated successfully";
}
else
{
Label.Text = "Not Updated";
}
con.Close();
}
INSERT query works perfectly fine.
Where am I doing wrong?
Preface: I know nothing of ASP.NET but I do know MS Access. And NO is a reserved word. Hence, if reserved words are used may result in unexpected answers or errors when referenced as fields.
To resolve, consider bracketing the NO column in both delete and update queries.
String query = "DELETE FROM TB WHERE [NO] = #number"
String query = "UPDATE TB SET NM = #name WHERE [NO] = #TextBox_NO"
I can confirm this solution as I just tested a NO vs [NO] column reference in a SQL query in MS Access 2013. The former returned zero records but latter returned correct records.
i think there is any datatype conversion error, that's why it's not deleting, and for the update case you just missed the parameter to pass #name,#TextBox_No
See here Why to use Add()
You need to change parameter passing method AddedWithValue() to Add()
Delete:
String query = "Delete FROM TB WHERE NO=#number";
OleDbCommand cmd = new OleDbCommand(query, con);
cmd.Parameters.Add("#number", OleDbType.Numeric, 30).Value=TextBox2.Text;
int res = cmd.ExecuteNonQuery();
if (res > 0)
{
Label.Text = "Deleted successfully";
}
else
{
Label.Text = "Not Deleted";
}
con.Close();
and for Update u missed the parameter to pass:
String x = "Connection String..";
OleDbConnection con = new OleDbConnection(x);
con.Open();
String query = "UPDATE TB SET NM = #name WHERE NO = #TextBox_NO";
OleDbCommand cmd = new OleDbCommand(query, con);
cmd.Parameters.Add("#name ", OleDbType.VarChar, 200).Value=your_Name_Variable;//
cmd.Parameters.Add("#TextBox_NO", OleDbType.Numeric, 30).Value=Your_No_Variable;
int res = cmd.ExecuteNonQuery();
if (res > 0)
{
Label.Text = "Updated successfully";
}
else
{
Label.Text = "Not Updated";
}
con.Close();
If it's not deleting any record that means int res = cmd.ExecuteNonQuery(); is returning 0 or no records deleted. Make sure that the condition in your WHERE clause WHERE NO=#number matches any record. To validate run a select along the line with the same condition
SELECT 1 FROM TB WHERE NO=#number
Also, try trimming the textbox data before punching as parameter like
cmd.Parameters.AddWithValue("#number", TextBox2.Text.Trim());
If NO is of type INT then covert it to integer before passing as parameter like
cmd.Parameters.AddWithValue("#number", Convert.ToInt32(TextBox2.Text.Trim()));
You can follow the same rules for your UPDATE case as well. Also, I don't see you are passing any parameter for your UPDATE query. Did you just skipped that in posted code?
String query = "UPDATE TB SET NM = #name WHERE NO = #TextBox_NO";
OleDbCommand cmd = new OleDbCommand(query, con);

How to show SQL query result in a Textbox?

I have the following code:
dbConnection cn = new dbConnection();
SqlCommand cmd = new SqlCommand();
protected void dropdown_student_SelectedIndexChanged(object sender, EventArgs e)
{
string StudentGUID = dropdown_student.SelectedValue;
cn.con.Open();
cn.cmd.Connection = cn.con;
cn.cmd.CommandText = "select SUM(Marks) AS 'Total' from Marksheet where StudentGUID = " + StudentGUID + " ";
dr = cn.cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
textbox_total.Text = dr["Total"].ToString();
}
cn.con.Close();
}
}
I want to show the total marks value in the textbox but it does not work. Can anyone point me in the right direction?
Try something like this:
// define your query upfront - using a PARAMETER!
string query = "SELECT SUM(Marks) FROM dbo.Marksheet WHERE StudentGUID = #StudentID;";
// put the SqlConnection and SqlCommand into using blocks
using (dbConnection cn = new dbConnection())
using (SqlCommand cmd = new SqlCommand(query, cn))
{
// define the parameter value
cmd.Parameters.Add("#StudentID", SqlDbType.UniqueIdentifier).Value = dropdown_student.SelectedValue;
cn.Open();
// use ExecuteScalar if you fetch one row, one column exactly
object result = cmd.ExecuteScalar();
cn.Close();
if(result != null)
{
int value = (int)result;
textbox_total.Text = value.ToString();
}
}
You SQL query is wrong. Try like below:
string query = string.Format("SELECT SUM(Marks) FROM dbo.Marksheet WHERE StudentGUID = '{0}';", StudentID);
Always try to follow this kind of standard practice and you will never fail.
Try putting single Quote around the GUID variable in SQL query.
cn.cmd.CommandText = "select SUM(Marks) AS 'Total' from Marksheet where StudentGUID = '" + StudentGUID + " '";

C# Check if value is returned from database

SqlCeConnection sqlCnn = new SqlCeConnection("Data Source=" + Application.StartupPath + "\\mainDB.sdf");
SqlCeCommand sqlCmd = new SqlCeCommand("SELECT * FROM Accounts WHERE (username = #user AND password = #pass)", sqlCnn);
sqlCmd.Parameters.Add("#user", textBox1.Text);
sqlCmd.Parameters.Add("#pass", textBox2.Text);
sqlCnn.Open();
SqlCeDataReader reader = sqlCmd.ExecuteReader();
while (reader.Read())
{
// Some code ...
}
I have this code that reads some values from a database but I want to check if any value is returned from the database. I want to check if the username and password from the database is equal to textBox1 and textBox2 and if not, return a failure message.
Simply use the code like this:
if(reader.Read()){
//your code
}else {
//Show message notifying failure
}
//remember to close your reader
reader.Close(); //or use using statement for convenience.
However DataReader is used mainly for reading a set of data (just 1 record is a little overkill). You can try modifying your query a little such as by using If Exists(...)... and use ExecuteScalar() to get the return result. If it's not null then it's OK.
//the modified query
If Exists(SELECT * FROM Accounts WHERE (username = #user AND password = #pass))
SELECT 1 ELSE SELECT 0
var r = sqlCmd.ExecuteScalar();
if(r == null || (int)r == 0){
//failure...
}
I would "select count(*) from ..."
Then do ExecuteScalar() instead. This will return an int.
SqlCeConnection sqlCnn = new SqlCeConnection("Data Source=" + Application.StartupPath + "\\mainDB.sdf");
SqlCeCommand sqlCmd = new SqlCeCommand("SELECT count(*) FROM Accounts WHERE (username = #user AND password = #pass)", sqlCnn);
sqlCmd.Parameters.Add("#user", textBox1.Text);
sqlCmd.Parameters.Add("#pass", textBox2.Text);
sqlCnn.Open();
int recordCount = (int)sqlCmd.ExecuteScalar();
if (recordCount > 0)
{
//dostuff
}
Check if your Datateader has rows with reader.HasRows.
See this SO post How to check if SQLDataReader has no rows for more info.

Categories