I see 5 records to be inserted, but only 4 are inserted. The last record is not inserted, and I can not figure out why. Copying from one database to the other. First is an access database, the second is a sql server database.
OleDbCommand cmd2 = new OleDbCommand();
OleDbDataReader oledbReader2;
using (cmd2 = new OleDbCommand())
{
query = "SELECT ID, STRAATNAAM, 'NL' AS TAALCODE, PKANCODE, CITY FROM Temp_Unique_Streetnames WHERE TRIM(Temp_Unique_Streetnames.STRAATNAAM) <> '' AND ID > " + lastId.ToString() + " ORDER BY ID";
WriteToFile(query);
cmd2.CommandText = query;
cmd2.CommandType = CommandType.Text;
cmd2.Connection = cn2;
using (oledbReader2 = cmd2.ExecuteReader())
{
while (oledbReader2.Read())
{
try
{
counter += 1;
query = "insert into tblgeo_street ( autoid, street_id, language, country, city, streetname, zip) values (" + counter.ToString() +
" , " + oledbReader2.GetValue(0).ToString() +
" , 'NL', 23, " + oledbReader2.GetValue(4).ToString() +
" , '" + oledbReader2.GetValue(1).ToString().Replace('\'', '´') + "'" +
" , " + oledbReader2.GetValue(3).ToString() + ") ";
OleDbCommand cmd3 = new OleDbCommand(query, cn3);
WriteToFile(query);
cmd3.ExecuteNonQuery();
}
catch (Exception errorException)
{
actionSucceedded = false;
//eventLog1.WriteEntry("Open db threw exception " + errorException.Message);
WriteToFile("insert tblgeo_street threw exception " + errorException.Message);
}
}
}
}
i would like to insert multiple data into my database. I am using for-each statement to get the data and when i insert into the database, it generates 10(just a random no. depending on the no. of data i retrieved) rows for me with one data in every row instead of all in one row. here is the for-each statement i am using.
foreach(var kiev in dict)
{
string na = kiev.Key;
if(na != "db_table_name")
{
string quer = "insert into " + HttpContext.Current.Session["tablename"].ToString() + " ( " + kiev.Key + " ) VALUES ( '" + kiev.Value + "' ) ";
SqlCommand cl = new SqlCommand(quer, con);
cl.ExecuteNonQuery();
}
}
There are better options like "SqlBulkCopy" available as already mentioned in the comments but also something like this should work:
string tablename = "";
string values = "";
string keys = "";
foreach(var kiev in dict)
{
string na = kiev.Key;
if(na != "db_table_name")
{
keys += kiev.Key + ", ";
values += "'" + kiev.Value + "', ";
}
}
keys = keys.Remove(keys.Length - 2);
values = values.Remove(values.Length - 2);
string quer = "insert into " + HttpContext.Current.Session["tablename"].ToString() + " ( " + keys + " ) VALUES ( " + values + " ) ";
SqlCommand cl = new SqlCommand(quer, con);
cl.ExecuteNonQuery();
I am using these lines of code to check if the record exists or not.
SqlCommand check_User_Name = new SqlCommand("SELECT * FROM Table WHERE ([user] = '" + txtBox_UserName.Text + "') ", conn);
int UserExist = (int)check_User_Name.ExecuteScalar();
But I am getting an error:
Object reference not set to an instance of an object.
I want to do:
if (UserExist > 0)
// Update record
else
// Insert record
ExecuteScalar returns the first column of the first row. Other columns or rows are ignored. It looks like your first column of the first row is null, and that's why you get NullReferenceException when you try to use the ExecuteScalar method.
From MSDN;
Return Value
The first column of the first row in the result set, or a null
reference if the result set is empty.
You might need to use COUNT in your statement instead which returns the number of rows affected...
Using parameterized queries is always a good practise. It prevents SQL Injection attacks.
And Table is a reserved keyword in T-SQL. You should use it with square brackets, like [Table] also.
As a final suggestion, use the using statement for dispose your SqlConnection and SqlCommand:
SqlCommand check_User_Name = new SqlCommand("SELECT COUNT(*) FROM [Table] WHERE ([user] = #user)" , conn);
check_User_Name.Parameters.AddWithValue("#user", txtBox_UserName.Text);
int UserExist = (int)check_User_Name.ExecuteScalar();
if(UserExist > 0)
{
//Username exist
}
else
{
//Username doesn't exist.
}
The ExecuteScalar method should be used when you are really sure your query returns only one value like below:
SELECT ID FROM USERS WHERE USERNAME = 'SOMENAME'
If you want the whole row then the below code should more appropriate.
SqlCommand check_User_Name = new SqlCommand("SELECT * FROM Table WHERE ([user] = #user)" , conn);
check_User_Name.Parameters.AddWithValue("#user", txtBox_UserName.Text);
SqlDataReader reader = check_User_Name.ExecuteReader();
if(reader.HasRows)
{
//User Exists
}
else
{
//User NOT Exists
}
sqlConnection.Open();
using (var sqlCommand = new SqlCommand("SELECT COUNT(*) FROM Table WHERE ([user] = '" + txtBox_UserName.Text + "'", sqlConnection))
{
SqlDataReader reader = sqlCommand.ExecuteReader();
if (reader.HasRows)
{
lblMessage.Text ="Record Already Exists.";
}
else
{
lblMessage.Text ="Record Not Exists.";
}
reader.Close();
reader.Dispose();
}
sqlConnection.Close();
MySqlCommand cmd = new MySqlCommand("select * from table where user = '" + user.Text + "'", con);
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
DataSet ds1 = new DataSet();
da.Fill(ds1);
int i = ds1.Tables[0].Rows.Count;
if (i > 0) {
// Exist
}
else {
// Add
}
I would use the "count" for having always an integer as a result
SqlCommand check_User_Name = new SqlCommand("SELECT count([user]) FROM Table WHERE ([user] = '" + txtBox_UserName.Text + "') " , conn);
int UserExist = (int)check_User_Name.ExecuteScalar();
if (UserExist == 1) //anything different from 1 should be wrong
{
//Username Exist
}
try this
public static bool CheckUserData(string phone, string config)
{
string sql = #"SELECT * FROM AspNetUsers WHERE PhoneNumber = #PhoneNumber";
using (SqlConnection conn = new SqlConnection(config)
)
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("#PhoneNumber", phone);
SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection);
if (reader.HasRows)
{
return true; // data exist
}
else
{
return false; //data not exist
}
}
}
}
Use try catch:
try
{
SqlCommand check_User_Name = new SqlCommand("SELECT * FROM Table WHERE ([user] = '" + txtBox_UserName.Text + "') ", conn);
int UserExist = (int)check_User_Name.ExecuteScalar();
// Update query
}
catch
{
// Insert query
}
You can write as follows:
SqlCommand check_User_Name = new SqlCommand("SELECT * FROM Table WHERE ([user] = '" + txtBox_UserName.Text + "') ", conn);
if (check_User_Name.ExecuteScalar()!=null)
{
int UserExist = (int)check_User_Name.ExecuteScalar();
if (UserExist > 0)
{
//Username Exist
}
}
I was asking myself the same question, and I found no clear answers, so I created a simple test.
I tried to add 100 rows with duplicate primary keys and measured the time needed to process it. I am using SQL Server 2014 Developer and Entity Framework 6.1.3 with a custom repository.
Dim newE As New Employee With {.Name = "e"}
For index = 1 To 100
Dim e = employees.Select(Function(item) item.Name = "e").FirstOrDefault()
If e Is Nothing Then
employees.Insert(newE)
End If
Next
2.1 seconds
Dim newE As New Employee With {.Name = "e"}
For index = 1 To 100
Try
employees.Insert(newE)
Catch ex As Exception
End Try
Next
3.1 seconds
sda = new SqlCeDataAdapter("SELECT COUNT(regNumber) AS i FROM tblAttendance",con);
sda.Fill(dt);
string i = dt.Rows[0]["i"].ToString();
int bar = Convert.ToInt32(i);
if (bar >= 1){
dt.Clear();
MetroFramework.MetroMessageBox.Show(this, "something");
}
else if(bar <= 0) {
dt.Clear();
MetroFramework.MetroMessageBox.Show(this, "empty");
}
protected void btnsubmit_Click(object sender, EventArgs e)
{
string s = #"SELECT * FROM tbl1 WHERE CodNo = #CodNo";
SqlCommand cmd1 = new SqlCommand(s, con);
cmd1.Parameters.AddWithValue("#CodNo", txtid.Text);
con.Open();
int records = (int)cmd1.ExecuteScalar();
if (records > 0)
{
Response.Write("<script>alert('Record not Exist')</script>");
}
else
{
Response.Write("<script>alert('Record Exist')</script>");
}
}
private void insert_data()
{
SqlCommand comm = new SqlCommand("Insert into tbl1(CodNo,name,lname,fname,gname,EmailID,PhonNo,gender,image,province,district,village,address,phonNo2,DateOfBirth,school,YearOfGraduation,exlanguage,province2,district2,village2,PlaceOfBirth,NIDnumber,IDchapter,IDpage,IDRecordNumber,NIDCard,Kankur1Year,Kankur1ID,Kankur1Mark,Kankur2Year,Kankur2ID,Kankur2Mark,Kankur3Year,Kankur3ID,Kankur3Mark) values(#CodNo,N'" + txtname.Text.ToString() + "',N'" + txtlname.Text.ToString() + "',N'" + txtfname.Text.ToString() + "',N'" + txtgname.Text.ToString() + "',N'" + txtemail.Text.ToString() + "','" + txtphonnumber.Text.ToString() + "',N'" + ddlgender.Text.ToString() + "',#image,N'" + txtprovince.Text.ToString() + "',N'" + txtdistrict.Text.ToString() + "',N'" + txtvillage.Text.ToString() + "',N'" + txtaddress.Value.ToString() + "','" + txtphonNo2.Text.ToString() + "',N'" + txtdbo.Text.ToString() + "',N'" + txtschool.Text.ToString() + "','" + txtgraduate.Text.ToString() + "',N'" + txtexlanguage.Text.ToString() + "',N'" + txtprovince1.Text.ToString() + "',N'" + txtdistrict1.Text.ToString() + "',N'" + txtvillage1.Text.ToString() + "',N'" + txtpbirth.Text.ToString() + "','" + txtNIDnumber.Text.ToString() + "','" + txtidchapter.Text.ToString() + "', '" + txtidpage.Text.ToString() + "','" + txtrecordNo.Text.ToString() + "',#NIDCard,'" + txtkankuryear1.Text.ToString() + "','" + txtkankurid1.Text.ToString() + "','" + txtkankurscore1.Text.ToString() + "','" + txtkankuryear2.Text.ToString() + "','" + txtkankurid2.Text.ToString() + "','" + txtkankurscore2.Text.ToString() + "','" + txtkankuryear3.Text.ToString() + "','" + txtkankurid3.Text.ToString() + "','" + txtkankurscore3.Text.ToString() + "')", con);
flpimage.SaveAs(Server.MapPath("~/File/") + flpimage.FileName);
string img = #"~/File/" + flpimage.FileName;
flpnidcard.SaveAs(Server.MapPath("~/Tazkiera/") + flpnidcard.FileName);
string img1 = #"~/Tazkiera/" + flpnidcard.FileName;
comm.Parameters.AddWithValue("CodNo", Convert.ToInt32(txtid.Text));
comm.Parameters.AddWithValue("image", flpimage.FileName);
comm.Parameters.AddWithValue("NIDCard", flpnidcard.FileName);
comm.ExecuteNonQuery();
con.Close();
Response.Redirect("~/SecondPage.aspx");
//Response.Write("<script>alert('Record Inserted')</script>");
}
}
Use the method Int.Parse() instead. It will work.
I had a requirement to register user. In that case I need to check whether that username is already present in the database or not. I have tried the below in C# windows form application(EntityFramework) and it worked.
var result = incomeExpenseManagementDB.Users.FirstOrDefault(x => x.userName == registerUserView.uNameText);
if (result == null) {
register.registerUser(registerUserView.fnameText, registerUserView.lnameText, registerUserView.eMailText, registerUserView.mobileText, registerUserView.bDateText, registerUserView.uNameText, registerUserView.pWordText);
} else {
MessageBox.Show("User Alreay Exist. Try with Different Username");
}
I'm currently working on a project using MySql in combination with C#.
The Data for the DataGridView is provided by a join from multiple tables in the DB. To show the data I use the following, working, code:
adapter.SelectCommand = new MySqlCommand(
" SELECT" +
" l.lot AS Lot, "+
" m.comment AS Bemerkungen," +
... (multiple columns from different tables) ...
" FROM m " +
" JOIN m2p ON m.m2p_id = m2p.id" +
... (more joins) ...
, this._mySqlConnection);
dataGridView1.DataSource = data;
adapter.Fill(data);
Now the user of the GUI is allowed to modify a certain column (the "comment" column). So I assigned an eventHandler to the CellEndEdit event and when the user modified the allowed column the adapter.Update(data) is called. Now this doesn't perform the correct action.
To define my updatecommand I used the following code:
adapter.UpdateCommand = new MySqlCommand(
" UPDATE m" +
" JOIN l ON m.l_id = l.id" +
" SET m.comment = #comment" +
" WHERE l.lot = #lot"
, this._mySqlConnection);
adapter.UpdateCommand.Parameters.Add("#comment", MySqlDbType.Text, 256, "Bemerkungen");
adapter.UpdateCommand.Parameters.Add("#lot", MySqlDbType.Text, 256, "Lot");
Could you explain me how I fix my code to automatically Update the database?
EDIT:
added further source code:
private MySqlDataAdapter warenlagerMySqlDataAdapter, kundenMySqlDataAdapter;
private DataTable warenlagerData, kundenData;
private DataGridView warenlagerGridView;
private void updateWarenlagerView(object sender, EventArgs e) {
warenlagerMySqlDataAdapter.Update(warenlagerData);
}
private void initialzeFields() {
warenlagerGridView.CellEndEdit += new DataGridViewCellEventHandler(this.updateWarenlagerView);
warenlagerMySqlDataAdapter = new MySqlDataAdapter();
warenlagerData = new DataTable();
}
private void initializeWarenlagerView() {
warenlagerMySqlDataAdapter.SelectCommand = new MySqlCommand(
" SELECT" +
" c.name AS Ursprung, " +
" m2p.art_nr AS ArtNr," +
" m.delivery_date AS Eingangsdatum," +
" CONCAT(FORMAT(m.delivery_amount / 100, 2), 'kg') AS Eingangsmenge, " +
" l.lot AS Lot," +
" m.quality AS Qualität," +
" m.comment AS Bemerkungen," +
" CONCAT(m.units, 'kg') AS Units," +
" CONCAT(FORMAT(s.amount / 100, 2), 'kg') AS Lagermenge, " +
" FORMAT(m.base_price / 100, 2) AS Einkaufspreis," +
" FORMAT(s.amount/10000 * m.base_price, 2) AS Wert" +
" FROM mushrooms AS m " +
" JOIN mushroom2path AS m2p ON m.mushroom2path_id = m2p.id" +
" JOIN countries AS c ON m.origin_id = c.id" +
" JOIN lots AS l ON m.lot_id = l.id" +
" JOIN stock AS s ON s.mushrooms_id = m.id"
, this._mySqlConnection);
warenlagerGridView.DataSource = warenlagerData;
warenlagerMySqlDataAdapter.Fill(warenlagerData);
warenlagerMySqlDataAdapter.UpdateCommand = new MySqlCommand(
" UPDATE mushrooms AS m" +
" JOIN lots AS l ON m.lot_id = l.id" +
" SET m.comment = #comment" +
" WHERE l.lot = #lot"
, this._mySqlConnection);
warenlagerMySqlDataAdapter.UpdateCommand.Parameters.Add("#comment", MySqlDbType.Text, 256, "Bemerkungen");
warenlagerMySqlDataAdapter.UpdateCommand.Parameters.Add("#lot", MySqlDbType.Text, 256, "Lot");
}
This is the whole code concerning this problem. I'm 100% sure the adapter.Update(data) method is called (debugging). And the data which is passed to the adapter.Update() method contains the new data.
Please try this update query it works.
UPDATE mushrooms
SET comment = #comment
WHERE
l_id=(select id from l where lot=#lot)
Your update statement is incorrect. It should be:
"UPDATE m FROM mushrooms m JOIN lots l ON m.lot_id = l.id SET m.comment = #comment WHERE l.lot = #lot"
Did you forget to execute the warenlagerMySqlDataAdapter.UpdateCommand?
You are just setting the command and the parameters but not executing it.
What I see is that you are calling the update when the info is updated, but your update command is not loaded.
You just call updateWarenlagerView when you update the row, but where are you calling initialzeFields?
Or am I missing code?
Try moving your update code from the CellEndEdit event to the CellValueChanged event and see if this works.
Try this example out:
public void UpdateAllFromDgv(DataGridView dataGridView1)
{
string query = "Update List set ColumnName1=#Value1" +
",ColumnName2=#Value2" +
",ColumnName3=#Value3" +
",ColumnName4=#Value4" +
",ColumnName5=#Value5" +
",ColumnName6=#Value6 where ColumnName0=#Value0";
try
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
using (MySqlConnection con = new MySqlConnection(ConnectionString))
{
using (MySqlCommand cmd = new MySqlCommand(query, con))
{
cmd.Parameters.AddWithValue("#Value0", row.Cells[0].Value);
cmd.Parameters.AddWithValue("#Value1", row.Cells[1].Value);
cmd.Parameters.AddWithValue("#Value2", row.Cells[2].Value);
cmd.Parameters.AddWithValue("#Value3", row.Cells[3].Value);
cmd.Parameters.AddWithValue("#Value4", row.Cells[4].Value);
cmd.Parameters.AddWithValue("#Value5", row.Cells[5].Value);
cmd.Parameters.AddWithValue("#Value6", row.Cells[6].Value);
con.Open();
cmd.ExecuteNonQuery();
dataGridView1.ResetBindings();
con.Close();
}
}
}
}
catch (MySqlException MsE)
{
MessageBox.Show(MsE.Message.ToString());
}
}