OleDbConnection baglanti =
new OleDbConnection("connect");
OleDbCommand komut = new OleDbCommand();
OleDbDataReader dr;
DataSet ds = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if(textBox1.Text=="" || textBox2.Text=="" || textBox3.Text=="" || maskedTextBox1.Text=="" || dateTimePicker1.Text=="" || maskedTextBox2.Text=="" || textBox6.Text=="")
{
MessageBox.Show("Lütfen Boş alanları doldurunuz !!");
}
else
{
baglanti.Open();
komut.Connection = baglanti;
komut.CommandText=("Select TcKimlik from Hasta");
dr = komut.ExecuteReader();
while(dr.Read())
{
if(dr["TcKimlik"].ToString()==textBox1.Text.ToString())
{
MessageBox.Show("aaaaa");
}
else
{
komut.CommandText = ("insert into Hasta (TcKimlik,h_adı,h_soyadı,tel_no,ran_tar,ran_saati,sikayet_nedeni) values('" + textBox1.Text.ToString() + "','" + textBox2.Text.ToString() + "','" + textBox3.Text.ToString() + "','" + maskedTextBox1.Text.ToString() + "','" + dateTimePicker1.Text.ToString() + "','" + maskedTextBox2.Text.ToString() + "','" + textBox6.Text.ToString() + "')");
komut.ExecuteNonQuery();
MessageBox.Show("Kayıt Başarı İle Tamamlandı", "Kayıt Başarılı", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
baglanti.Close();
textBox1.Clear();
textBox2.Clear();
textBox3.Clear();
maskedTextBox1.Clear();
maskedTextBox2.Clear();
textBox6.Clear();
}
}
I have tried a lot of ways but I could not go to a solution. If I check the data or make dr.Close() before registering the data, I can save the data, but then I get an error because I close the data reader prematurely.
I want to check the data in the database but I get an error like below.
Associated with this Command, there is already an explicit DataReader that should be closed first.
Issue with you code is you are making use of Command object for performing reading and inserting record at one time.
you require to perform operation one by one , you cannot do both in one time. so you code should be like this
using (OleDbconnection connection = new OleDbconnection (ConnectionString))
{
connection.Open();
OleDbCommand select = new OleDbCommand("..selecte query",connection);
OleDbDataReader reader = select.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
//read data you want
//you might not need another connection , but i added to seperate it , you can reuse connection you created and perfrom update
using(OleDbconnection connection1 = new OleDbconnection (ConnectionString))
{
OleDbCommand insert= new OleDbCommand ("..insertquery", connection1);
insert.ExecuteNonQuery();
}
}
}
reader.Close();
}
}
you can use command object to perfrom multiple task but it should be one by one , example
//first complete reading and close reader
//second do insert operation complete it
//third do update operation
One more suggstion make use of Parameter as your insert query is open for sql injection attack, if you go with parameterise query can resolve that issue
Related
There was a problem. I checked the connection to the database - everything works.
But when I try to check the lines in the database, then the error pops up:
System.InvalidOperationException: "Connection must be valid and open." c#
How can i fix this?
private void button1_Click(object sender, EventArgs e)
{
try
{
MySqlConnection conn = GetDBConnection();
conn.Open();
MySqlCommand selectCommand = new MySqlCommand("SELECT * FROM 'rcc_base' WHERE login='" + this.textBox1.Text + "', pass='" + this.textBox2.Text + "' ;");
MySqlDataReader myReader;
MessageBox.Show("Connection...");
myReader = selectCommand.ExecuteReader();
int count = 0;
while (myReader.Read())
{
count = count + 1;
}
if (count == 1)
{
MessageBox.Show("All nice");
}
else
{
MessageBox.Show("Login failed");
}
conn.Close();
}
catch (Exception)
{
MessageBox.Show("Error");
}
}
In your MySqlCommand you are not using your MySqlConnection :( .So change it as follows
MySqlCommand selectCommand = new MySqlCommand("SELECT * FROM rcc_base WHERE 'login' ='" + this.textBox1.Text + "' AND 'pass' ='" + this.textBox2.Text + "' ;",conn);
Also , create a new instance of the MySqlConnection like :
MySqlConnection conn = new MySqlConnection;
conn = GetDBConnection();
And a few suggestions:Your code is not good.Don't give direct values to columns in the SqlCommand rahter pass parameters like #abc , this will also prevent sql-injections.Sample :
MySqlCommand selectCommand = new MySqlCommand("SELECT COUNT(*) FROM rcc_base WHERE login=#username AND pass=#password;",conn);
selectCommand.Parameters.Add("#username",MySqlDbType.VarChar).Value = textBox1.Text;
selectCommand.Parameters.Add("#password",MySqlDbType.VarChar).Value = textBox2.Text;
///Now to check if data exists in the database or not
int count = Convert.ToInt32(selectCommand.ExecuteScalar());
if(count > 0)
{
///data exists-login successful
}
else
{
///data doesn't exists , login failed
}
Also you should open the connection on form load so that you can access the database throughout the class/form.It is a better way to do it :)
i have a button that when clicked inserts data from textbox and combobox fields into database tables, but every time i insert it gives me "Invalid attempt to call read when reader is closed". How can i get rid of this error. And tips on optimising the code are welcome, because i know im a total noob. thanks
private void btnSave_Click(object sender, RoutedEventArgs e)
{
try
{
SqlConnection sqlCon = new SqlConnection(#"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query1 = "insert into location(Storage, Shelf, columns, rows) values(" + txtWarehouse.Text + ", " + txtShelf.Text + ", " + txtColumn.Text + ", " + txtRow.Text + ")";
SqlCommand sqlCmd = new SqlCommand(Query1, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
sqlCon.Close();
}
catch (Exception er)
{
MessageBox.Show(er.Message);
}
try
{
SqlConnection sqlCon = new SqlConnection(#"Data Source=(localdb)\mssqllocaldb; Initial Catalog=Storagedb;");
sqlCon.Open();
string Query3 = "SELECT LOCATION_ID FROM LOCATION WHERE storage='" + txtWarehouse.Text + "' AND shelf='" + txtShelf.Text + "' AND columns='"
+ txtColumn.Text + "' AND rows='" + txtRow.Text + "'";
SqlCommand sqlCmd1 = new SqlCommand(Query3, sqlCon);
SqlDataReader dr = sqlCmd1.ExecuteReader(); ;
while (dr.Read())
{
string LocationId = dr[0].ToString();
dr.Close();
string Query2 = "insert into product(SKU, nimetus, minimum, maximum, quantity,location_ID,category_ID,OrderMail_ID) values ('" + txtSku.Text + "','" + txtNimetus.Text + "', '"
+ txtMin.Text + "', '" + txtMax.Text + "', '" + txtQuan.Text + "', '" + LocationId + "', '" + (cbCat.SelectedIndex+1) + "', '" + (cbMail.SelectedIndex+1) + "')";
SqlCommand sqlCmd = new SqlCommand(Query2, sqlCon);
SqlDataAdapter dataAdp = new SqlDataAdapter(sqlCmd);
dataAdp.SelectCommand.ExecuteNonQuery();
}
sqlCon.Close();
}
catch (Exception ed)
{
MessageBox.Show(ed.Message);
}
}
Let's try to make some adjustments to your code.
First thing to consider is to use a parameterized query and not a
string concatenation when you build an sql command. This is mandatory
to avoid parsing errors and Sql Injections
Second, you should encapsulate the disposable objects in a using statement
to be sure they receive the proper disposal when you have finished to
use them.
Third, you can get the LOCATION_ID from your table without running a
separate query simply adding SELECT SCOPE_IDENTITY() as second batch to your first command. (This works only if you have declared the LOCATION_ID field in the first table as an IDENTITY column)
Fourth, you put everything in a transaction to avoid problems in case
some of the code fails unexpectedly
So:
SqlTransaction tr = null;
try
{
string cmdText = #"insert into location(Storage, Shelf, columns, rows)
values(#storage,#shelf,#columns,#rows);
select scope_identity()";
using(SqlConnection sqlCon = new SqlConnection(.....))
using(SqlCommand cmd = new SqlCommand(cmdText, sqlCon))
{
sqlCon.Open();
using( tr = sqlCon.BeginTransaction())
{
// Prepare all the parameters required by the command
cmd.Parameters.Add("#storage", SqlDbType.Int).Value = Convert.ToInt32(txtWarehouse.Text);
cmd.Parameters.Add("#shelf", SqlDbType.Int).Value = Convert.ToInt32(txtShelf.Text);
cmd.Parameters.Add("#columns", SqlDbType.Int).Value = Convert.ToInt32(txtColumn.Text );
cmd.Parameters.Add("#rows", SqlDbType.Int).Value = Convert.ToInt32(txtRow.Text);
// Execute the command and get back the result of SCOPE_IDENTITY
int newLocation = Convert.ToInt32(cmd.ExecuteScalar());
// Set the second command text
cmdText = #"insert into product(SKU, nimetus, minimum, maximum, quantity,location_ID,category_ID,OrderMail_ID)
values (#sku, #nimetus,#min,#max,#qty,#locid,#catid,#ordid)";
// Build a new command with the second text
using(SqlCommand cmd1 = new SqlCommand(cmdText, sqlCon))
{
// Inform the new command we are inside a transaction
cmd1.Transaction = tr;
// Add all the required parameters for the second command
cmd1.Parameters.Add("#sku", SqlDbType.NVarChar).Value = txtSku.Text;
cmd1.Parameters.Add("#nimetus",SqlDbType.NVarChar).Value = txtNimetus.Text;
cmd1.Parameters.Add("#locid", SqlDbType.Int).Value = newLocation;
.... and so on for the other parameters required
cmd1.ExecuteNonQuery();
// If we reach this point the everything is allright and
// we can commit the two inserts together
tr.Commit();
}
}
}
}
catch (Exception er)
{
// In case of exceptions do not insert anything...
if(tr != null)
tr.Rollback();
MessageBox.Show(er.Message);
}
Notice that in the first command I use parameters of type SqlDbType.Int because you haven't used single quotes around your text. This should be verified against the real data type of your table columns and adjusted to match the type. This is true as well for the second command where you put everything as text albeit some of those fields seems to be integer (_location_id_ is probably an integer). Please verify against your table.
I am not getting, how to do insert and update of the data in C# WinForms on single button click.
private void save_Click(object sender, EventArgs e)
{
SqlConnection cn = new SqlConnection();
cn.ConnectionString = "data source=Sai;database=kaur; user id=sa;password=azxc;";
cn.Open();
string gen;
if (radioButton1.Checked == true)
gen = "Male";
else
gen = "Female";
string clas = null;
clas = comboBox1.Text;
string section = null;
section = comboBox2.Text;
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "insert into studetail values('" + textBox1.Text + "','" + textBox2.Text + "','" + gen + "','" + textBox3.Text + "','" + clas + "','" + section + "')";
cmd.Connection = cn;
int n = cmd.ExecuteNonQuery();
if (n > 0)
MessageBox.Show(n + " Row Inserted.");
else
MessageBox.Show("Insertion failed.");
SqlDataAdapter da = new SqlDataAdapter("select * from studetail ", cn);
DataTable dt = new DataTable();
da.Fill(dt);
dataGridView1.DataSource = dt;
You can add a deletion before the insertion:
private void save_Click(object sender, EventArgs e)
{
DeletePerson(id); // add this
SqlConnection cn = new SqlConnection();
...
}
public void DeletePerson(int id)
{
using(SqlConnection connection = new SqlConnection(credentials))
{
connection.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = connection;
cmd.CommandText = "delete from studetail where someUniqeIdColumn = " + id;
cmd.ExecuteNonQuery();
}
}
Using responsible to dispose the connection.
Consider using Entity Framework or LINQ to SQL.
You are exposed to SQL injection.
First off the SQL query isn't quite right. It should look something like the following:
INSERT INTO studetail (columnName1, columnName2, ...columnNameN)
VALUES (value1, value2, ...valueN);
Where the column names are the columns where you want data to be inserted, and the values are the data you want inserted into said columns.
You should also be disposing the connection by wrapping the connection within a using statement.
using(var con = new SqlConnection(connectionString))
{
con.Open();
//rest of code that needs a connection here
}
Additionally, you need to be wary of SQL injection. I highly suggest reading this example from the MSDN website. It will give you an example of using an SQL Update and avoiding SQL injection with use of SqlCommand.Paramaters property.
You should also have a Primary Key in your database tables, if you don't already, so you can uniquely identify each record in a table.
To do an update and a save on the same button, you will need to check if a row already exists for the data that is being edited. This when a Primary comes in handy. You will want to check your database to see if a record already exists
SELECT 1 FROM studetail WHERE <Condition>
The WHERE condition will be the way you uniquely identify (a Primary Key) a row in your table. If the rows in the table are uniquely identified, the above SQL statement will return 1 if a value exists, which means you can UPDATE or 0 if no record exists, so you can INSERT
Can anyone help me on how to avoid getting duplicated output on DataGridView. Here is the image Before change and the image After add/edit or delete.
Here is the loader for my DataGridView:
private DataTable data()
{
using (OleDbConnection con = new OleDbConnection(inventorydb))
{
using (OleDbCommand com = new OleDbCommand("Select * FROM Items",con))
{
con.Open();
OleDbDataReader reader = com.ExecuteReader();
items.Load(reader);
}
}
return items;
}
void reset()
{
connect.Close();
connect.ConnectionString = inventorydb;
connect.Open();
dataGridView1.DataSource = null;
dataGridView1.Update();
dataGridView1.Refresh();
dataGridView1.DataSource = data();
}
Add and save changes:
private void save_Click(object sender, EventArgs e)
{
if (mode == "a")
{
connect.Close();
connect.ConnectionString = inventorydb;
connect.Open();
sqlcommand.CommandText = "INSERT INTO Items (SerialID, Brand_Name, Item_Name,Item_Date) VALUES ('" + txtserial.Text + "','" + txtbrand.Text + "', '" + txtitem.Text + "', '" + date + "') ";
sqlcommand.Connection = connect;
OleDbDataReader reader = sqlcommand.ExecuteReader();
MessageBox.Show("Record(s) Saved", "Sample");
}
connect.Close();
reset();
}
DataTable.Load adds result to the existing rows by default. So if you need to just have latest records, before calling DataTable.Load, you should clear the DataTable, otherwise the new result will be merged with existing rows.
So with your items variable which is DataTable, you can use either of these options:
items= new DataTable();
or
items.Clear();
items.AcceptChanges();
DataTable.Load
Fills a DataTable with values from a data source using the supplied
IDataReader. If the DataTable already contains rows, the incoming
data from the data source is merged with the existing rows.
private void button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = "Data Source=asa-PC\\SQLEXPRESS;Initial Catalog=table1;Integrated Security=True";
con.Open();
SqlCommand cmd = new SqlCommand("select * from worker where number='" + textBox1.Text.Trim() + "'", con);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
textBox2.Text = dr[0].ToString();
textBox3.Text = dr[1].ToString();
MessageBox.Show("No record is found with this number >> " + textBox1.Text.ToString());
}
}
}
}
hello guys can you help me with this
i need the MessageBox to show this message if No record is found but i don't know how to include the IF with the code
and a max numbers or letters for textbox1 is 10 if the user put more then the MessageBox (max10) will appear
You can use SqlDataReader.HasRows property to determine whether any records were returned. like:
if (dr.HasRows)
{
while (dr.Read())
{
textBox2.Text = dr[0].ToString();
textBox3.Text = dr[1].ToString();
}
}
else
{
MessageBox.Show("No record is found with this number >> " + textBox1.Text.ToString());
}
But couple of other things to add:
Use SqlParamaters instead of concatenation queries, you are open to SQL Injection.
Not really sure how would you accomplish showing more than one record in TextBox controls you probably need a Grid or add your returned rows/recrods to a List<T> or List<Worker> where Worker class can have properties for columns.
Use using statement with SqlCommand/SqlConnection and SqlDataReader as they implement IDisposable
this dr[0].ToString() could potentially throw Null Reference Exception, research and see how you can safeguard it.
So your code more or less should look like:
private void button1_Click(object sender, EventArgs e)
{
using (SqlConnection con = new SqlConnection())
{
con.ConnectionString = "Data Source=asa-PC\\SQLEXPRESS;Initial Catalog=table1;Integrated Security=True";
con.Open();
using (SqlCommand cmd = new SqlCommand("select * from worker where number=#Number", con))
{
cmd.Parameters.AddWithValue("#Number", textBox1.Text);//or explicity specify type using .Add
using (SqlDataReader dr = cmd.ExecuteReader())
{
if (dr.HasRows)
{
while (dr.Read())
{
//Add to List<Worker> with properties Name and Number etc
textBox2.Text = dr[0].ToString();
textBox3.Text = dr[1].ToString();
}
}
else
{
MessageBox.Show("No record is found with this number >> " + textBox1.Text.ToString());
}
}
}
}
}