MySqlDataReader executes command, but reader.Read() outputs error message - c#

I do not really know how to ask this well, but will try to describe.
I have created a mysql command, that should insert data into a table and it does exactly what I want, but if statement reader.Read() jumps into an error saying it failed to create the user, even though the user was created.
Why is this happening?
private void iconButton1_Click(object sender, EventArgs e)
{
//create user in mysql
MySqlConnection conn = new MySqlConnection(#"SERVER=localhost;DATABASE=sklad;UID=root;PASSWORD=;");
conn.Open();
MySqlCommand cmd = new MySqlCommand("INSERT INTO users (username, password, role) VALUES ('" + username.Text + "', '" + password.Text + "', '" + role.Text + "') ", conn);
MySqlDataReader reader = cmd.ExecuteReader();
if(reader.Read())
{
MessageBox.Show("Uživatel vytvořen!", "E-Skladovka.cz - Uživatel vytvořen", MessageBoxButtons.OK);
}
else
{
MessageBox.Show("Failed to create user");
}
reader.Close();
cmd.Dispose();
conn.Close();
}
I tried to search, but as long as I do not know how to ask properly, I can not search properly.

Related

Invalid object name 'Main' error when inserting into Database - C# (WebForms), MySql

I know plenty of people have these issues, and I've actually tried to implement some of the suggestions to my code, however I'm getting errors that just don't make sense to me. This is my first time implementing database calls to my code. Can someone please tell me what I'm doing wrong? The following error pops up: ERROR: Invalid object name 'Main'. This is actually triggered by my exception so at least something is working. Otherwise, I don't know what the issue is. On the DB end, I have (username VARCHAR, email VARCHAR and number NCHAR) Please see the code below
static string path = Path.GetFullPath(Environment.CurrentDirectory);
static string databaseName = "u_DB.mdf";
string connectionString = #"Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=" + path + #"\" + databaseName + "; Integrated Security=True;";
private void button1_Click(object sender, EventArgs e)
{
// string query = "INSERT INTO UserInfo '" + textBox1.Text + "' and password = '" + textBox2.Text + "'";
string query = "insert into Main ([username], [email], [number]) values(#username,#email,#number)";
using (SqlConnection con = new SqlConnection(connectionString))
{
try
{
con.Open();
using (SqlCommand cmd = new SqlCommand(query, con))
{
cmd.Parameters.Add("#username", SqlDbType.VarChar).Value = textBox3.Text;
cmd.Parameters.Add("#email", SqlDbType.VarChar).Value = textBox2.Text;
cmd.Parameters.AddWithValue("#number", SqlDbType.VarChar).Value = textBox1.Text;
int rowsAdded = cmd.ExecuteNonQuery();
if (rowsAdded > 0)
MessageBox.Show("Added to Database");
else
MessageBox.Show("Nothing was added");
}
}
catch (Exception ex)
{
MessageBox.Show("ERROR: " + ex.Message);
}
con.Close();
}
}
Firstly, as Chetan assumed, do you have a main table?
The syntax of the query you are using is :
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
Furthermore,
AddWithValue(string parameterName, object value (<== The actual value to insert!));
in your case
AddWithValue("#number", textBox1.Text);
is enough.

Connection must be valid and open SQL

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 :)

DataReader Associated with this Command Error

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

Invalid attempt to call read when reader is closed when inserting data

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.

Why I get syntax error in this update statement?

I wanted to update a table in my m/s access database where my the user entered a new password in order to replace the old one but i have syntax error in the update statement. Please help!
public partial class resetPassword : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void SubmitButton_Click(object sender, EventArgs e)
{
string userName = (string) Session["username"];
string str = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\inetpub\wwwroot\JetStar\database\JetstarDb.accdb";
var con = new OleDbConnection(str);
con.Open();
string pwd = Request.Form["conPassword"];
OleDbCommand cmd = new OleDbCommand("UPDATE [users] SET password = '" + pwd + "' WHERE username = '" + userName + "'", con);
try
{
cmd.ExecuteNonQuery();
MessageBox.Show("Your password has been changed successfully.");
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
con.Close();
}
}
}
Probably this happends because password is a reserved keyword on Microsoft Access. You should use it with square brackets as [password]
But more important
You should always use parameterized queries. This kind of string concatenations are open for SQL Injection attacks.
Don't store your passwords as a plain text. Read: Best way to store password in database
Use using statement to dispose your OleDbConnection and OleDbCommand.
using(OleDbConnection con = new OleDbConnection(str))
using(OleDbCommand cmd = con.CreateCommand())
{
cmd.CommandText = "UPDATE [users] SET [password] = ? WHERE username = ?";
cmd.Parameters.Add("pass", OleDbType.VarChar).Value = pwd;
cmd.Parameters.Add("user", OleDbType.VarChar).Value = userName;
con.Open();
try
{
cmd.ExecuteNonQuery();
MessageBox.Show("Your password has been changed successfully.");
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
}
92.3% (a) of all DB problems become obvious if you just print the command before you use it, and read the error message.
So replace:
OleDbCommand cmd = new OleDbCommand("UPDATE [users] SET password = '" + pwd + "' WHERE username = '" + userName + "'", con);
with something like:
String s = "UPDATE [users] SET password = '" + pwd + "' WHERE username = '" + userName + "'";
Console.WriteLine(s);
OleDbCommand cmd = new OleDbCommand(s, con);
Then post the results of:
Response.Write(ex.Message);
for all to see, and examine what it tells you very carefully.
(a) A statistic I just plucked out of nowhere - actual value may be wildly different.

Categories