insert into multiple tables without knowing the primary key - c#

Hey guys bit of a complication here, I have a create account page and it just inserts data into a mysql db:
protected void Button1_Click(object sender, EventArgs e)
{
OdbcConnection cn = new OdbcConnection("Driver={MySQL ODBC 3.51 Driver}; Server=localhost; Database=gymwebsite2; User=root; Password=commando;");
cn.Open();
OdbcCommand cmd = new OdbcCommand("INSERT INTO User (Email, FirstName, SecondName, DOB, Location, Aboutme, username, password) VALUES ('" + TextBox1.Text + "', '" + TextBox2.Text + "', '" + TextBox3.Text + "', '" + TextBox4.Text + "', '" + TextBox5.Text + "', '" + TextBox6.Text + "', '" + TextBox7.Text + "', '" + TextBox8.Text + "')", cn);
cmd.ExecuteNonQuery();
{
//e.Authenticated = true;
Response.Redirect("Login.aspx");
// Event useradded is true forward to login
}
}
}
But here is my problem on the create account page I have added a fileupload control and I would like to upload a image and save the imageurl in the pictures table:
string filenameDB = Path.GetFileName(FileUploadControl.FileName);
string fileuploadpath = Server.MapPath("~/userdata/" + theUserId + "/uploadedimage/") + Path.GetFileName(FileUploadControl.FileName);
FileUploadControl.SaveAs(fileuploadpath);
string fileuploadpaths = ("~/userdata/" + theUserId + "/uploadedimage/") + filenameDB;
StatusLabel.Text = "Upload status: File uploaded!";
OdbcCommand cmd = new OdbcCommand("INSERT INTO Pictures VALUES picturepath ='" + fileuploadpaths + "' WHERE UserId = '" + theuserid + "'", cn);
cmd.ExecuteNonQuery();
The first problem is the sql syntax I need to combine the fileupload with my buttonclick so it would be INSERT INTO two tables User and Pictures but the problem after that is how on earth do I get the userid if the account isnt created yet? AHHH lol
Table structure:
So to sum it up I need to Insert user details into the user table and upload to the project file AND insert the imageUrl into the pictures table (stored like so ~/userdata/2/uploadedimages/bla.jpg) as you can see the pictures table is a 1-1 relationship to the user table so its dependant on the userid which be4 the account is created there is no userid so not sure if there is a way to stagger the code so the user details are inserted first then use a session to retrieve that userid then insert the imageurl into the pictures table?
Or Maybe there is some funky function that some clever person has already came upon this issue or maybe its just a simple sql syntax decombobulator.
P.S I KNOW ABOUT THE SQL INJECTION RISKS, please do not post about this. Thanks guys!
EDIT:
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
try
{
OdbcConnection cn = new OdbcConnection("Driver={MySQL ODBC 3.51 Driver}; Server=localhost; Database=gymwebsite2; User=root; Password=commando;");
cn.Open();
OdbcCommand cmd = new OdbcCommand("INSERT INTO User (Email, FirstName, SecondName, DOB, Location, Aboutme, username, password) VALUES ('" + TextBox1.Text + "', '" + TextBox2.Text + "', '" + TextBox3.Text + "', '" + TextBox4.Text + "', '" + TextBox5.Text + "', '" + TextBox6.Text + "', '" + TextBox7.Text + "', '" + TextBox8.Text + "')", cn);
OdbcCommand sc = new OdbcCommand("SELECT LAST_INSERT_ID()", cn);
//convert LAST INSERT into string theUserId
string filenameDB = Path.GetFileName(FileUpload1.FileName);
string fileuploadpath = Server.MapPath("~/userdata/" + theUserId + "/uploadedimage/") + Path.GetFileName(FileUpload1.FileName);
FileUpload1.SaveAs(fileuploadpath);
string fileuploadpaths = ("~/userdata/" + theUserId + "/uploadedimage/") + filenameDB;
Label10.Text = "Upload status: File uploaded!";
OdbcCommand cm = new OdbcCommand("INSERT INTO Pictures (picturepath, UserId) VALUES ('" + fileuploadpaths + "', " + theUserId + ")", cn);
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
Label10.Text = "Upload status: The file could not be uploaded. The following error occured: " + ex.Message;
}
//e.Authenticated = true;
//Response.Redirect("Login.aspx");
// Event useradded is true forward to login
}
}
}

If pictures is 1:1 with users, is it possible to put the picture path in the user table?
If not, MySQL has a last_insert_id() function allowing you to get the last auto-increment value from a table (in this case User) - usually the primary key.

You need to return the new user id from your user insert. From the mysql auto increment docs:
You can retrieve the most recent
AUTO_INCREMENT value with the
LAST_INSERT_ID() SQL function or the
mysql_insert_id() C API function.
These functions are
connection-specific, so their return
values are not affected by another
connection which is also performing
inserts.
Anyway, you'll need to store this return and pass it into related operations.

I can't see your table structure, but is it as simple as inserting into the User table, retrieving the UserID, preserving the UserID (maybe passing to the upload page on the query string, or using session, etc), and then using that UserID in the Pictures table insert? Here's documentation on how to get the unique ID from an inserted row in MySQL.

Related

Cannot insert duplicate value into datatable when updating record from textbox

Trying to update records in my datatable using textboxes on a button click. The error message says is cannot insert a duplicate value, and shows the value that I have entered into txtID. This is the code for the update button:
private void btnUpdate_Click(object sender, EventArgs e)
{
connection.Open();
SqlCommand command = new SqlCommand();
String query = "UPDATE Bug SET Tester_ID=" + txtID.Text + "',Tester_Name= '" + txtName.Text + "',Application_Name= '" + txtApp.Text + "',Class_Name= '" + txtClass.Text + "',Line_No= '" + txtLineNo.Text + "',Error_Description= '" + txtDesc.Text + "',Source_Code= '" + txtSource.Text + "',Status= '" + txtStatus.Text + "')";
SqlDataAdapter adapter = new SqlDataAdapter(query, connection);
adapter.SelectCommand.ExecuteNonQuery();
connection.Close();
MessageBox.Show("Data Updated Successfully");
}
You do not have where clause in that query, so it is updating all records in the table, which is making some records duplicate. Hence the error.
The could be due to your defined table structure.
P.S. You should look for SQL injection attack and should parameterize your query to avoid it.
Edit based on your comment
String query = "UPDATE Bug Set Tester_Name= '" + txtName.Text + "',Application_Name= '" + txtApp.Text + "',Class_Name= '" + txtClass.Text + "',Line_No= '" + txtLineNo.Text + "',Error_Description= '" + txtDesc.Text + "',Source_Code= '" + txtSource.Text + "',Status= '" + txtStatus.Text + "' WHERE Tester_ID='" + txtID.Text + "'";
If Tester_Id is numeric, you don't need those quotes.
Where clause comes after Set.
Here is the Parameterized version:
String query = "UPDATE Bug Set Tester_Name=#Tester_Name,Application_Name= #AppName,Class_Name= #Class_Name,Line_No= #Line_No,Error_Description= #Error_Description,Source_Code= #Source_Code,Status= #Status WHERE Tester_ID=#Tester_ID";
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("#Tester_Name", "XYZ");
// other params
command.Parameters.AddWithValue("#Tester_ID", 10);

Data type mismatch in criteria expression Oledb Access database

I'm getting the error:
Data type mismatch in criteria expression
When using this code. And using Access database.
OleDbConnection bab = new OleDbConnection();
bab.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\sdega\OneDrive\school\Werknemersdata.accdb;Persist Security Info=False;";
bab.Open();
try
{
OleDbCommand kaas = new OleDbCommand();
kaas.Connection = bab;
kaas.CommandText = "insert into Werknemersdata (Naam, Adres, Postcode, Woonplaats, Salaris) values ('" + txtNaam.Text + "', '" + txtAdress.Text + "', '" + txtpostcode1.Text + " " +txtpostcode2.Text + "', '" + txtwoonplaats.Text + "', '" + txtsalaris.Text + "') ";
kaas.ExecuteNonQuery(); // this is where it goes wrong
txtStatus.BackColor = Color.Green;
MessageBox.Show("data saved");
bab.Close();
}
catch (Exception ghakbal)
{
MessageBox.Show("Error" + ghakbal);
}
You missed one ' after '" + txtpostcode1.Text + " and one before " +txtpostcode2.Text + "' and also one , between them. It should be like this:
'" + txtpostcode1.Text + "' , '" +txtpostcode2.Text + "',
Also I strongly recommend that you always use parameterized queries to avoid SQL Injection. Like this:
kaas.CommandText = "insert into Werknemersdata (Naam, Adres, Postcode, Woonplaats, Salaris) values (?, ? ,.....");
kaas.Parameters.AddWithValue("Naam", txtNaam.Text);
kaas.Parameters.AddWithValue("Adres", txtAdress.Text);
//And other parameters...
Also It would be better to specify the type directly and use the Value property. Read more here.

C# to Access - Inserting a ComboBox to Access column

I'm not getting any errors and I'm a bit lost on where to look to solve the problem (my first project - Probably way over my head heh). The Amount and Settlement amount both save to the table but the combobox options aren't saving. The Access fields are set to Short Text (if that helps).
I'm not looking for a hand me out but rather if someone could point me in the right direction to get this solved.
private void btnSubmit_Click(object sender, EventArgs e)
{
try
{
connection.Open();
//converting data entered to be imported into Access tblePayments
string EmployeeConverted;
double AmountConverted;
string ClientConverted;
string PaymentMethodConverted;
string PaymentTypeConverted;
string MonthConverted;
int SettlementConverted;
EmployeeConverted = Convert.ToString(cboxEmployee.SelectedValue);
AmountConverted = Convert.ToDouble(txtAmount.Text);
ClientConverted = Convert.ToString(cboxClient.SelectedValue);
PaymentMethodConverted = Convert.ToString(cboxPaymentMethod.SelectedValue);
PaymentTypeConverted = Convert.ToString(cboxPaymentType.SelectedValue);
MonthConverted = Convert.ToString(cboxMonth.SelectedValue);
SettlementConverted = Convert.ToInt32(txtSettlement.Text);
//inserting converted data into Access
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = "insert into tblePayments (Employee, AmountofPayment, Client, PaymentMethod, PaymentType, MonthofPayment, Settlement) values('" + EmployeeConverted + "', " + AmountConverted + ", '" + ClientConverted + "', '" + PaymentMethodConverted + "', '" + PaymentTypeConverted + "', '" + MonthConverted + "', " + SettlementConverted + ")";
command.ExecuteNonQuery();
MessageBox.Show("Payment Saved");
connection.Close();
}
catch (Exception error)
{
MessageBox.Show("Error: " + error);
}

forgot password query failure due to multiple 'and' & or 'claws'

<TD>
con.Open();
string sql = "select password from Login_user where user_name='" + txtname.Text + "' and mobile='" + txtmob.Text + "' and security_question='" + cmbquestion.SelectedText + "' and answer='" + txtanswer.Text + "' || user_name='" + txtname.Text + "' and dob='" + dateTimePicker1.Value.ToString() + "' and security_question='" + cmbquestion.SelectedText + "' and answer='" + txtanswer.Text + "'";
//string sql1 = "select password from Login_user where user_name='" + txtname.Text + "' and mobile='" + txtmob.Text + "' and security_question='" + cmbquestion.SelectedText + "' and answer='" + txtanswer.Text + "'";
cmd = new SqlCommand(sql, con);
dr = cmd.ExecuteReader();
if (dr.Read() == true)
{
MessageBox.Show("Your Password is : " + dr.GetString(0) + ".", "SUCCESSFUL !", MessageBoxButtons.OK, MessageBoxIcon.Information);
con.Close();
this.Hide();
Form1 f = new Form1();
f.Show();
}
else
{
MessageBox.Show("NOT found");
}
con.Close();
dr.Close();
</TD>
i have given a c# code where i have taken query to show a password in a password recovery form and i want all the fields to be compulsory, but only the two fields that are mobile and dob will be either or condition.so any one of them will be given to submit.what will be the code please provide me the correct query for this functionality.
You need to group mobile and dob together within parenthesis and an OR clause.
Besides that, you really need to structure your query so it can be read easier and use parameters for better security and performance.
Try this:
string sql = #"
select password
from Login_user
where user_name=#user_name
and (
mobile=#mobile
OR
dob=#dob
)
and security_question=#security_question
and answer=#answer ";
cmd.Paramaters.AddWithValue("#user_name", txtname.Text);
cmd.Paramaters.AddWithValue("#mobile", txtmob.Text);
cmd.Paramaters.AddWithValue("#answer", txtanswer.Text);
cmd.Paramaters.AddWithValue("#security_question", cmbquestion.SelectedText);
cmd.Paramaters.AddWithValue("#dob", dateTimePicker1.Value.ToString());

insert statement wont work

Hey guys I get no errors from my code but nothing seems to happen when i try my insert statement below?
Not sure if its how I wrapped my textbox or if its my FriendID query string?
protected void Button1_Click(object sender, EventArgs e)
{
string friendid = Request.QueryString["FriendID"];
string theUserId = Session["UserID"].ToString();
using (OdbcConnection cn = new OdbcConnection("Driver={MySQL ODBC 3.51 Driver}; Server=localhost; Database=***; User=***; Password=***;"))
{
cn.Open();
using (OdbcCommand cmd = new OdbcCommand("INSERT INTO WallPosting (UserID, Wallpostings, FriendUserID) VALUES (" + friendid + ", '" + TextBox1.Text + "', " + theUserId + ")", cn))
{
cmd.ExecuteNonQuery();
}
}
PopulateWallPosts(friendid);
}
}
You switched your variables, according to the field names it should be:
using (OdbcCommand cmd = new OdbcCommand("INSERT INTO WallPosting (UserID, Wallpostings, FriendUserID) VALUES (" + theUserId + ", '" + TextBox1.Text + "', " + friendid + ")", cn))
New record has been added, but for the wrong user so you didn't find it later when reloading the posts.
As you've been told already deal with the SQL Injection risk by using Parameters instead of directly adding the values to the SQL string.
"INSERT INTO WallPosting (UserID, Wallpostings, FriendUserID) VALUES (" + friendid + ", '" + TextBox1.Text + "', " + theUserId + ")"
becomes
"INSERT INTO WallPosting (UserID, Wallpostings, FriendUserID) VALUES ('" + friendid + "', '" + TextBox1.Text + "', '" + theUserId + "')"
Have to qualify the strings using single quotes. otherwise they are treated as variables by the parser.

Categories

Resources