SQL DateDiff inconsistency - c#

When I run the following script on my SQL database (from the management studio) I get the results I expect -
SELECT *
FROM [Case]
WHERE ABS((DATEDIFF(DAY, [DateAccident], '2013-01-01'))) < 100;
When I increase / decrease the value 100, I get more / less matches exactly as expected.
However, when I attempt to produce the same result from my WinForms app (in C#) I get far more results than I should -
public static DataTable DOACases(DateTime doa, int days)
{
try
{
DataTable table = new DataTable();
string sqlText = "SELECT * " +
"FROM [Case] " +
"WHERE ABS((DATEDIFF(DAY, [DateAccident], " + doa.ToString().Substring(0,10) + "))) < " + days.ToString() + ";";
SqlCommand sqlCom = new SqlCommand(sqlText);
table = Express.GetTable(sqlCom);
return table;
}
catch (Exception eX)
{
throw new Exception("Case: DOACases(Date)" + Environment.NewLine + eX.Message);
}
}
I do not know why
PS. Express.GetTable(sqlCom) simply creates a connection on the database and the necessary code to fill a DataTable using a DataReader and has worked hundreds of times, so I doubt the issue is there.

Thanks to allo-man, using parameters worked.
The final code looked as follows -
public static DataTable DOACases(DateTime doa, int days)
{
try
{
DataTable table = new DataTable();
string sqlText = "SELECT * " +
"FROM [Case] " +
"WHERE ABS((DATEDIFF(DAY, [DateAccident], #Date))) < #Days;";
SqlCommand sqlCom = new SqlCommand(sqlText);
sqlCom.Parameters.Add("#Date", SqlDbType.Date).Value = doa;
sqlCom.Parameters.Add("#Days", SqlDbType.Int).Value = days;
table = Express.GetTable(sqlCom);
return table;
}
catch (Exception eX)
{
throw new Exception("Case: DOACases(Date)" + Environment.NewLine + eX.Message);
}
}

You better use parameters but here the problem is
'" + doa.ToString("yyyy-MM-dd" , CultureInfo.InvariantCulture) + "'
you need single quotes

Related

How to search SQL database and display in C# listview

I need to filter an SQL database using C# to display it in a windowsFormsHost.
For that, I created a text box in which you input the required string. Using this input, the code uses the text to search through the database and display on clicking a refresh button.
The refresh button works and is done, I just need to create the list with the selected rows according to my filter.
Here is the code, which states that no value is returned:
private string GetPassengerList(string sPasssenger)
{
string sPasssengerL = textBoxPassengerName.Text;
if (sPasssenger.Trim().Length > 0)
{
string sToTime = dtpToDate.Value.Year.ToString("D4") + #"/" + dtpToDate.Value.Month.ToString("D2") + #"/" + dtpToDate.Value.Day.ToString("D2");
sToTime += #" " + dtpToTime.Value.Hour.ToString("D2") + #":" + dtpToTime.Value.Minute.ToString("D2") + #":" + dtpToTime.Value.Second.ToString("D2");
string sFromTime = dtpFromDate.Value.Year.ToString("D4") + #"/" + dtpFromDate.Value.Month.ToString("D2") + #"/" + dtpFromDate.Value.Day.ToString("D2");
sFromTime += #" " + dtpFromTime.Value.Hour.ToString("D2") + #":" + dtpFromTime.Value.Minute.ToString("D2") + #":" + dtpFromTime.Value.Second.ToString("D2");
string sSqlSelect = #"SELECT Passenger FROM ";
string sSqlWhere = #" WHERE (Created BETWEEN '" + sFromTime + #"' AND '" + sToTime + #"')";// and (IATA='" + sIata + #"')";
string sSqlLike = #" LIKE '%" + sPasssengerL + "'%";
SqlDataReader sqlReader = null;
try {
SqlCommand sqlCommand = new SqlCommand(sSqlSelect + #"dbo.BagData" + sSqlWhere + sSqlLike, this.dbConnection);
sqlReader = sqlCommand.ExecuteReader();
if(!sqlReader.Read()) {
sqlReader.Close();
sqlCommand.CommandText = sSqlSelect + #"dbo.BagDataHistory" + sSqlWhere + sSqlLike;
sqlReader = sqlCommand.ExecuteReader();
if(!sqlReader.Read()) {
sqlReader.Close();
sqlCommand.CommandText = sSqlSelect + #"dbo.BagDataArchive" + sSqlWhere + sSqlLike;
sqlReader = sqlCommand.ExecuteReader();
if(!sqlReader.Read()) {
sqlReader.Close();
}
}
}
if(!sqlReader.IsClosed) {
sPasssengerL = this.GetSqlDataString(#"Passenger", sqlReader);
sqlReader.Close();
}
}
catch(SqlException x) {
MessageBox.Show(#"GetPassengerName(): SQL Exception: " + x.Message, this.GetHashString("Error"), MessageBoxButton.OK, MessageBoxImage.Error);
}
catch(Exception ex) {
MessageBox.Show(#"GetPassengerName(): General Exception: " + ex.Message, this.GetHashString("Error"), MessageBoxButton.OK, MessageBoxImage.Error);
}
finally {
if(sqlReader != null) {
if(!sqlReader.IsClosed) {
sqlReader.Close();
}
}
}
return sPasssengerL;
}
}
You have a few errors in the code you posted.
Using concatenated strings instead of parameters in your sql query.
Re-declaring a variable with the same name as the functions parameter. You are declaring another passenger variable sPasssengerL needlessly in the function now.
Not returning a string value from the function. Your edited code shows the function returning the seemingly unneeded extra passenger variable sPasssengerL now.
Your LIKE statement did not include which column it is checking
against.
I cleaned up the code a little, leaving the sSqlWhere in case that was oddly delcared outside your example. This also shows how to add the first column of data to a listview as you've requested.
EDIT: Per your comment on the original question I've updated the code
to show your sSqlWhere variable.
private void GetPassengerList()
{
string sPassenger = textBoxPassengerName.Text;
if (sPassenger.Trim().Length > 0)
{
string sToTime = dtpToDate.Value.Year.ToString("D4") + #"/" + dtpToDate.Value.Month.ToString("D2") + #"/" + dtpToDate.Value.Day.ToString("D2");
sToTime += #" " + dtpToTime.Value.Hour.ToString("D2") + #":" + dtpToTime.Value.Minute.ToString("D2") + #":" + dtpToTime.Value.Second.ToString("D2");
string sFromTime = dtpFromDate.Value.Year.ToString("D4") + #"/" + dtpFromDate.Value.Month.ToString("D2") + #"/" + dtpFromDate.Value.Day.ToString("D2");
sFromTime += #" " + dtpFromTime.Value.Hour.ToString("D2") + #":" + dtpFromTime.Value.Minute.ToString("D2") + #":" + dtpFromTime.Value.Second.ToString("D2");
string sSqlSelect = #"SELECT Passenger FROM ";
string sSqlWhere = #" WHERE (Created BETWEEN #startDate AND #endDate)";
// I assume this is looking for passenger. Change appropriately.
string sSqlLike = #"AND Passenger LIKE #name";
string searchTerm = "%" + sPassenger + "%";
SqlDataReader sqlReader = null;
try
{
SqlCommand sqlCommand = new SqlCommand(sSqlSelect + #"dbo.BagData" + sSqlWhere, parentWindow.dbConnection);
sqlReader = sqlCommand.ExecuteReader();
if (!sqlReader.Read())
{
sqlReader.Close();
sqlCommand.CommandText = sSqlSelect + #"dbo.BagDataHistory" + sSqlWhere + sSqlLike;
sqlCommand.Parameters.Add(new SqlParameter("#name", searchTerm));
sqlCommand.Parameters.Add(new SqlParameter("#startDate", sToTime));
sqlCommand.Parameters.Add(new SqlParameter("#endDate", sFromTime));
sqlReader = sqlCommand.ExecuteReader();
if (!sqlReader.Read())
{
sqlReader.Close();
sqlCommand.CommandText = sSqlSelect + #"dbo.BagDataArchive" + sSqlWhere + sSqlLike;
sqlReader = sqlCommand.ExecuteReader();
// This will loop through your returned data and add
// an item to a list view (listView1) for each row.
while (sqlReader.Read())
{
ListViewItem lvItem = new ListViewItem();
lvItem.SubItems[0].Text = sqlReader[0].ToString();
lvItem.SubItems.Add(sqlReader[0].ToString());
listView1.Items.Add(lvItem);
}
sqlReader.Close();
}
}
if (!sqlReader.IsClosed)
{
sPassenger = parentWindow.GetSqlDataString(#"Passenger", sqlReader);
sqlReader.Close();
}
}
catch (SqlException x)
{
MessageBox.Show(#"GetPassengerName(): SQL Exception: " + x.Message, parentWindow.GetHashString("Error"), MessageBoxButton.OK, MessageBoxImage.Error);
}
catch (Exception ex)
{
MessageBox.Show(#"GetPassengerName(): General Exception: " + ex.Message, parentWindow.GetHashString("Error"), MessageBoxButton.OK, MessageBoxImage.Error);
}
finally
{
if (sqlReader != null)
{
if (!sqlReader.IsClosed)
{
sqlReader.Close();
}
}
}
}
}
NOTE: There are other places this code can be cleaned up and simplified but that is beyond the scope of this question.
Check your variables, you've declared sSqlSelect and sSqlLike but not sSqlWhere which you are using in your queries.
a) your function will not compile:
- Missing ";" in several lines,
- local variable declaration "sPessanger" in line 2 conflicts with parameter name ...
b) you never return a value. At least you need a single "return sPassenger;" somewhere in the code to return the selected value.
c) bad style using sql injection. As already stated in the comments, use parameters in your SQL.
d) as far as i can see, you are selecting only a single value from your resultset, or is the GetSqlDataString function supposed to do the job?

Multiple OleDbCommands producing System Resource Exceeded

So basically I have a C# project, that iterates through every student (300 students) within a table called Student within a Microsoft Access 2016 database. In a single iteration for a single student by using other tables like Mathematics, Reading that have a 1-to-1 relationship with the Student table, to grab the data that belongs to that student.
try
{
OleDbCommand allStudents = new OleDbCommand("SELECT [NSN]"
+ " FROM [Student]; ");
allStudents.Connection = conn;
OleDbDataAdapter allData = new OleDbDataAdapter(allStudents);
DataTable allTable = new DataTable();
allData.Fill(allTable);
foreach (DataRow dr in allTable.Rows)
{
string NSN = dr["NSN"].ToString();
OleDbCommand cmd = new OleDbCommand("SELECT * "
+ "FROM (((([Student] s "
+ "INNER JOIN [Student Extra] se ON se.[NSN] = s.[NSN]) "
+ "INNER JOIN [Reading] r ON r.[NSN] = s.[NSN])"
+ "INNER JOIN [Writing] w ON w.[NSN] = s.[NSN])"
+ "INNER JOIN [Mathematics] m ON m.[NSN] = s.[NSN]) "
+ "WHERE s.[NSN] = '" + NSN + "'; ");
cmd.Connection = conn;
OleDbDataAdapter daa = new OleDbDataAdapter(cmd);
DataTable dtt = new DataTable();
daa.Fill(dtt);
foreach (DataRow drr in dtt.Rows)
{
firstName = drr["Preferred Name"].ToString();
gender = drr["Gender"].ToString();
room = drr["Room Number"].ToString();
NSAchieve = drr["National Standard Achieve"].ToString();
NSProgress = drr["National Standard Progress"].ToString();
The above code is only a snippet of the code I have, but this is basically where the function will start.
By using this data, I want to be able to go through several SELECT statements for other tables and compare them and produce a calculated value.
Dictionary<string, OleDbCommand> d = new Dictionary<string, OleDbCommand>();
cmd = new OleDbCommand("SELECT [Achievement Statement]"
+ " FROM [National Standard Codes]"
+ " WHERE [National Standard Code] = '" + readingNSAchievementCode + "'; ");
d["readingNSAchievementOTJ"] = cmd;
cmd = new OleDbCommand("SELECT [" + NSAchieve + "]"
+ " FROM [Reading National Standards]"
+ " WHERE [Assessment] = '" + readingFinalAssessment + "'; ");
d["readingNSAchievementComp"] = cmd;
cmd = new OleDbCommand("SELECT [Timeframe]"
+ " FROM [Reading Statements]"
+ " WHERE [Year Code] = '" + NSProgress + "'; ");
d["readingNSProgressTimeframe"] = cmd;
There are several more commands, (approx <150). I use a Dictionary to store my Commands, and then execute the commands in a FOREACH loop.
foreach(KeyValuePair<string, OleDbCommand> pair in d)
{
try
{
string v = pair.Key;
OleDbCommand dbCmd = pair.Value;
dbCmd.Connection = conn;
OleDbDataReader reader = dbCmd.ExecuteReader();
reader.Read();
readingDict[v] = reader.GetString(0);
}
catch (Exception e)
{
MessageBox.Show("Error at " + pair.Key + "\n\n Here is message " + e);
}
}
After executing and getting my value, I want to store my data into another table called Calculated.
string insert1 = "INSERT INTO [Calculated] (";
int i = 0;
Dictionary<string, string> dict = createDictionary(NSN);
int len = dict.Count / 2;
foreach (KeyValuePair<string, string> pair in dict)
{
string field = pair.Key;
string value = pair.Value;
if (i == (len - 1))
{
insert1 += "[" + field + "])";
break;
}
else
{
insert1 += "[" + field + "], ";
}
i++;
}
insert1 += " VALUES (";
i = 0;
foreach (KeyValuePair<string, string> pair in dict)
{
string field = pair.Key;
string value = pair.Value;
if (i == len - 1)
{
insert1 += "'" + value + "')";
break;
}
else
{
insert1 += "'" + value + "', ";
}
i++;
}
I build my INSERT INTO query, and then I execute using an OleDbCommand. This needs to repeat 300 times, but for development purposes currently I only have 5 students in my Student table. However when executing after the 4th student it will always consistently give me an error System Resources Exceeded always at a specific OleDbCommand. I have tested each command separately, so there is no issue with the way the OleDbCommands are written.
I have tried searching on here, and tried to encase the first code snippet in a using statement, using using (OleDbConnection conn = new OleDbConnection(connectionStr)) but as I am still a novice at C#, I am unable to produce a solution.

Problems in updating a SQL Server 2008 in C#. NET in runtime mode

I have faced a problem to update a row in SQL Serve 2008 via C#. NET application.
During runtime, the application tries to update the database but with no success. However, there is no exception, error, NOTHING. Checking the SQL Profile, the update command was sent, but not committed.
If I run the application debugging it step-by-step (via 'F11') the row is updated successfully (!?!?!?!?!)
I have copied the SQL update command and ran it on SQL Management Studio and also worked fine.
General Information:
- The only problem is in runtime mode.
- The user used is 'sa' with all granted permission
- I have ran the SAME METHODS for other tables (the only thing that changes is the table name) and it works fine.
The method responsible for it is:
public void Save(FormaResult obj)
{
try
{
bool insert = GetById(obj.SLABID) == null;
IList<string> colResult = GetColumns(TABLE);
List<string> colList = colResult.Where(TableColumns.Contains).ToList();
if (insert)
{
string col = string.Join(",", colList.Select(i => i).ToArray());
string colParam = string.Join(", ", colList.Select(i => "#" + i).ToArray());
QueryString = "INSERT INTO " + TABLE + " (" + col + ") VALUES(" + colParam + ");";
}
else
{
string colSet = string.Join(", ", colList.Select(i => i + " = #" + i).ToArray());
QueryString = "UPDATE " + TABLE + " SET " + colSet + " WHERE SLABID = #Id1;";
}
DbCommand = Conn.CreateCommand();
DbCommand.Connection = Conn;
DbCommand.CommandText = QueryString;
ListDbParameters = new List<DbParameter>
{
this.CriarParametro<DateTime>("GT_TIME", obj.GT_TIME),
this.CriarParametro<long?>("SLABID", obj.SLABID),
this.CriarParametro<short?>("STATUS", obj.STATUS)
};
if (!insert)
{
ListDbParameters.Add(this.CriarParametro<long>("Id1", obj.SLABID));
}
foreach (DbParameter param in ListDbParameters)
{
DbCommand.Parameters.Add(param);
}
Conn.Open();
DbCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
TrkCGManagedModuleService.Logger.Error(ex.Message);
throw;
}
finally
{
Conn.Close();
}
}
I have also used this method:
public void OkEvt()
{
try
{
this.QueryString = "UPDATE " + TABLE + " SET STATUS = 1 " +
"FROM (SELECT TOP(1) * FROM " + TABLE + " WHERE STATUS=0 ORDER BY GT_TIME ASC) I " +
"WHERE " + TABLE + ".SLABID = I.SLABID AND " + TABLE + ".STATUS=0 AND " + TABLE + ".GT_TIME = I.GT_TIME;";
this.DbCommand = this.Conn.CreateCommand();
this.DbCommand.Connection = this.Conn;
this.DbCommand.CommandText = this.QueryString;
this.Conn.Open();
this.DbCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
TrkCGManagedModuleService.Logger.Error(ex.Message);
throw;
}
finally
{
this.Conn.Close();
}
}
Both methods have the same aim, update the column 'STATUS' to '1'.
I would say the same thing as Soner Gonul about the SQL injection. I understand what your trying to do, but from my experience your leaving open a security door that is easily closed. Just requires a bit more time writing your CRUD statements for each table.
Here is a code sample that I use for my update queries you might find useful. If you are going to use this method, remember to create a user that has deny reader and deny writer. Then run a command to grant them execute permissions on all stored procedures.
this.o_ConnectionString is a private variable set inside my class constructor since i put my data layer in a separate project than my web applications.
public int UpdateThisTable(int TableUID, string SomeField)
{
string StoredProcedure = "usp_SomeStoredProcedure";
SqlConnection conn = new SqlConnection(enteryourconnectionstring);
SqlCommand cmd = new SqlCommand(StoredProcedure, conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#TableUID", TableUID);
cmd.Parameters.AddWithValue("#SomeField", SomeField);
conn.Open();
int rowsaffected = cmd.ExecuteNonQuery();
conn.Close();
return rowsaffected;
}

SqlCommand AddWithValue and if statements issue with gridview

I am trying to build a web form that uses SQL queries to help populate various dropdowns and display results in gridviews, the issue i'm having at the moment is getting the user input to replace varibles in the SQL query.
My query is as follows:
SELECT TOP 50
'Select' AS 'Select',
id_ref AS 'Number',
created_date AS 'Date Created',
address 'Address',
category AS 'Category',
borough
FROM Events
WHERE location_address LIKE '%%'
AND borough #borcond
AND admin_ref #stacond
AND id_ref #Numcond
AND category #cat
AND created_date #startDate
AND created_date #endDate
AND address LIKE #Addresscond
ORDER BY id_todays_date DESC
My C# code is as follows:
public void SQLQueryv2(
string AddressSel,
string startDateSel,
string endDateSel,
string incidentSel,
string borsel,
string stasel,
string numsel)
{
//this is filled in really
SqlConnection Connection = new SqlConnection(
"Data Source=;Initial Catalog=;User=;Password=;");
string sqlquery = <<as above>>
try
{
SqlCommand Command = new SqlCommand(sqlquery, Connection);
Connection.Open();
if (borsel == "Select Borough")
{
Command.Parameters.AddWithValue("#borcond", " = IS NOT NULL ");
}
else
{
Command.Parameters.AddWithValue("#borcond","= " + "'" + borsel + "'");
}
if (stasel == "Select Town")
{
Command.Parameters.AddWithValue("#stacond", " = IS NOT NULL ");
}
else
{
Command.Parameters.AddWithValue("#borcond","= "+ "'" + borsel + "'");
}
if (startDateSel == "")
{
Command.Parameters.AddWithValue("#startDate", " = IS NOT NULL");
}
else
{
Command.Parameters.AddWithValue(
"#startDate",
">= CONVERT(datetime," + "'" + startDateSel + "'" + ",103)");
}
if (endDateSel == "")
{
Command.Parameters.AddWithValue("#endDate", " = IS NOT NULL");
}
else
{
Command.Parameters.AddWithValue(
"#endDate",
">= CONVERT(datetime," + "'" + endDateSel + "'" + ",103)");
}
if (incidentSel == "Select Category")
{
Command.Parameters.AddWithValue(
"#cat",
" in ('cat a','cat b','cat c')");
}
else
{
Command.Parameters.AddWithValue(
"#cat",
" AND category =" + "'" + incidentSel + "'");
}
if (AddressSel == "")
{
Command.Parameters.AddWithValue("#Addresscond", "%%");
}
else
{
Command.Parameters.AddWithValue("#Addresscond","%" + AddressSel + "%");
}
if (numsel == "")
{
Command.Parameters.AddWithValue("#Numcond", " = IS NOT NULL ");
}
else
{
Command.Parameters.AddWithValue("#Numcond", "= " + "'" + numsel + "'");
}
//use adapter to populate dataset...
SqlDataAdapter DataAdapter = new SqlDataAdapter(sqlquery, Connection);
DataTable DataTable = new DataTable();
DataAdapter.SelectCommand = Command;
DataAdapter.Fill(DataTable);
//then bind dataset to the gridview
GridView1.AutoGenerateColumns = true;
GridView1.DataSource = DataTable;
GridView1.DataBind();
lblResults.Visible = true;
lblResults.ForeColor = System.Drawing.Color.Green;
lblResults.Text = "Your search has returned "
+ Dataset.Tables[0].Select(
"'Incident Number' IS NOT NULL").Length.ToString()
+ " records.";
}
catch (Exception err)
{
lblResults.Visible = true;
lblResults.ForeColor = System.Drawing.Color.Red;
lblResults.Text =
"An error has occurred loading data into the table view. ";
lblResults.Text += err.Message;
}
}
When run, the Gridview doesn't populate and the query (when investigated) it still has the variables and not the 'is nulls' or user inputs.
I think its something to so with the IF statements but i'm entirely sure. I think i just need another pair of eyes on this, any help would be appreciated.
Bit more info:
If i take out the sqlCommand bits it works perfectly with the IF statements, i'm trying to stop people from using malicious SQL queries.
This really isn't the correct way to use parameters. You should only assign values to them, not add comparison operators. Here's an example of how to "fix" your query for the #borcond parameter
...
AND ((#borcond = 'Select Borough' AND borough IS NOT NULL)
OR borough = #borcond)
...
Note: you don't need the equal sign with IS NOT NULL
And replace the if-else with
Command.Parameters.AddWithValue("#borcond", borsel);
You'll need to do similar changes for all of your parameters. The trick here is to basically move your if-else logic from the code into the sql query.
Additionally I don't think you need the location_address LIKE '%%' in your query as that just matches everything.
What juhar said. You've got the wrong idea about parameters. They're parameters and not text substitution. Here's an example of a valid query:
Select firstname, lastname from contacts
where ssn = #ssn
And in your code you'd say
Command.parameters.AddWithValue("#ssn","123-45-6789")

Automatically Update Values in Database from DataGridView

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());
}
}

Categories

Resources