oledbcommand ExecuteNonQuery won't update - c#

I have the following code which does a select based upon a string field and a date and if it returns anything then it tries to do an update. The select returns something, however when I do an update the variable "affected" is set to zero, Could this be because of dates? My date variable is set to (in British format) {02/06/2016 13:10:00} when I inspect it, so it does have a time component.
// DateTime Md, string ht = these are set at this point
var conn = new OleDbConnection();
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\MyPath\\MyDb.accdb";
conn.Open();
var cmdSel = conn.CreateCommand();
cmdSel.CommandText = #"SELECT * FROM MyTable WHERE Md = #MD AND HT=#HT";
cmdSel.Parameters.AddWithValue("#MD", Md);
cmdSel.Parameters.AddWithValue("#HT", ht);
var da = new OleDbDataAdapter(cmdSel);
var ds = new DataSet();
da.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
var cmd = conn.CreateCommand();
cmd.CommandText = #"UPDATE MyTable SET HS=#HS WHERE Md = #MD AND HT=#HT";
cmd.Parameters.AddWithValue("#MD", Md);
cmd.Parameters.AddWithValue("#HT", ht);
cmd.Parameters.AddWithValue("#HS", hs);
var affected = cmd.ExecuteNonQuery();
}

Access/OleDB doesn't use named parameters as such, they are just positional placeholders. So, you must supply the parameter values in the exact order listed in the SQL. Your code with the other recommended fixes would be something like:
string sql = #"UPDATE MyTable SET HS=#HS WHERE Md = #MD AND HT=#HT";
using (OleDbConnection dbcon = new OleDbConnection(AceConnStr))
{
// other code
using (OleDbCommand cmd = new OleDbCommand(sql, dbcon))
{
// add in the same order as in SQL
// I have no idea that these are
cmd.Parameters.Add("#HS", OleDbType.VarChar).Value = Hs;
cmd.Parameters.Add("#MD", OleDbType.Date).Value = Md;
cmd.Parameters.Add("#HT", OleDbType.Integer).Value = Ht;
int rows = cmd.ExecuteNonQuery();
} // closes and disposes of connection and command objects
}
The results of not disposing of things which ought to be seen in this question where the user ran out of resources trying to manually insert in a loop.
You also do not need to create a DataAdapter (or DataSet) just to fill a table' you can use a DataReader to do the same thing.
myDT.Load(cmd.ExecuteReader());

Related

Why does my MySQL connection not work in visual studio code C#?

i am making a program in visual studio code with C#, it is a paid program so it needs an hwid system. Basically i want it to check if your computer HWID exists in the HWID table in my users database. But it says it can't connect to the database. Can you help me? This is my code.`
string connectionString = "Server=SomeServer;Database=i got you this is notthe real database;User ID=same;Password=same for password;";
MySqlConnection mydbCon = new MySqlConnection(connectionString);
mydbCon.Open();
MySqlCommand command = mydbCon.CreateCommand();
command.CommandText = "SELECT * FROM yourTable WHERE hwid = GetHDDSerial";
IDataReader reader = command.ExecuteReader();
`
It could be that the connection string isn't formatted the way the MySQL connector wants it. The MySQL documentation shows "uid" instead of User, and "pwd" instead of Password. https://dev.mysql.com/doc/connector-net/en/connector-net-programming-connecting-connection-string.html
This should do what you need:
string connectionString = "Server=SomeServer;Database=i got you this is notthe real database;User ID=same;Password=same for password;";
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
using (MySqlCommand command = new MySqlCommand())
{
string sql = "SELECT * FROM yourTable WHERE hwid = #val1";
command.Connection = connection;
command.CommandType = CommandType.Text;
command.CommandText = sql;
command.Parameters.AddWithValue("#val1", "GetHDDSerial");
connection.Open();
using (MySqlDataAdapter adapter = new MySqlDataAdapter())
{
using (DataSet ds = new DataSet())
{
adapter.SelectCommand = command;
adapter.Fill(ds);
if (ds.Tables.Count > 0)
{
DataTable dt = ds.Tables[0];
foreach (DataRow row in dt.Rows)
{
// Do something here. You can access the data like this:
// row["Id"] or whatever your field names are.
// int id = (int) row["Id"];
// Of course, I don't know your field names, so you'll have to complete this.
}
}
}
}
}
}

C# write select from mysql to variable

I have a big problem with save variable from select in mysql.
I wrote the following code:
string connectionstring = #"****;userid=*****;
password=***;database=***";
cnn = new MySqlConnection(connectionstring);
cnn.Open();
MySqlDataReader reader = null;
string query_date = "SELECT computer_name from wp_users where user_login = #login";
MySqlCommand command2 = new MySqlCommand(query_date, cnn);
command2.Parameters.AddWithValue("#login", metroTextBox.Text);
reader = command2.ExecuteReader();
while (reader.Read())
{
string ColumnName = (string)reader["computer_name"];
}
cnn.Close();
I tried a lot of commands like ExecuteReader , ExecuteNonQuery , ExecuteScalar. but none of them worked and I am getting the same error:
Really don't know what is wrong here I searched a lot and didn't find a solution of any form. Please help.
EDIT 1
I just did how you wrote and i did this :
string connectionstring = #"****;userid=*****;
password=***;database=***";
cnn = new MySqlConnection(connectionstring);
cnn.Open();
MySqlDataReader reader = null;
string query_date = "SELECT computer_name from wp_users where user_login = #login";
MySqlCommand command2 = new MySqlCommand(query_date, cnn);
command2.Parameters.AddWithValue("#login", metroTextBox.Text);
DataTable table = new DataTable("ResultTable");
MySqlDataAdapter adapter = new MySqlDataAdapter(command2);
adapter.Fill(table);
// This is the important line
string result = table.Rows[0].ToString();
cnn.Close();
Its the same error as earlier but another place. What's going on here... just don't know.
Additional information mean in english : The key is not present in the dictionary
EDIT 2
The funniest is when i just try to update with code :
string connectionstring = #"****;userid=*****;
password=***;database=***";
cnn = new MySqlConnection(connectionstring);
cnn.Open();
MySqlDataReader reader = null;
string upd = "UPDATE w_users Set computer_name = CURRENT_DATE where user_login = #login";
MySqlCommand command2 = new MySqlCommand(upd, cnn);
command2.Parameters.AddWithValue("#login", metroTextBox.Text);
DataTable table = new DataTable("ResultTable");
SqlDataAdapter adapter = new MySqlDataAdapter(command2);
adapter.Fill(table);
cnn.Close();
And this works fine without any errors just update my table... What's the point of it
EDIT 3
I jutr try used to ExecuteScalar() and still i have the same error :
The solution is simple:
Updating mysql.data.dll to the newest version fixed it (https://dev.mysql.com/downloads/connector/net/6.9.html).
This exception wants to tell you, that there is no matching key in your resultset. Keys are case sensitive. Have you tried to spell your column name with all uppercase letters: (string)reader["COMPUTER_NAME"]?
Databases tend to return the column names in uppercase, even though you selected the column name in lower case.
If you have the MySqlDataAdapter, try if the following code works for you:
string connectionstring = #"****;userid=*****;
password=***;database=***";
cnn = new MySqlConnection(connectionstring);
cnn.Open();
string query_date = "SELECT computer_name AS `computer_name` FROM wp_users WHERE user_login = #login";
MySqlCommand command2 = new MySqlCommand(query_date, cnn);
command2.Parameters.AddWithValue("#login", metroTextBox.Text);
DataTable table = new DataTable("ResultTable");
MySqlDataAdapter adapter = new MySqlDataAdapter(command2);
adapter.Fill(table);
// This is the important line
string result = table["computer_name"];
cnn.Close();

Want to Fill Text Box With Access Data

In C# I want to use access data to fill my textBox I Am using ADO.Net To connect to access.So far I've got this:
OleDbConnection con = new OleDbConnection(Price.constr);
OleDbCommand cmd = new OleDbCommand();
cmd.Connection=con;
cmd.CommandText = "select * from Table1";
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
Price.constr is my connection String.
I want to fill textBox1 with the data in the Price Column Where my row ID = 1.(For Example)
If you want to read only one record from your table then there is no need to return the whole table and use an adapter to fill a datatable. You can simply ask the database to return just the record you are interested in.
string cmdText = "select * from Table1 WHERE ID = 1";
using(OleDbConnection con = new OleDbConnection(Price.constr))
using(OleDbCommand cmd = new OleDbCommand(cmdText, con))
{
con.Open();
using(OleDbDataReader reader = cmd.ExecuteReader())
{
if(reader.Read())
textBox1.Text = reader["Price"].ToString();
else
textBox1.Text = "No record found";
}
}
I have enclose the connection, command and reader in an using statement because these are disposable objects and it is a good practice to destroy them when you have finished to use them. (In particular the connection could cause problems if you don't dispose it)
Notice also that I have used the constant 1 to retrieve the record. I bet that you want this to be dynamic and in this case I suggest you to look at how to PARAMETRIZE your queries. (Don't do string concatenations)

Error when adding parameters to stored procedure call

In the ShippedContainerSettlement program I am trying to add parameters to a SQL statement on a stored procedure that I created on the remote server (plex).
public void checkGradedSerials()
{
localTable = "Graded_Serials";
List<string> gradedHides = new List<string>();
string queryString = "call sproc164407_2053096_650214('#startDate', '" + endDate + "');";
OdbcDataAdapter adapter = new OdbcDataAdapter();
OdbcCommand command = new OdbcCommand(queryString, connection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#startDate", startDate);
adapter.SelectCommand = command;
connection.Open();
while (rowsCollected == false)
{
if (retries <= 5)
{
try
{
DataTable table = new DataTable();
adapter.Fill(table);
An error is thrown when I use the parameter #startDate and give it a value. However, when I run the program, and add the parameters how I have done for endDate, it runs fine?
The error I get back is:
Any ideas what I am doing wrong.
EDIT:
I have incorporated some of the changes mentioned below. Here is the code I used.
public void checkGradedSerials()
{
localTable = "Graded_Serials";
List<string> gradedHides = new List<string>();
OdbcCommand command = new OdbcCommand("sproc164407_2053096_650214", odbcConnection);
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue("#startDate", startDate);
command.Parameters.AddWithValue("#endDate", endDate);
OdbcDataAdapter adapter = new OdbcDataAdapter();
adapter.SelectCommand = command;
odbcConnection.Open();
while (rowsCollected == false)
{
if (retries <= 5)
{
try
{
DataTable table = new DataTable();
adapter.Fill(table);
But it doesn't seem to be receiving the parameters i am sending through as I am getting this error.
Here is the stored procedure I am using. This might look odd but remember this is working when I simply pass a string into a select command (see endDate in first code example above).
SELECT DISTINCT(Serial_No)
FROM Part_v_Container_Change2 AS CC
WHERE CC.Change_Date > #Change_Start_Date AND
CC.Change_Date <= #Change_End_Date AND
CC.Location = 'H Grading';
and the parameters are added here:
You should use the System.Data.SqlClient. You can explicitly declare the datatypes of paramaters you are sending... like this:
SqlConnection cn;
cn = new SqlConnection(ConnectionString);
SqlCommand cmd;
cmd = new SqlCommand("sproc164407_2053096_650214", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#startDate", SqlDbType.DateTime);
cmd.Parameters["#startDate"].Value = startDate;
cmd.Parameters.Add("#enddate", SqlDbType.VarChar);
cmd.Parameters["#enddate"].Value = enddate;
If you must use the ODBC, then you do have to use the ODBC CALL syntax, which does not support named parameters. So change your queryString line to:
string queryString = "{call sproc164407_2053096_650214 (?, ?)}";
Then you can add your parameters:
command.Parameters.Add("#startDate", OdbcType.DateTime).Value=startDate;
command.Parameters.Add("#endDate", OdbcType.DateTime).Value=endDate;
Use SqlCommand instead of odbc.
Just put the stored proc name in the CommandText, not a SQL statement to execute it. Adding the param values means the adapter will pass in the params in the right format. You don't need to do the string manipulation in CommandText.
If you need to use OdbcCommand then see this answer showing you need to use ? syntax for the parameters, so maybe change your CommandText back to including the 'call' or 'exec' command and parameter placeholders, then make sure you AddWithValue the params in the right order

How to Use an Update Statement in SQLDataAdapter

I am trying to run an update statement after i built my sqldataadapter. I have column called INIT_PHASE in my table and if the INIT_PHASE is null or there is no data then i would like to set it to 1. I have tried but i can't seem to get it right the update statement. Pls. help. here is my code:
string ID = ddlPractice.SelectedValue;
string TYPE = DDL_TYPE.SelectedValue;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["myConnection"].ConnectionString);
SqlDataAdapter da = new SqlDataAdapter(#"select SET_SK, UNIT_NM, TYPE, INIT_PHASE FROM myTable WHERE UNIT_NM =#ID AND TYPE = #TYPE", con);
DataTable dtSETS = new DataTable();
da.SelectCommand.Parameters.AddWithValue("#ID", (ID));
da.SelectCommand.Parameters.AddWithValue("#TYPE", (TYPE));
da.Fill(dtSETS);
if (dtSETS.Rows.Count > 0)
{
DataRow dtSETS_row = dtSETS.Rows[0];
long SET_SK = dtSETS_row.Field<long>("SET_SK");
if (dtSETS_row.Field<string>("INIT_PHASE") == null)
{
//run update command here
update myTable set INIT_PHASE = 1;
}
}
One approach here would be to use the SqlCommandBuilder to build the UPDATE statement:
string ID = ddlPractice.SelectedValue;
string TYPE = DDL_TYPE.SelectedValue;
SqlConnection con = new SqlConnection(
ConfigurationManager.ConnectionStrings["myConnection"].ConnectionString);
SqlDataAdapter da = new SqlDataAdapter(
#"select SET_SK, UNIT_NM, TYPE, INIT_PHASE FROM myTable WHERE UNIT_NM =#ID AND TYPE = #TYPE",
con);
DataTable dtSETS = new DataTable();
da.SelectCommand.Parameters.AddWithValue("#ID", (ID));
da.SelectCommand.Parameters.AddWithValue("#TYPE", (TYPE));
da.Fill(dtSETS);
SqlCommandBuilder builder = new SqlCommandBuilder(da);
da.UpdateCommand = builder.GetUpdateCommand();
if (dtSETS.Rows.Count > 0)
{
DataRow dtSETS_row = dtSETS.Rows[0];
long SET_SK = dtSETS_row.Field<long>("SET_SK");
if (dtSETS_row.Field<string>("INIT_PHASE") == null)
{
dtSETS_row["INIT_PHASE"] = 1;
}
}
da.Update(dtSETS);
Take note to the following lines of code. Here we are building the update command:
SqlCommandBuilder builder = new SqlCommandBuilder(da);
da.UpdateCommand = builder.GetUpdateCommand();
here we are literally modifying the DataRow so that it's RowState is changed to Modified:
dtSETS_row["INIT_PHASE"] = 1;
and then finally, here we are sending updates to the database with the Update method on the SqlDataAdapter:
da.Update(dtSETS);
What this is going to do is only send updates for the rows with a RowState of Modified.
NOTE: each of the ADO.NET objects should be wrapped in a using. Refactor your code to match this type of template:
using (SqlConnection con = new SqlConnection(...))
{
using (SqlDataAdapter da = new SqlDataAdapter(...))
{
}
}
If I understand correctly, you could execute directly a command to update just this field
if (dtSETS_row.Field<string>("INIT_PHASE") == null)
{
SqlCommand cmd = new SqlCommand(#"UPDATE myTable set INIT_PHASE = 1 " +
"WHERE UNIT_NM =#ID AND TYPE = #TYPE", con);
cmd.Parameters.AddWithValue("#ID", (ID));
cmd.Parameters.AddWithValue("#TYPE", (TYPE));
cmd.ExecuteNonQuery();
}
You need to open the connection though both for the SqlDataAdapter and for the following command
You will have to use SqlCommandBuilder class for updating data in disconnected mode. ie) DataSet and Data Adapters.

Categories

Resources