C# Windows Forms Application - display sql server values in textbox - c#

I need assistance to display sql server values in a windows forms. In the application below if the query returns a row then the values are displayed. I understand that I am to use sqldatareader but so far I have been unsuccessful how to add it.
SqlConnection ChuoDB_Connection = new SqlConnection("Data Source=test-PC\\tester;Initial Catalog=Chuo;Integrated Security=True;Pooling=False");
SqlDataAdapter select_adapt;
private void btn_guardian_student_search_Click(object sender, EventArgs e)
{
if (rd_btn_guardian_student_no.Checked == true)
{
DataSet ds = new DataSet();
SqlDataReader dr;
ChuoDB_Connection.Open();
select_adapt = new SqlDataAdapter("SELECT * FROM Guardian WHERE STUDENT_NO = #student_no", ChuoDB_Connection);
select_adapt.SelectCommand.Parameters.Add("#student_no", SqlDbType.Int).Value = Convert.ToInt32(txt_bx_guardian_student_search.Text);
select_adapt.Fill(ds);
if (ds.Tables[0].Rows.Count == 0)
{
lbl_guardian_student_search.Text = "No Guardian record exists for this student. Please enter the Guardian Information";
ChuoDB_Connection.Close();
}
if (ds.Tables[0].Rows.Count > 0)
{
lbl_guardian_student_search.Text = "";
while (dr.read())
{
txtBox1.Text = rdr.Item["DBFieldName1"].ToString();
txtBox2.Text = rdr.Item["DBFieldName2"].ToString();
}
}
}
}

I think you do not need DataAdapter and DataSet here.
Try just with the DataReader:
string _connectionString = "Data Source=test-PC\\tester;Initial Catalog=Chuo;Integrated Security=True;Pooling=False";
string _selectCommand = #"SELECT * FROM Guardian WHERE STUDENT_NO = #student_no";
here code for the click handler:
SqlParameter parameter = new SqlParameter("#student_no", SqlDbType.Int);
parameter.Value = Convert.ToInt32(txt_bx_guardian_student_search.Text);
using (IDbConnection connection = new SqlConnection(_connectionString))
{
connection.Open();
using (IDbCommand command = connection.CreateCommand())
{
command.Connection = connection;
command.CommandText = _selectCommand;
command.Parameters.Add("#student_no", SqlDbType.Int).Value = Convert.ToInt32(txt_bx_guardian_student_search.Text);
IDataReader reader = command.ExecuteReader();
if (reader.Read())
{
txtBox1.Text = reader["DBFieldName1"].ToString();
txtBox2.Text = reader["DBFieldName2"].ToString();
}
else
{
lbl_guardian_student_search.Text = "No Guardian record exists for this student. Please enter the Guardian Information";
}
}
}

To use a SqlDataReader you need to initialize it using the ExecuteReader method of a SqlCommand. So in your code you could discard all the part relative to the SqlDataAdapter
private void btn_guardian_student_search_Click(object sender, EventArgs e)
{
if (rd_btn_guardian_student_no.Checked == true)
{
using(SqlConnection cnn = new SqlConnection(......))
using(SqlCommand cmd = new SqlCommand(#"SELECT * FROM Guardian
WHERE STUDENT_NO = #student_no", cnn))
{
cnn.Open();
cnn.Add("#student_no", SqlDbType.Int).Value = Convert.ToInt32(txt_bx_guardian_student_search.Text);
using(SqlDataReader rd = new cmd.ExecuteReader())
{
if(!rd.HasRows)
lbl_guardian_student_search.Text = "No Guardian record exists for this student. Please enter the Guardian Information";
else
{
rdr.Read();
txtBox1.Text = rdr.Item["DBFieldName1"].ToString();
txtBox2.Text = rdr.Item["DBFieldName2"].ToString();
}
}
}
}
}
Note that I have moved the global connection object inside the code making it a local variable that is initialized inside a using block as well the command and the reader. They are disposable objects and should be disposed when you have finished with them. The Using Statement ensure correct dispose of these objects
Also note that keeping a connection opened all the time of your application is really a big NO-NO in database server applications. You hinder the server ability to serve more requests if you keep your connection constantly open. And there is no great penalty in restoring the server connection because ADO.NET has an infrastructure called Connection Pooling that allows you to restore your connection immediately

Related

How to store multiple SQL data columns into different variables C#

I am trying to store sql data that I have for a voucher id and voucher amount into a variable and display it into a label on a click of a button.
protected void Button1_Click(object sender, EventArgs e)
{
string voucherId = String.Empty;
string voucherAmount = String.Empty;
string queryVoucherId = "select voucherid from ReturnForm where email = '" + Session["username"] + "';";
string queryVoucherAmount = "select voucheramount from ReturnForm where email = '" + Session["username"] + "';";
int index = 0;
using (SqlConnection con = new SqlConnection(str))
{
SqlCommand cmd = new SqlCommand(queryVoucherId, con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
voucherId = reader[index].ToString();
index++;
}
}
using (SqlConnection con = new SqlConnection(str))
{
SqlCommand cmd = new SqlCommand(queryVoucherAmount, con);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
voucherAmount = reader[index].ToString();
index++;
}
}
if (txtVoucher.Text == voucherId)
{
Label3.Visible = true;
Label3.Text = voucherAmount;
}
}
When I click the button its giving me an error saying that the index is out of bounds.
Building on #JSGarcia's answer - but using parameters as one ALWAYS should - you'd get this code:
string email = Session['username'];
string query = $"SELECT voucherid, voucheramount FROM ReturnFrom WHERE Email = #email";
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = new SqlCommand(query, conn))
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
// set the parameter before opening connection
// this also defines the type and length of parameter - just a guess here, might need to change this
cmd.Parameters.Add("#email", SqlDbType.VarChar, 100).Value = email;
conn.Open();
sda.Fill(dt);
conn.Close();
}
Personally, I'd rather use a data class like
public class VoucherData
{
public int Id { get; set; }
public Decimal Amount { get; set; }
}
and then get back a List<VoucherData> from your SQL query (using e.g. Dapper):
string query = $"SELECT Id, Amount FROM ReturnFrom WHERE Email = #email";
List<VoucherData> vouchers = conn.Query<VoucherData>(query).ToList();
I'd try to avoid the rather clunky and not very easy to use DataTable construct...
I strongly recommend combining your sql queries into a single one, write it into a datatable and continue your logic from there. IMHO it is much cleaner code:
string email = Session['username'];
string query = $"SELECT voucherid, voucheramount FROM ReturnFrom where Email = '{email}'";
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString))
using (SqlCommand cmd = conn.CreateCommand())
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
conn.Open();
sda.Fill(dt);
conn.Close();
}
// Work with DataTable dt from here on
...
Well, one more big tip?
You ONLY as a general rule need a dataadaptor if you going to update the data table.
And you ONLY need a new connection object if you say not using the sql command object.
The sqlcommand object has:
a connection object - no need to create a separate one
a reader - no need to create a separate one.
Note how I did NOT create a seperate connection object, but used the one built into the command object.
And since the parameter is the SAME in both cases? Then why not re-use that too!!
So, we get this:
void TestFun2()
{
String str = "some conneciton???";
DataTable rstVouch = new DataTable();
using (SqlCommand cmdSQL =
new SqlCommand("select voucherid from ReturnForm where email = #email",
new SqlConnection(str)))
{
cmdSQL.Parameters.Add("#email", SqlDbType.NVarChar).Value = Session["username"];
cmdSQL.Connection.Open();
rstVouch.Load(cmdSQL.ExecuteReader());
// now get vouch amount
cmdSQL.CommandText = "select voucheramount from ReturnForm where email = #email";
DataTable rstVouchAmount = new DataTable();
rstVouchAmount.Load(cmdSQL.ExecuteReader());
if (rstVouch.Rows[0]["vourcherid"].ToString() == txtVoucher.Text)
{
Label3.Visible = true;
Label3.Text = rstVouchAmount.Rows[0]["voucheramount"].ToString();
}
}
}

Show a data from database to a label

I'm new to c# programming and have a problem retrieving data from database to a label text. Here is the code what I was trying to do.
private void label3_Click_1(object sender, EventArgs e)
{
MySqlConnection con = new MySqlConnection("Server=localhost; Database=car_rental; user=root; Pwd=; SslMode=none");
DataTable dTable = new DataTable();
con.Open();
MySqlDataReader dr = null;
MySqlCommand cmd = new MySqlCommand("Select * from login where username=" + username, con);
dr =cmd.ExecuteReader();
while (dr.Read())
{
label3.Text = (dr["username"].ToString());
}
con.Close();
}
The problem in your code is created by the concatenation of a string (username) to another string (the sql query). This is a well known source of problems, going from syntax errors (the engine is not able to parse correctly the query text) to a much worse problem known as Sql Injection.
The well known solution is to use parameters instead of concatenated strings
private void label3_Click_1(object sender, EventArgs e)
{
using(MySqlConnection con = new MySqlConnection("Server=localhost; Database=car_rental; user=root; Pwd=; SslMode=none"))
{
con.Open();
// A single string with a parameter placeholder
string sqlCmd = "Select * from login where username=#name";
using(MySqlCommand cmd = new MySqlCommand(sqlCmd, con))
{
// Associate a value to the required parameter
cmd.Parameters.Add("#name", MySqlDbType.VarChar).Value = username;
using(MySqlDataReader dr =cmd.ExecuteReader())
{
// Supposing you have just one user with that name
if(dr.Read())
{
label3.Text = dr["username"].ToString();
}
else
{
label3.Text = "User not found!";
}
}
}
}
Notice how I have added the using statement around each disposable object required to query the database. This statement ensures that the objects involved are disposed at the end of their use freeing the valuable unmanaged resource kept during their usage.

Why does my MySQL connection not work in visual studio code C#?

i am making a program in visual studio code with C#, it is a paid program so it needs an hwid system. Basically i want it to check if your computer HWID exists in the HWID table in my users database. But it says it can't connect to the database. Can you help me? This is my code.`
string connectionString = "Server=SomeServer;Database=i got you this is notthe real database;User ID=same;Password=same for password;";
MySqlConnection mydbCon = new MySqlConnection(connectionString);
mydbCon.Open();
MySqlCommand command = mydbCon.CreateCommand();
command.CommandText = "SELECT * FROM yourTable WHERE hwid = GetHDDSerial";
IDataReader reader = command.ExecuteReader();
`
It could be that the connection string isn't formatted the way the MySQL connector wants it. The MySQL documentation shows "uid" instead of User, and "pwd" instead of Password. https://dev.mysql.com/doc/connector-net/en/connector-net-programming-connecting-connection-string.html
This should do what you need:
string connectionString = "Server=SomeServer;Database=i got you this is notthe real database;User ID=same;Password=same for password;";
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
using (MySqlCommand command = new MySqlCommand())
{
string sql = "SELECT * FROM yourTable WHERE hwid = #val1";
command.Connection = connection;
command.CommandType = CommandType.Text;
command.CommandText = sql;
command.Parameters.AddWithValue("#val1", "GetHDDSerial");
connection.Open();
using (MySqlDataAdapter adapter = new MySqlDataAdapter())
{
using (DataSet ds = new DataSet())
{
adapter.SelectCommand = command;
adapter.Fill(ds);
if (ds.Tables.Count > 0)
{
DataTable dt = ds.Tables[0];
foreach (DataRow row in dt.Rows)
{
// Do something here. You can access the data like this:
// row["Id"] or whatever your field names are.
// int id = (int) row["Id"];
// Of course, I don't know your field names, so you'll have to complete this.
}
}
}
}
}
}

c# System.InvalidOperationException: 'The connection is already open.'

I'm coding a Windows Forms login page for an administration application. My problem is, that when I try to log on, I get the error message
System.InvalidOperationException: 'The connection is already open.'
Any help would be appreciated
public partial class Form1 : Form
{
MySqlConnection con = new MySqlConnection (#"Database= app2000; Data Source = localhost; User = root; Password =''");
int i;
public Form1()
{
InitializeComponent();
}
private void btnClose_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btnLogin_Click(object sender, EventArgs e)
{
i = 0;
con.Open();
MySqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM adminlogin WHERE username='" + txtBoxUsername + "'AND password='" + txtBoxPassword + "'";
cmd.ExecuteNonQuery();
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
i = Convert.ToInt32(dt.Rows.Count.ToString());
if (i == 0)
{
lblerrorInput.Show();
}
else
{
this.Hide();
Main ss = new Main();
ss.Show();
}
}
}
Do not cache Connection, it's a typical antipattern, but recreate it when you need it
public partial class Form1 : Form {
...
//DONE: Extract method
private static bool UserExists(string userName, string password) {
//DONE: Do not cache connections, but recreate them
using (MySqlConnection con = new MySqlConnection (#"...") {
con.Open();
//DONE: wrap IDisposable into using
using (MySqlCommand cmd = con.CreateCommand()) {
cmd.CommandType = CommandType.Text;
//DONE: Make query being readable
//DONE: Make query being parametrized
cmd.CommandText =
#"SELECT *
FROM adminlogin
WHERE username = #UserName
AND password = #PassWord"; // <- A-A-A! Password as a plain text!
//TODO: the simplest, but not the best solution:
// better to create parameters explicitly
// cmd.Parameters.Add(...)
cmd.Parameters.AddWithValue("#UserName", txtBoxUsername);
cmd.Parameters.AddWithValue("#PassWord", txtBoxPassword);
// If we have at least one record, the user exists
using (var reader = cmd.ExecuteReader()) {
return (reader.Read());
}
}
}
}
Finally
private void btnLogin_Click(object sender, EventArgs e) {
if (!UserExists(txtBoxUsername.Text, txtBoxPassword.Text))
lblerrorInput.Show();
else {
Hide();
Main ss = new Main();
ss.Show();
}
}
You forgot to close the connection, use con.Close() at the end to close the connection and avoid this error the next time the event fires.
There are some mistakes in your code.
You should close the sql connection when you finished your process.
I suggest you to use using statement to dispose connection instance after complete database actions.
Also, you should use command parameters to prevent Sql injection.
You can declare connection string like this;
private string _connectionString = #"Database= app2000; Data Source = localhost; User = root; Password =''";
The method part looks like;
using (var con = new MySqlConnection(_connectionString))
{
i = 0;
con.Open();
MySqlCommand cmd = con.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM adminlogin WHERE username = #username and password = #password";
cmd.Parameters.AddWithValue("#username", txtBoxUsername);
cmd.Parameters.AddWithValue("#password", txtBoxPassword);
cmd.ExecuteNonQuery();
DataTable dt = new DataTable();
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
da.Fill(dt);
i = Convert.ToInt32(dt.Rows.Count.ToString());
if (i == 0)
{
lblerrorInput.Show();
}
else
{
this.Hide();
Main ss = new Main();
ss.Show();
}
con.Close();
}
First, don't cache your Connection objects. It's a terrible practice and I've had to go back and fix it every time I accept a new job and inherit code. Most database access classes implement IDisposable, so use using and take advantage of it to keep your code clean. FYI, Readers and Adapters are also IDisposable so you can do the same with them, too.
string command = "select stuff from mydata";
string connection = GetConnectionStringFromEncryptedConfigFile();
using (var conn = new SqlConnection(connection))
{
using (var cmd = new SqlCommand(command, conn))
{
cmd.Connection.Open();
//do stuff
}
}
Second, if you're forced to use a cached connection (i.e., you inherited horrible code and don't have time to fix it yet), check your State first.
if(conn.State != System.Data.ConnectionState.Open)
{
conn.Open();
}
Note that there are a lot more states than just Open and Closed, and if you try to open a connection that is busy, you'll still get errors. It's still a much wiser approach to use the IDisposable implementations with using so you don't have to worry about this sort of thing so much.

Loading combobox from database in C#

I am creating an application, where I can add a customer's first name, last name, email, the date, service type (pc repair), the technician PC brand, pc type, type of OS, and the problem with the computer. I am able to insert data into the MySQL database using phpMyAdmin.
However, I a stuck on this part. I am trying to view the service order that was just created. I would like to load the combobox by the last name of the customer, and once I click on the customer's name, it populates all the fields that were mentioned above and the service number that it was inserted into the database. I am having issues loading the combobox and texfields.
Any ideas are appreciated! If a combobox is a bad idea and there is a better way, please let me know! I tried this code, but SQLDataAdapter is not working for me. I somehow can't find an example that I can relate too.
private void cbViewServices_SelectedIndexChanged(object sender, EventArgs e)
{
if (cbViewServices.SelectedIndex >- 1)
{
string lastName = cbViewServices.SelectedValue.ToString();
MySqlConnection conn = new MySqlConnection("server=localhost;uid=******;password=**********;database=dboserviceinfo;");
conn.Open();
SqlDataAdapter da = new SqlDataAdapter("select distinct LastName from tserviceinfo where LastName='" + lastName + "'", conn);
DataSet ds = new DataSet();
da.Fill(ds); conn.Close();
}
}
I do not recommend using the 'Lastname' as a parameter to load your details since that field most likely isn't unique. Unless that is the case in your program.
This sample does the following:
Load customer ID (or lastname in your case) to a combobox.
Handle the combobox's change event and pass it as a parameter to a
method that will use that to load the details.
Load the customer details using the passed parameter.
A couple of guidelines:
Enclose disposable objects in a 'using' statement so it will be
disposed properly.
Do not use string concatenation to create your SQL statements. Use
SQL parameters instead, that way you'll avoid SQL injection and make
your code clearer.
Take a look at MySQL .NET connector provider documentation for best practices.
//Load customer ID to a combobox
private void LoadCustomersId()
{
var connectionString = "connection string goes here";
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
var query = "SELECT Id FROM Customers";
using (var command = new MySqlCommand(query, connection))
{
using (var reader = command.ExecuteReader())
{
//Iterate through the rows and add it to the combobox's items
while (reader.Read())
{
CustomerIdComboBox.Items.Add(reader.GetString("Id"));
}
}
}
}
}
//Load customer details using the ID
private void LoadCustomerDetailsById(int id)
{
var connectionString = "connection string goes here";
using (var connection = new MySqlConnection(connectionString))
{
connection.Open();
var query = "SELECT Id, Firstname, Lastname FROM Customer WHERE Id = #customerId";
using (var command = new MySqlCommand(query, connection))
{
//Always use SQL parameters to avoid SQL injection and it automatically escapes characters
command.Parameters.AddWithValue("#customerId", id);
using (var reader = command.ExecuteReader())
{
//No customer found by supplied ID
if (!reader.HasRows)
return;
CustomerIdTextBox.Text = reader.GetInt32("Id").ToString();
FirstnameTextBox.Text = reader.GetString("Firstname");
LastnameTextBox.Text = reader.GetString("Lastname");
}
}
}
}
//Pass the selected ID in the combobox to the customer details loader method
private void CustomerIdComboBox_SelectedIndexChanged(object s, EventArgs e)
{
var customerId = Convert.ToInt32(CustomerIdComboBox.Text);
LoadCustomerDetailsById(customerId);
}
I'm not entirely sure if this is what your looking for but most of the guidelines still applies.
Hope this helps!
Try something like this to bind data to the combo box:
public void ListCat()
{
DataTable linkcat = new DataTable("linkcat");
using (SqlConnection sqlConn = new SqlConnection(#"Connection stuff;"))
{
using (SqlDataAdapter da = new SqlDataAdapter("SELECT LastName FROM list WHERE LastName <> 'NULL'", sqlConn))
{
da.Fill(linkcat);
}
}
foreach (DataRow da in linkcat.Rows)
{
comboBox1.Items.Add(da[0].ToString());
}
}
Taken from my own question.
SqlDataAdapter is used to communicate with SQL Server rather than MySQL.
Try the following:
MySqlDataAdapter da = new MySqlDataAdapter("select distinct LastName from tserviceinfo where LastName='" + lastName + "'", conn);
We can also use while loop. When completing the database connection after the SQLDatareader we can use while loop.
"userRead " is SQLData reader
while (userRead.Read())
{
cboxReportNo.Items.Add(userRead[1].ToString());
}
bind your dataset in ComboBox DataSource
this.comboBox1.DataSource = ds;
this.comboBox1.DisplayMember = "LastName";
this.comboBox1.ValueMember = "Id";
this.comboBox1.SelectedIndex = -1;
this.comboBox1.AutoCompleteMode = AutoCompleteMode.Append;
this.comboBox1.AutoCompleteSource = AutoCompleteSource.ListItems;
//USING
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data;
namespace YourNamespace
{
//Initialization
string connetionString = null;
SqlConnection cnn;
SqlCommand cmdDataBase;
SqlDataReader reader;
DataTable dt;
public frmName()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//
// TODO: Add constructor code after the InitializeComponent() call.
//
FillComboNameOfCombo();
}
void FillcmbNameOfCombo()
{
string sqlQuery = "SELECT * FROM DATABASENAME.[dbo].[TABLENAME];";
connetionString = "Data Source=YourPathToServer;Initial Catalog=DATABASE_NAME;User ID=id;Password=pass";
cnn = new SqlConnection(connetionString);
cmdDataBase = new SqlCommand(sqlQuery, cnn);
try {
cnn.Open();
reader = cmdDataBase.ExecuteReader();
dt = new DataTable();
dt.Columns.Add("ID", typeof(string));
dt.Columns.Add("COLUMN_NAME", typeof(string));
dt.Load(reader);
cnn.Close();
cmbGender.DataSource = dt;
cmbGender.ValueMember = "ID";
cmbGender.DisplayMember = "COLUMN_NAME";
dt = null;
cnn = null;
cmdDataBase = null;
connetionString = null;
reader = null;
}
catch (Exception ex) {
MessageBox.Show("Can not open connection ! " + ex.ToString());
}
}
}

Categories

Resources