Duplicating records in c# - c#

I am making a attendance system, and here is my problem now, after i searched for a name of a person and try to log him in for attendance, it is fine at first, after logging in the second name it is still fine. but once i tried to edit the login attendance of the first or second user, all the values in my datagridview(connected to my database) became duplicated. if i enter name1 for attendance in my week1 it is fine. name2 for attendance in week1 is still fine.
but if i edit the same name. or even go to the next week number, all of the saved values got duplicated based on my recent inputed name.
for inserting new records
SqlConnection cnn200 = new SqlConnection(connectionstring);
string sql200 = "SELECT * FROM attendance WHERE csign=#csign ";
cnn200.Open();
SqlCommand cmd200 = new SqlCommand(sql200, cnn200);
SqlDataReader rdr200;
cmd200.Parameters.AddWithValue("#csign", callsign);
rdr200 = cmd200.ExecuteReader();
if (rdr200.Read() == true)
{
SqlConnection cnn201 = new SqlConnection(connectionstring);
if (textBox89.Text == "1")
{
string sql201 = "insert INTO attendance
(csign,name,week1)" + "VALUES" + "(#csign,#name,#week1)";
cnn201.Open();
SqlCommand cmd201 = new SqlCommand(sql201, cnn201);
cmd201.Parameters.AddWithValue("#csign", callsign);
cmd201.Parameters.AddWithValue("#name", namee);
cmd201.Parameters.AddWithValue("#week1",
comboBox1.Text);
cmd201.ExecuteNonQuery();
}
if (textBox89.Text == "2")
{
string sql201 = "insert INTO attendance
(csign,name,week2)" + "VALUES" + "(#csign,#name,#week2)";
cnn201.Open();
SqlCommand cmd201 = new SqlCommand(sql201, cnn201);
cmd201.Parameters.AddWithValue("#csign", callsign);
cmd201.Parameters.AddWithValue("#name", namee);
cmd201.Parameters.AddWithValue("#week2",
comboBox1.Text);
cmd201.ExecuteNonQuery();
}
and for updating
else{
SqlConnection cnn201 = new SqlConnection(connectionstring);
if (textBox89.Text == "1")
{
string sql201 = "UPDATE attendance SET
name=#name,csign=#csign,week1=#week1";
cnn201.Open();
SqlCommand cmd201 = new SqlCommand(sql201, cnn201);
cmd201.Parameters.AddWithValue("#name", namee);
cmd201.Parameters.AddWithValue("#csign", callsign);
cmd201.Parameters.AddWithValue("#week1",
comboBox1.Text);
cmd201.ExecuteNonQuery();
}
if (textBox89.Text == "2")
{
string sql201 = "UPDATE attendance SET
name=#name,csign=#csign,week2=#week2";
cnn201.Open();
SqlCommand cmd201 = new SqlCommand(sql201, cnn201);
cmd201.Parameters.AddWithValue("#name", namee);
cmd201.Parameters.AddWithValue("#csign", callsign);
cmd201.Parameters.AddWithValue("#week2",
comboBox1.Text);
cmd201.ExecuteNonQuery();
}`}

nica, I think I can help. What you are trying to do can be done easily with less coding lines. An entire DataGridView can be displayed, edited, deleted and have no duplicates by using a few more objects
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Globalization;
using System.Data.SqlClient;
using System.IO;
using System.Configuration;
namespace ADO_NET_Testbed
{
public partial class MainForm : Form
{
private SqlDataAdapter adapter;
private string connectionString = #"Data Source=Server;Persist Security Info=True;Password=password!;User ID=sooperuser;Initial Catalog=Database";
private string sqlcommand = #"SELECT OPID, LastName, FirstName, Title, PhoneOffice, PhoneCell, Email, Active, Admin, Tester, Educator, Developer FROM AuditUser";
private SqlCommandBuilder cmdBuilder = new SqlCommandBuilder();
private DataTable datatable = new DataTable();
private DataSet dataset = new DataSet();
public MainForm()
{
InitializeComponent();
}
private void MainForm_Load(object sender, EventArgs e)
{
adapter = new SqlDataAdapter(sqlcommand, connectionString);
adapter.Fill(dataset, "AuditUser");
dgvUsers.DataSource = dataset.Tables[0];
dgvUsers.Enabled = true;
this.Show();
}
private void btnCancel_Click(object sender, EventArgs e)
{
dataset.Clear();
dataset.Reset();
this.Close();
}
private void btnSave_Click(object sender, EventArgs e)
{
cmdBuilder.DataAdapter = adapter;
adapter.Update(dataset.Tables[0]);
this.Close();
}
}
}
As a quick rundown of what is going on, the SqlDataAdapter holds the four queries, but auto-creates three from the SELECT command. Using a SqlCommandBuilder enables the other three to be added, although the debugger will not show them as anything but NULL. The adapter.Fill() and adapter.Update() handle all the different commands based on the RowState of each row in the datagridview. "Cancel" is overkill seeing as this form is closed anyway.

Related

why sql server allows to save null value inside of not null fields?

im trying to learn c# and sql server and i have some problems with them in n-th layer projects.
so i created a 3-layer project:
1-DataAccessLayer
2-CodeLayer
3-UILayer
i connect all layers with references.
in DataAccessLayer there is a class with this code below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
namespace DataAccessLayer
{
public class DataContent
{
SqlConnection cnn;
SqlCommand cmd;
SqlDataAdapter sa;
DataTable dt;
public DataContent()
{
cnn = new SqlConnection();
cmd = new SqlCommand();
sa = new SqlDataAdapter();
cmd.Connection = cnn;
sa.SelectCommand = cmd;
}
public void connect()
{
cnn.ConnectionString = "Data Source=.;Initial Catalog=testDB;Integrated Security=True";
cnn.Open();
}
public void disConnect()
{
cnn.Close();
}
public void runCommend(string query)
{
cmd.CommandText = query;
cmd.ExecuteNonQuery();
}
public DataTable SELECT(string query)
{
cmd.CommandText = query;
dt = new DataTable();
sa.Fill(dt);
return dt;
}
}
}
in CodeLayer there is a class whit this code below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using DataAccessLayer;
namespace codeLayer
{
public class Data : DataContent
{
public string userName;
public string userPass;
public string uName;
public string uFamily;
public string uTell;
public DataTable validation()
{
base.connect();
string query = "select * from tblData where userName = '{0}' and userPass = '{1}'";
query = String.Format(query, userName, userPass);
DataTable dt = base.SELECT(query);
base.disConnect();
return dt;
}
public void updateTable()
{
base.connect();
string query = "update tblData set userPass = '{0}', uName = N'{1}', uFamily = N'{2}', uTell = '{3}' where userName = '{4}'";
query = String.Format(query, userPass, uName, uFamily, uTell, userName);
base.runCommend(query);
base.disConnect();
}
}
}
my form in UILayer like this:
enter image description here
and i have table with one record that i add manually like this:
enter image description here
and i set all fields in table to not null
there is 2 click event in form:
1-btnSearch_click :
private void btnSearch_Click(object sender, EventArgs e)
{
Data a = new Data();
a.userName = txtUserNameSearch.Text;
a.userPass = txtPassWordSearch.Text;
DataTable newDT = a.validation();
if (newDT != null && newDT.Rows.Count > 0)
{
txtName.Text = newDT.Rows[0]["uName"].ToString();
txtFamily.Text = newDT.Rows[0]["uFamily"].ToString();
txtUserName.Text = newDT.Rows[0]["userName"].ToString();
txtPassWord.Text = newDT.Rows[0]["userPass"].ToString();
txtTell.Text = newDT.Rows[0]["uTell"].ToString();
}
else
{
MessageBox.Show("sorry...! cant finde user with inserted info.", "user not found", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
2-btnEdit_Click:
private void btnEdit_Click(object sender, EventArgs e)
{
Data a = new Data();
a.userName = txtUserName.Text;
a.userPass = txtPassWord.Text;
a.uName = txtName.Text;
a.uFamily = txtFamily.Text;
a.uTell = txtTell.Text;
try
{
a.updateTable();
MessageBox.Show("edit information was success.", "successfull", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch
{
MessageBox.Show("failed to update information", "error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
so when i run it for test, search function is works and get data from table and puts them in text boxes.
but problem is when i try to edit. after search i clear one of the text boxes and click edit and its just work. Should not i get some exeptions here???
after that i check the table and the field that i cleared before is empty in table like picture below:
enter image description here
whats happning here?? am i doing something wrong?? what did I missed??
please help me to solve this problem.
ps: im sorry for my bad english.

How to save data when i add in datagridview into database sql server

First, I'm really sorry about my English pronounciation. I have a datagridview, and i connect it to sql server which has been dip into my project in visual studio. However, when i save info in datagridview, it works but in database it is not saved in my database in sql server. Can you help me, please
And this is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Lab3_Bai09
{
public partial class Form1 : Form
{
SqlConnection cnn = null;
string connetionString;
public Form1()
{
InitializeComponent();
connetionString = "Data Source=(LocalDB)\\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\\QLSV.mdf;Integrated Security=True";
cnn = new SqlConnection(connetionString);
cnn.Open();
cnn.Close();
}
private void button1_Click(object sender, EventArgs e)
{
txtB2.Text = txtB1.Text;
}
private void button2_Click(object sender, EventArgs e)
{
txtB1.Text = txtB2.Text;
}
private void Save_Click(object sender, EventArgs e)
{
cnn.Open();
SqlCommand sqlCommand;
SqlDataAdapter adapter = new SqlDataAdapter();
string sql = "";
string sex = "";
if(checkBox1.Checked == true)
{
sex = "Nam";
}
else
{
sex = "Nu";
}
string[] subjectList = txtB1.Text.Split('\n');
int countSubject = subjectList.Length;
sql = $"insert into SINHVIEN(MSSV, HOTEN, CHUYENNGANH, GIOITINH, SOMON) values ('{textBox1.Text}', '{textBox2.Text}', '{comboBox1.Text}', '{sex}', '{countSubject}')";
sqlCommand = new SqlCommand(sql, cnn);
adapter.InsertCommand = new SqlCommand(sql, cnn);
adapter.InsertCommand.ExecuteNonQuery();
MessageBox.Show("Đã thêm mới dữ liệu thành công!");
this.sINHVIENTableAdapter1.Fill(this.qLSVDataSet1.SINHVIEN);
textBox1.Clear();
textBox2.Clear();
checkBox1.Checked = false;
checkBox2.Checked = false;
txtB1.Clear();
txtB2.Clear();
cnn.Close();
}
private void Delete_Click(object sender, EventArgs e)
{
cnn.Open();
DialogResult result = MessageBox.Show("Bạn có muốn xóa dòng đã chọn?", "Delete", MessageBoxButtons.YesNoCancel);
if (result == DialogResult.Yes)
{
SqlCommand sqlCommand;
SqlDataAdapter adapter = new SqlDataAdapter();
string sql = "";
int selectedrowindex = dataGridView1.SelectedCells[0].RowIndex;
DataGridViewRow selectedRow = dataGridView1.Rows[selectedrowindex];
string c = selectedRow.Cells[0].Value.ToString();
sql = $"delete from SINHVIEN where MSSV = {c}";
sqlCommand = new SqlCommand(sql, cnn);
adapter.InsertCommand = new SqlCommand(sql, cnn);
adapter.InsertCommand.ExecuteNonQuery();
MessageBox.Show("Xóa dữ liệu thành công");
this.sINHVIENTableAdapter1.Fill(this.qLSVDataSet1.SINHVIEN);
}
cnn.Close();
}
private void Form1_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'qLSVDataSet1.SINHVIEN' table. You can move, or remove it, as needed.
this.sINHVIENTableAdapter1.Fill(this.qLSVDataSet1.SINHVIEN);
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
DialogResult result = MessageBox.Show("Bạn có muốn thoát?", "Exit", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
Application.Exit();
}
else
{
e.Cancel = true;
}
}
else
{
e.Cancel = true;
}
}
}
}
It looks like you are just pulling values from text boxes and a combo box. There is a line for this.sINHVIENTableAdapter1.Fill(this.qLSVDataSet1.SINHVIEN); but where are those declared? I don't see you calling anything that writes the data back to the database from that adapter or dataset. After you declare the sqlCommand, you write a new instance of an sql command into the adapter, do you mean to do that?
sqlCommand = new SqlCommand(sql, cnn);
adapter.InsertCommand = new SqlCommand(sql, cnn);
adapter.InsertCommand.ExecuteNonQuery();
I will say that you are leaving yourself wide open for SQL injection. The SQL INSERT should be handled more like this:
sql = $"insert into SINHVIEN(MSSV, HOTEN, CHUYENNGANH, GIOITINH, SOMON) values (#mssv, #hoten, #chuy, #sex, #countsub)";
sqlCommand = new SqlCommand(sql, cnn);
sqlCommand.Parameters.AddWithValue("#mssv", textBox1.Text);
sqlCommand.Parameters.AddWithValue("#hoten", comboBox1.Text);
sqlCommand.Parameters.AddWithValue("#chuy", textBox2.Text);
sqlCommand.Parameters.AddWithValue("#sex", sex);
sqlCommand.Parameters.AddWithValue("#countSub", countSubject);
adapter.InsertCommand = sqlCommand;
adapter.InsertCommand.ExecuteNonQuery();
See this post for how to bind a datagridview to a datatable: How to bind Dataset to DataGridView in windows application.

C# button that would add text from one textbox into another textbox based on a SQL query

I am new to C# and need to create a little form application, that has two textboxes one that asks for a [File_ID] then when button is pressed send that number to a query and in another textbox display the output.
I have been playing around with it a bit, and have something like this. But it is not working. I am not sure if I should go on a different direction. I would REALLY appreciate your help.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace testing
{
public partial class Form1 : Form
{
String str,dr;
SqlConnection con = new SqlConnection("Data Source=USHOU2016\\USFi;Initial Catalog=HOU_2016_Project;Integrated Security=True");
SqlCommand cmd;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
con.Open();
str = "SELECT TOP 1,[Sender Name],[Subject] from [OLE DB Destination] WHERE [CHAT #] ='" + textBox1.Text + "'";
cmd = new SqlCommand(str, con);
// dr = cmd.ExecuteReader();
con.Close();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
textBox1.Text = cmd.ExecuteScalar().ToString();
}
}
}
Your SQL query syntax is wrong it should rather be below. You have a extra , after TOP 1 .. remove that
SELECT TOP 1 [Sender Name],[Subject] from [OLE DB Destination] WHERE...
Again in your button click you are just creating the command cmd = new SqlCommand(str, con); but never executing it. and just closing the connection.
In textBox2_TextChanged event handler you are trying to execute the query but connection has already gone. I think it's time you should consider reading about ADO.NET
This should do the trick. A couple of things to note:
since the button is executing your sql and populating the 2nd textbox, there's no need for the textbox_changed event
Using string concatenation to append your variables to your sql query is bad practice and makes your code susceptible to Sql Injection. Instead, parameterize your sql inputs as shown in the code below.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string query = "SELECT TOP 1,[Sender Name],[Subject] "
+ " from[OLE DB Destination] WHERE[CHAT #] = :chatId ";
using (SqlConnection con = new SqlConnection("Data Source=USHOU2016\\USFi;Initial Catalog=HOU_2016_Project;Integrated Security=True"))
{
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.AddWithValue("chatId", textBox1.Text); //use Sql parameters to protect yourself against Sql Injection!
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
textBox2.Text = reader[0] + " " + reader[1]; //or however you want your output formatted
}
reader.close();
}
}
}

Storing Selected CheckedListBox Values in Database

I have two tables in my database. Let's say table A and table B. table A values are put in checkedlistbox. The selected values in checkedlistbox then are put into table B. I tried to make a code however it wont work. Do you have any idea on how to make this problem work?
thanks ahead guys.
by the way im using c#.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Npgsql;
namespace WindowsFormsApplication1
{
public partial class Form8 : Form
{
public Form8()
{
InitializeComponent();
this.Load += Form8_Load;
button2.Click += button2_Click;
}
private void Form8_Load(object sender, EventArgs e)
{
string connstring = ("Server=localhost;Port=5432;User Id=postgres;Password=021393;Database=postgres;");
NpgsqlConnection conn = new NpgsqlConnection(connstring);
NpgsqlCommand cmd = new NpgsqlCommand("SELECT conname FROM condition", conn);
cmd.CommandType = CommandType.Text;
conn.Open();
using (NpgsqlDataAdapter da = new NpgsqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
da.Fill(dt);
((ListBox)checkedListBox1).DataSource = dt;
((ListBox)checkedListBox1).DisplayMember = "conname";
((ListBox)checkedListBox1).DisplayMember = "conid";
string[] condition = dt.Rows[0]["conname"].ToString().Split(',');
}
}
private void button2_Click(object sender, EventArgs e)
{
string connstring = ("Server=localhost;Port=5432;User Id=postgres;Password=021393;Database=postgres;");
NpgsqlConnection conn = new NpgsqlConnection(connstring);
NpgsqlCommand cmd = new NpgsqlCommand("Insert into famhistory(famid) Values (#famid)", conn);
conn.Open();
cmd.Parameters.AddWithValue("#famid", checkedListBox1.Text);
cmd.ExecuteNonQuery();
MessageBox.Show("Data has been saved");
conn.Close();
}
}
}
You have to iterate through all the selected items:
//check if any item is selected
if (checkedListBox1.SelectedItems.Count > 0)
{
//connect to database
string connstring = ("Server=localhost;Port=5432;User Id=postgres;Password=021393;Database=postgres;");
NpgsqlConnection conn = new NpgsqlConnection(connstring);
conn.Open();
//loop through all selected items
foreach (object item in checkedListBox1.CheckedItems)
{
//convert item to string
string checkedItem = item.ToString();
//insert item to database
NpgsqlCommand cmd = new NpgsqlCommand("Insert into famhistory(famid) Values (#famid)", conn);
cmd.Parameters.AddWithValue("#famid", checkedItem); //add item
cmd.ExecuteNonQuery();
}
//close connection
conn.Close();
MessageBox.Show("Data has been saved");
}
Note: I am executing all insert commands in one open connection, because opening and closing connection frequently is not best practice.

How to read and print out data from mysql in c#

My problem is that I can't print out all the data from the table in my mysql database, I got out just last row in the given table "teacher". is there anyone who can help me find the error?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
namespace ReadDataFromMysql
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string sql = " SELECT * FROM teacher ";
MySqlConnection con = new MySqlConnection("host=localhost;user=root;password=859694;database=projekt;");
MySqlCommand cmd = new MySqlCommand(sql, con);
con.Open();
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read()) {
data2txt.Text = reader.GetString("id");
datatxt.Text = reader.GetString("userId");
}
}
private void btnclose_Click(object sender, EventArgs e)
{
Close();
}
}
}
Your problem is that you are overwriting data2txt.Text and datatxt.Text on each row of data. if you want to see all of the data in those fields, something like this should do what you need:
data2txt.Text = string.Empty;
datatxt.Text = string.Empty;
while (reader.Read())
{
data2txt.Text += $"{reader.GetString("id")};";
datatxt.Text += $"{reader.GetString("userId")};";
}
You're assigning the value of each field instead of the value of the existing control's text plus the new value. Add a breakpoint to make sure you're getting multiple rows, but as your code is written, you would only see the result of one row in your form because you're overwriting on each iteration through the loop.
This code works.
private void getdata()
{
MySqlConnection connect = new MySqlConnection("SERVER=localhost; user id=root; password=; database=databasename");
MySqlCommand cmd = new MySqlCommand("SELECT ID, name FROM data WHERE ID='" + txtid.Text + "'");
cmd.CommandType = CommandType.Text;
cmd.Connection = connect;
connect.Open();
try
{
MySqlDataReader dr;
dr = cmd.ExecuteReader();
while(dr.Read())
{
txtID.Text = dr.GetString("ID");
txtname.Text = dr.GetString("name");
}
dr.Close();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if(connect.State == ConnectionState.Open)
{
connect.Close();
}
}
Obviously your code shows the last row values of teacher table into your text fields on form.Because your are looping throught the datareader and assigning the values to textfiled.So each iteration it will overwright the previous values in textbox.
You should output the data before again writing in it:
data2txt.Text = reader.GetString("id");
datatxt.Text = reader.GetString("userId");
Or use a var to store all the data in with each 'read' and then output that var
varexample.Text += reader.GetString("id");

Categories