C# : querying multiple columns into textboxes - c#

This is my code, and I want to be able to search for a name, and then pull from the database the name, status, member_id into the textboxes in my form.
I got the name to work but how do I get the other columns and parse the output into the textboxes with the additional columns (member_id, status)? Let's say the other textboxes have the standard name such as textbox2, 3, 4...
string connetionString = null;
SqlConnection connection;
SqlCommand command;
string sql = null;
string sql1 = null;
SqlDataReader dataReader;
connetionString = "Data Source=......"
sql = "SELECT NAME FROM Test_Employee WHERE Name LIKE '" + textBox1.Text.ToString() + "%'";
connection = new SqlConnection(connetionString);
{
connection.Open();
command = new SqlCommand(sql, connection);
dataReader = command.ExecuteReader();
while (dataReader.Read())
{
textBox9.Text = dataReader[0].ToString();
textBox7.Text = dataReader[0].ToString();
}
connection.Close();
}

Are the fields Member_Id and Status also in the table Test_Employee? You can add them in your Select statement and get them from your SqlReader, like the code below (assuming you are using c#7 and below). You may copy and paste this code.
var connectionString = "";
var sql = #"SELECT TOP 1 Name, Member_Id, Status
FROM Test_Employee
WHERE Name LIKE #name + '%'";
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(sql, connection))
{
command.Parameters.Add("name", SqlDbType.NVarChar, 100).Value = textBox1.Text.ToString();
connection.Open();
var reader = command.ExecuteReader();
if (reader.Read())
{
textBox9.Text = dataReader["Name"].ToString();
textBox7.Text = dataReader["Name"].ToString();
textBox2.Text = dataReader["Member_Id"].ToString();
textBox3.Text = dataReader["Status"].ToString();
}
}
You will notice that instead of including the Textbox1.Text's value in your Select statement, it is added as a parameter in the SQLCommand object's Parameters. In this way your query is protected from SQL Injection. If you want to learn more, you can search c# sqlcommand parameters and why it is very important to build data access code this way.
Also, notice that I added Top 1 in your Select statement, and instead of using while, I am using if. This is because a textbox can only hold 1 result at a time in a comprehensible way. If you meant to show multiple results clearly, you need to use a different control other than a TextBox.
The using statements allow you to dispose the connection, so you don't have to call connection.Close().

Related

How to dynamically add lables for every name in MYSQL database?

I have a MYSQL database and I am trying to get the first name and last name of every student I put in the database and dynamically show them as a label in my WPF form, here is what I got so far
string connstr = "Server=localhost; Database=login; UID=root; Pwd=password";
MySqlConnection connc = new MySqlConnection(connstr);
MySqlCommand command;
connc.Open();
// Label[] labels = new Label[n];
try
{
command = connc.CreateCommand();
command.CommandText = "SELECT First_name, Last_name FROM Students";
command.ExecuteReader();
MessageBox.Show("S");
}
catch (Exception ex)
{
MessageBox.Show("something went wrong: " + ex.ToString());
}
finally
{
connc.Close();
}
So how could I add all my entry's in the database to a label?
ExecuteNonQuery method just executes your query. You can't get your values with it.
You need to use ExecuteReader at least to get your values. You can read your column values in a while statement with MySqlDataReader.Read() method. This method reads your query row by row.
Also use using statement to dispose your MySqlConnection, MySqlCommand and MySqlDataReader.
using(MySqlConnection connc = new MySqlConnection(connstr))
using(MySqlCommand command = new MySqlCommand("SELECT First_name, Last_name FROM Students", connc))
{
using(MySqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
// reader[0] gets you first column which is First_name
// reader[1] gets you second column which is Last_name
// Do your label assingments..
}
}
}
First , ExecuteNonQuery() method is used for DML statements INSERT ,UPDATE , DELETE .
Use ExecuteReader() method.
command = connc.CreateCommand();
command.CommandText = "SELECT First_name, Last_name FROM Students";
SqlDataReader dr = command.ExecuteReader();
string result=string.Empty;
while(dr.Read())
{
result += dr["First_name"].ToString() + " " + dr["Last_name"].ToString();
}
lableId.Content=result;

How to Access Specific Fields of Data from Database

I am working on a inventory software in which I want to access the ProductName and Product Price by Comparing it With the ProductCode, the Data I've Already Stored in Database table named ProductLog, the Data in Product Log is:
ItemNO Productode ProductName ProductPrice
1 123 lux 58
2 321 soap 68
now I want that I only enter productCode in my textbook named txtProductCode, and press tab then ProductPrice(txtProductPrice) and ProductName(txtProductName) boxes fills automatically.
The code I tried to compare the Productcode and access values is:
private void txtProdcutCode_Leave(object sender, EventArgs e)
{
///////////////////////////////////////////////////////////////////////
InitializeComponent();
string sql;
int productCode = 0;
productCode = Convert.ToInt32(txtProdcutCode.Text);
sql = "";
sql = "SELECT dbo.ProductLog.ProductName, dbo.ProductLog.ProductName";
sql = " WHERE ProductLog.ProductCode = " + txtProdcutCode.Text + "";
SqlConnection cn = new SqlConnection();
SqlCommand rs = new SqlCommand();
SqlDataReader sdr = null;
clsConnection clsCon = new clsConnection();
clsCon.fnc_ConnectToDB(ref cn);
rs.Connection = cn;
rs.CommandText = sql;
sdr = rs.ExecuteReader();
while (sdr.Read())
{
txtProductPrice.Text = sdr["ProductPrice"].ToString();
txtProductName.Text = sdr["ProductName"].ToString();
}
//lblTotalQuestion.Text = intQNo.ToString();
sdr.Close();
rs = null;
cn.Close();
/////////////////////////////////////////////////////////////////////////
}
but in line productCode = Convert.ToInt32(txtProdcutCode.Text); it says Input string was not in a correct format.
Please help me out with this problem.
EDIT:
I've also tried this code :
private void txtProdcutCode_Leave(object sender, EventArgs e)
{
///////////////////////////////////////////////////////////////////////
string sql;
// int productCode = 0;
//productCode = Convert.ToInt32(txtProdcutCode.Text);
sql = "";
sql = "SELECT dbo.ProductLog.ProductName, AND dbo.ProductLog.ProductName";
sql = " WHERE dbo.ProductLog.ProductCode = " + txtProdcutCode.Text + "";
SqlConnection cn = new SqlConnection();
SqlCommand rs = new SqlCommand();
SqlDataReader sdr = null;
clsConnection clsCon = new clsConnection();
clsCon.fnc_ConnectToDB(ref cn);
rs.Connection = cn;
rs.CommandText = sql;
sdr = rs.ExecuteReader();
while (sdr.Read())
{
txtProductPrice.Text = sdr["ProductPrice"].ToString();
txtProductName.Text = sdr["ProductName"].ToString();
}
//lblTotalQuestion.Text = intQNo.ToString();
sdr.Close();
rs = null;
cn.Close();
/////////////////////////////////////////////////////////////////////////
}
but it says Incorrect syntax near the keyword 'WHERE'. means I am making mistake in calling database table in my query, but I am not able to find out the mistake ...
There are some issues with your SQL.
You were originally overwriting the sql variable and only ended up with a WHERE clause;
You don't have a FROM statement so the database doesn't know where you're trying to retrieve records from.
The use of AND in a SELECT statement is incorrect; you just need commas to separate the fields.
You're never selecting ProductPrice from the DB, but selecting ProductName twice!
You're not using parameterized SQL for your query, leaving your app open to SQL injection attacks.
To address this (points 1-4, I will leave point 5 for your own research),
sql = "";
sql = "SELECT dbo.ProductLog.ProductName, AND dbo.ProductLog.ProductName";
sql = " WHERE dbo.ProductLog.ProductCode = " + txtProdcutCode.Text + "";
Should be
sql += "SELECT ProductName, ProductPrice";
sql += " FROM dbo.ProductLog";
sql += " WHERE ProductCode = '" + txtProdcutCode.Text + "'";
Note: This answer assumes that the value of txtProductCode.Text is an integer!
EDIT: It turns out that the column, ProductCode, was a VarChar. For OP
and others reading this question, when you get SQL conversion errors
check your column datatype in SQL server and make sure it matches what
you're submitting.
That's the basics. There are many other improvements that can be made but this will get you going. Brush up on basic SQL syntax, and once you get that down, look into making this query use a parameter instead of directly placing txtProductCode.Text into your query. Good luck!
Never call InitializeComponent method twice.It's creating your form and controls and it's calling in your form's constructor.Probably when you leave your textBox it's creating again and textBox will be blank.therefore you getting that error.Delete InitializeComponent from your code and try again.
Update: your command text is wrong.here you should use +=
sql += " WHERE dbo.ProductLog.ProductCode = " + txtProdcutCode.Text + "";
But this is not elegant and safe.Instead use paramatirezed queries like this:
SqlCommand cmd = new SqlCommand();
cmd.Connection = cn;
cmd.CommandText = "SELECT dbo.ProductLog.ProductName,dbo.ProductLog.ProductName WHERE dbo.ProductLog.ProductCode = #pCode";
cmd.Parameters.AddWithValue("#pCode", txtProdcutCode.Text );

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!

How to display specific database entries into a textbox on a WinForm application

UPDATE:
Thanks everyone, the code was not the issue, although the information regarding SQL injection was useful, my issue was that I was using an older version of my database which did not have the corresponding product ID so it was instead using the first product that it could find. Feel very stupid now but thanks for the suggestions.
I currently have the following code :
SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\v11.0 AttachDbFilename=C:\Users\h8005267\Desktop\Practical Project\Build\System4\System\StockControl.mdf;Integrated Security=True;Connect Timeout=30");
connection.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM Product WHERE ProductID='" + textBox3.Text + "'", connection);
SqlDataReader re = cmd.ExecuteReader();
if (re.Read())
{
textBox4.Text = re["ProductTitle"].ToString(); // only fills using first product in table
textBox5.Text = re["ProductPublisherArtist"].ToString();
comboBox1.Text = re["ProductType"].ToString();
textBox6.Text = re["Price"].ToString();
}
else
{
MessageBox.Show("Please enter a valid item barcode");
}
re.Close();
connection.Close();
The issue I am currently having is although the text boxes display the information on button click, the information displayed is only the first row of data in the database, NOT the row corresponding to the textbox3 in the sql statement
Try this instead. Avoid building SQL statement dynamically the way you are doing it. You are opening your database to risks of SQL Injection. Used parameters insead.
using (var connection = new SqlConnection("connection string"))
{
connection.Open();
using (var cmd = new SqlCommand("SELECT * FROM Product WHERE ProductID=#MYVALUE", connection))
{
cmd.Parameters.Add("#MYVALUE", SqlDbType.VarChar).Value = textBox3.Text;
SqlDataReader re = cmd.ExecuteReader();
if (re.Read())
{
textBox4.Text = re["ProductTitle"].ToString(); // only fills using first product in table
textBox5.Text = re["ProductPublisherArtist"].ToString();
comboBox1.Text = re["ProductType"].ToString();
textBox6.Text = re["Price"].ToString();
}
else
{
MessageBox.Show("Please enter a valid item barcode");
}
}
}
put a breakpoint on that line
SqlDataReader re = cmd.ExecuteReader();
and enter the following into textBox3
'; DROP TABLE Product; SELECT '
the ' are to be entered in your textbox. now execute your method and carefully read the resulting sql command... welcome to sql injection ;)
#M Patel: thx for your comment and you are perfectly right
The result would be the following SQL
SELECT * FROM Product WHERE ProductID=''; DROP TABLE Product; SELECT ''
And this would allow a malicious user to destroy your database.
To prevent that you should work with prepared Statements like M Patel suggested in his answer
you have SQL Injection problem with '" + textBox3.Text + "'"
and you don't have to name your controls like that, you have to use a meaningful names
you can use this code
using (SqlConnection connection = new SqlConnection(#"Data Source=(LocalDB)\v11.0 AttachDbFilename=C:\Users\h8005267\Desktop\Practical Project\Build\System4\System\StockControl.mdf;Integrated Security=True;Connect Timeout=30"))
{
connection.Open();
SqlCommand cmd = new SqlCommand("SELECT * FROM Product WHERE ProductID=#ProductID", connection);
cmd.Parameters.AddWithValue("#ProductID", textBox3.Text);
SqlDataReader re = cmd.ExecuteReader();
if (re.Read())
{
textBox4.Text = re.GetString(re.GetOrdinal("ProductTitle")); // only fills using first product in table
textBox5.Text = re.GetString(re.GetOrdinal("ProductPublisherArtist"));
comboBox1.Text = re.GetString(re.GetOrdinal("ProductType"));
textBox6.Text = re.GetString(re.GetOrdinal("Price"));
}
else
{
MessageBox.Show("Please enter a valid item barcode");
}
re.Close();
}

Dynamically passing a value inside a query?

I have two columns syntax and query in my table Table1. Syntax contains data called po and a query called select * from po_pomas_pur_order_hdr where pomas_pono =. I got this query value by using
SqlDataAdapter da = new SqlDataAdapter("select query from Table1 where syntax = '" + textBox1.Text + "'", conn);
And my problem is that I need to dynamically pass another value inside the query which I retrived using dataadapter like this:
SqlDataAdapter da1 = new SqlDataAdapter(da.tostring() +"'"+ textBox1.Text +"'", conn)
The resulting query should be like this:
select * from po_pomas_pur_order_hdr where pomas_pono = '2PO/000002/09-10'
But it is not possible. How to get a query like this? Any suggestion?
SqlDataAdapter is used to fill datasets and datatables. You cannot obtain the result of a query with ToString(). I think you want to use SqlCommand to execute your first query to retrieve the actual query to run from the database like this:
string query = null;
using (var command = new SqlCommand("select query from Table1 where syntax = #Syntax", conn))
{
command.Parameters.AddWithValue("#Syntax", textBox1.Text);
query = command.ExecuteScalar(); // this assumes only one query result is returned
}
Then you can use the data adapter to fill it:
SqlDataAdapter da1 = new SqlDataAdapter(query +"'"+ textBox1.Text +"'", conn);
Although I would suggest to use parameters for that as well.
in this way is more safe: dotnetperls
He check the "'" and the "\", check the type of the fields etc...
Code from the example above (is the same for insert delete and update):
using (SqlCommand command = new SqlCommand("SELECT * FROM Dogs1 WHERE Name LIKE #Name", connection))
{
//
// Add new SqlParameter to the command.
//
command.Parameters.Add(new SqlParameter("Name", dogName));
//
// Read in the SELECT results.
//
SqlDataReader reader = command.ExecuteReader();
while (reader.Read())
{
int weight = reader.GetInt32(0);
string name = reader.GetString(1);
string breed = reader.GetString(2);
Console.WriteLine("Weight = {0}, Name = {1}, Breed = {2}", weight, name, breed);
}
}
I suggest you to use SqlParameters. Here is example how to use DataAdapter and parameters.
Provided that you have a DataSet you intend to fill using the adapter and that you adjust the queries to use parameters in order to avoid sql injection you should be able to use something like this:
string query;
using(var sqlCommand = new SqlCommand(
"select query from Table1 where syntax=#syntax", conn))
{
sqlCommand.Parameters.AddWithValue("syntax", textBox1.Text);
query = (string)sqlCommand.ExecuteScalar();
}
using(var dataAdapter = new SqlDataAdapter())
using(var dataCommand = new SqlCommand(query, conn))
{
dataCommand.Parameters.AddWithValue("parameter", poNumber);
dataAdapter.SelectCommand = dataCommand;
dataAdapter.Fill(myDataSet);
}

Categories