Can't update MS Access database in C#? - c#

My code:
OleDbCommand cmd1 = new OleDbCommand("UPDATE student_info SET fee_due = #fee_due WHERE adm_no = #adm_no", con);
cmd1.Parameters.AddWithValue("#adm_no", adm_no);
cmd1.Parameters.AddWithValue("#fee_due", fee_due);
int affect = cmd1.ExecuteNonQuery();
MessageBox.Show(affect.ToString());
My code always shows 0 row affected every time but in my database the are must be a row that will be affect
Can you suggest me how I debug this problem?

Since OleDB for MS Access doesn't support named parameters (only positional parameters), you must be very careful about providing the values in the same order in which you define the parameters.
In your case, the statement lists #fee_due first, before #adm_no - but you provide the values in the other order.
Change your code like this:
OleDbCommand cmd1 = new OleDbCommand("UPDATE student_info SET fee_due = #fee_due WHERE adm_no = #adm_no", con);
// provide the value for #fee_due FIRST
cmd1.Parameters.AddWithValue("#fee_due", fee_due);
// provide the value for #adm_no only after #fee_due
cmd1.Parameters.AddWithValue("#adm_no", adm_no);
int affect = cmd1.ExecuteNonQuery();
MessageBox.Show(affect.ToString());

Related

Data type mismatch in criteria expression - started only recently

I use Access database. This error wasn't occurring 30 minutes ago.
ERROR is:
Data type mismatch in criteria expression.
OleDbConnection con = new OleDbConnection(Utility.GetConnection());
con.Open();
OleDbCommand cmd2 = new OleDbCommand("INSERT INTO Temsilci(isin_adi,isin_tanimi,verildigi_tarih,teslim_tarihi,sorumlu_marka,sorumlu_ajans,revize,Temsilci_isverenid)
values (#isinadi,#isintanimi,#vertarih,#testarih,#smarka,#sajans,#revize,#temsid)", con);
cmd2.Parameters.Add("isintanimi", txtMarkaAdi.Text);
cmd2.Parameters.Add("isinadi", txtisAdi.Text);
cmd2.Parameters.Add("smarka", txtMarkaTemsilcisi.Text);
cmd2.Parameters.Add("sajans", txtAjansTemsilcisi.Text);
cmd2.Parameters.Add("revize", txtSorumluKisiler.Text);
cmd2.Parameters.Add("vertarih", txtverilisTarihi.Text);
cmd2.Parameters.Add("testarih", txtTeslimTarihi.Text);
cmd2.Parameters.Add("temsid", Session["UserID"]);
cmd2.ExecuteNonQuery();
con.Close();
My database columns are:
ID = AutoNumber
isin_adi = Short Text
isin_tanimi = Long Text
verildigi_tarih= Date/Time
teslim_tarihi=Date/Time
sorumlu_marka = Short Text
sorumlu_ajans=Short Text
personel_id=Number
revize=Short Text
is_durum=Short Text
Temsilci_isverenid=Number
I Solved the problem. I realized the rank of parameters was not true. i change my code like that:
OleDbConnection con = new OleDbConnection(Utility.GetConnection());
con.Open();
OleDbCommand cmd2 = new OleDbCommand("INSERT INTO Temsilci(isin_adi,isin_tanimi,verildigi_tarih,teslim_tarihi,sorumlu_marka,sorumlu_ajans,revize,Temsilci_isverenid) values (#isinadi,#isintanimi,#vertarih,#testarih,#smarka,#sajans,#revize,#temsid)", con);
cmd2.Parameters.Add("isinadi", txtisAdi.Text);
cmd2.Parameters.Add("isintanimi", txtMarkaAdi.Text);
cmd2.Parameters.Add("vertarih", txtverilisTarihi.Text);
cmd2.Parameters.Add("testarih", txtTeslimTarihi.Text);
cmd2.Parameters.Add("smarka", txtMarkaTemsilcisi.Text);
cmd2.Parameters.Add("sajans", txtAjansTemsilcisi.Text);
cmd2.Parameters.Add("revize", txtSorumluKisiler.Text);
cmd2.Parameters.Add("temsid", Session["UserID"]);
cmd2.ExecuteNonQuery();
con.Close();
after that i get error like this :
You cannot add or change a record because a related record is required in table 'Personel'.
And i remove the relationship from 2 tables. And now it works normally.
I think access database have some bugs ,and even if code is correct, errors may accuired.
So i will move my database to SQL from ACCESS i think. Thanks guys.

No values given for one or more required parameters

I am getting error as "No values given for one or more required parameters" Please help. For Nid.Text value is "N712".
private void Form1_Load(object sender, EventArgs e)
{
OleDbConnection cont1 = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=H:\vsual\Database3.accdb");
OleDbCommand cmd1 = new OleDbCommand("select distinct UserName from Users where UID=#UID ", cont1);
OleDbCommand cmd2 = new OleDbCommand("select distinct QueueName from Users where UID=#UID ", cont1);
OleDbCommand cmd3 = new OleDbCommand("select * from Issues", cont1);
cmd1.Parameters.AddWithValue("#UID", Nid.Text);
cmd2.Parameters.AddWithValue("#UID", Nid.Text);
cont1.Open();
OleDbDataReader rdr1= cmd1.ExecuteReader();
while(rdr1.Read())
{
txtName.Text = rdr1[0].ToString();
}
OleDbDataReader rdr2 = cmd2.ExecuteReader();
while (rdr2.Read())
{
txtQueue.Text= rdr2[0].ToString();
}
txtName.Enabled = false;
txtQueue.Enabled = false;
OleDbDataAdapter da = new OleDbDataAdapter();
DataSet ds = new DataSet();
da.SelectCommand = cmd3;
da.Fill(ds);
cmbIssue.DataSource = ds.Tables[0];
cmbIssue.ValueMember = "Issues";
cmbIssue.DisplayMember = "Issues";
cmbIssue.Enabled = true;
}
All i got from internet is some issue with sql statement. Please help me out to resolve this issue.
I tried testing your code and got the same error, but then fixed up my database to match your query and it worked fine.
Upon deleting a column from the table to test, the error reappeared. So I think in this case it is just a misleading error message, and actually your database is missing a column you reference in your query (as opposed to a problem with your parameter).
e.g. deleting the QueueName column from Users broke cmd2 with the message you stated.
Have a look at your database and make sure the columns match your query. i.e. your UserName table should have columns UID, UserName, QueueName and your Issues table should have a Issues column.
Update: Adding images of the data I used to successfully run your code. Please have a look and see if anything doesn't match your data. Particularly check data types.
Users schema:
Users data:
Issues schema:
Issues data:
This might help but not sure.
The OLE DB .NET Provider does not support named parameters for passing parameters to an SQL statement or a stored procedure called by an OleDbCommand when CommandType is set to Text. In this case, the question mark (?) placeholder must be used. For example:
SELECT * FROM Customers WHERE CustomerID = ?
Therefore, the order in which OleDbParameter objects are added to the OleDbParameterCollection must directly correspond to the position of the question mark placeholder for the parameter in the command text.
Source : https://msdn.microsoft.com/en-us/library/system.data.oledb.oledbcommand.parameters(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1

DataAdapter.UpdateCommand not working c#?

I am using this code to update "SOME" columns in a table in my database. But everytime I try to do so an error is given.
No value given for one or more required parameters.
con.Open();
SlipDA = new OleDbDataAdapter();
string sqlUpdate = "Update tbl_Slip SET RaiseBasic=#RaiseBasic, OtherDed=#OtherDed, Arrears=#Arrears, Notes=#Notes WHERE SlipNo=#SlipNo";
SlipDA.UpdateCommand = new OleDbCommand(sqlUpdate, con);
SlipDA.UpdateCommand.Parameters.AddWithValue("#RaiseBasic", Convert.ToInt32(dRow[4].ToString()));
SlipDA.UpdateCommand.Parameters.AddWithValue("#OtherDed", Convert.ToInt32(dRow[5].ToString()));
SlipDA.UpdateCommand.Parameters.AddWithValue("#Arrears", Convert.ToInt32(dRow[7].ToString()));
SlipDA.UpdateCommand.Parameters.AddWithValue("#Notes", dRow[8].ToString());
SlipDA.UpdateCommand.Parameters.AddWithValue("#SlipNo", dRow[0].ToString());
SlipDA.UpdateCommand.ExecuteNonQuery();
con.Close();
The table contains 9 columns but I only want to update a few.
This Could be the problem :
The OLE DB .NET Provider does not support named parameters for passing
parameters to an SQL statement or a stored procedure called by an
OleDbCommand when CommandType is set to Text. In this case, the
question mark (?) placeholder must be used. For example: SELECT * FROM
Customers WHERE CustomerID = ?
source : this
so basically your query should be like this :
string sqlUpdate = "Update tbl_Slip SET RaiseBasic= ?, OtherDed= ?, Arrears= ?, Notes= ? WHERE SlipNo= ?";
try this
string sqlUpdate = "Update tbl_Slip SET RaiseBasic=#RaiseBasic, OtherDed=#OtherDed, Arrears=#Arrears, Notes=#Notes WHERE SlipNo=#SlipNo";
OleDbCommand UpdateCommand = new OleDbCommand(sqlUpdate, con);
UpdateCommand.Parameters.AddWithValue("#RaiseBasic", Convert.ToInt32(dRow[4].ToString()));
UpdateCommand.Parameters.AddWithValue("#OtherDed", Convert.ToInt32(dRow[5].ToString()));
UpdateCommand.Parameters.AddWithValue("#Arrears", Convert.ToInt32(dRow[7].ToString()));
UpdateCommand.Parameters.AddWithValue("#Notes", dRow[8].ToString());
UpdateCommand.Parameters.AddWithValue("#SlipNo", dRow[0].ToString());
con.Open();
UpdateCommand.ExecuteNonQuery();
con.Close();

OleDbDataAdapter Update To dbf [Free Table] -Syntax Error()

When I insert through the OleDbCommand with direct values no problem, it's working fine
OleDbCommand OleCmd1 = new OleDbCommand("Insert into My_Diary (sl_no,reminder) values("+a1+",'CHECK VALUE')", OleCon1);
OleCmd1->ExecuteNonQuery();
But when I like to update through parameter its showing "Syntax Error"....I can't identify my mistake...
string MyConStr = "Provider=VFPOLEDB.1; Data Source='C:\\For_Dbf'; Persist Security Info=False";
InsSavDiaryCmd = "Insert into My_Table1 (sl_no,reminder) values (#sl_no,#reminder) ";
VFPDAp=gcnew OleDbDataAdapter();
VFPDApMy_Table1InsertCommand = gcnew OleDbCommand(InsSavDiaryCmd, OleCon1);
WithInsVar = VFPDAp.InsertCommand.Parameters;
WithInsVar.Add("#sl_no", OleDbType.Integer, 10, "sl_no");
WithInsVar.Add("#reminder", OleDbType.Char, 250, "reminder");
OleCon1.ConnectionString = MyConStr;
OleCon1.Open();
OleDbTransaction Trans=OleCon1.BeginTransaction();
//VFPDAp.DeleteCommand.Transaction = Trans;
//VFPDAp.UpdateCommand.Transaction = Trans;
VFPDAp.InsertCommand.Transaction = Trans;
VFPDAp.Update(MyDataTbl);
Trans.Commit();
OleCon1.Close();
The OleDbCommand doesn't use named parameters. You need to change the insert statement so that it uses questions.
InsSavDiaryCmd = "Insert into My_Table1 (sl_no,reminder) values (?, ?) ";
You need to make sure that you have a parameter for each question mark and make sure that the parameters are inserted in order of their use in the insert statement.
** If you'd like to use name parameters... you can try using VfpClient which is a project that I'm working on to make data access a little nicer from .Net.

Is my SqlCommand variable overworked? Did it get tired?

In my testing project, I have a static class called FixtureSetup which I use to setup my integration testing data for validation.
I use the same SqlCommand and SqlParameter variable (not the object itself) within that class, repeatedly, using the same variable references over and over, assigning new SqlCommand and SqlParameter objects each time. My connection itself is created once and passed into the methods performing the setup, so each setup uses it's own distinct connection reference, and while the same conn is used multiple times, it's always in a linear sequence.
In one such method, I ran into a very odd situation, where my SqlCommand variable simply appears to have gotten tired.
cmd = new SqlCommand("INSERT INTO Subscription (User_ID, Name, Active) VALUES (#User_ID, #Name, #Active)", conn);
parameter = new SqlParameter("#User_ID", TestUserID); cmd.Parameters.Add(parameter);
parameter = new SqlParameter("#Name", "TestSubscription"); cmd.Parameters.Add(parameter);
parameter = new SqlParameter("#Active", true); cmd.Parameters.Add(parameter);
cmd.ExecuteNonQuery();
cmd = new SqlCommand("SELECT Subscription_ID FROM [Subscription] WHERE Name = 'TestSubscription'", conn);
parameter = new SqlParameter("#User_ID", TestUserID);
cmd.Parameters.Add(parameter);
using (dr = cmd.ExecuteReader())
{
while (dr.Read())
{
TestSubscriptionID = dr.GetInt32(dr.GetOrdinal("Subscription_ID"));
}
}
cmd = new SqlCommand("INSERT INTO SubscriptionCompany (Subscription_ID, Company_ID) VALUES (#Subscription_ID, #Company_ID)", conn);
parameter = new SqlParameter("#Subscription_ID", TestSubscriptionID); cmd.Parameters.Add(parameter);
parameter = new SqlParameter("#Company_ID", KnownCompanyId); cmd.Parameters.Add(parameter);
cmd.ExecuteNonQuery();
In the above, at the last line shown, doing the same thing I've done quite literally in dozens of other places (insert data, read the ID column and capture it), I get the following:
SetUp : System.InvalidOperationException : ExecuteNonQuery requires an
open and available Connection. The connection's current state is
closed. at
System.Data.SqlClient.SqlConnection.GetOpenConnection(String method)
BUT - replace cmd with new variable myCmd, and everything works swimmingly!
SqlCommand myCmd;
myCmd = new SqlCommand("INSERT INTO Subscription (User_ID, Name, Active) VALUES (#User_ID, #Name, #Active)", conn);
parameter = new SqlParameter("#User_ID", TestUserID); myCmd.Parameters.Add(parameter);
parameter = new SqlParameter("#Name", "TestSubscription"); myCmd.Parameters.Add(parameter);
parameter = new SqlParameter("#Active", true); myCmd.Parameters.Add(parameter);
myCmd.ExecuteNonQuery();
myCmd = new SqlCommand("SELECT Subscription_ID FROM [Subscription] WHERE Name = 'TestSubscription'", conn);
parameter = new SqlParameter("#User_ID", TestUserID);
myCmd.Parameters.Add(parameter);
using (dr = myCmd.ExecuteReader())
{
while (dr.Read())
{
TestSubscriptionID = dr.GetInt32(dr.GetOrdinal("Subscription_ID"));
}
}
myCmd = new SqlCommand("INSERT INTO SubscriptionCompany (Subscription_ID, Company_ID) VALUES (#Subscription_ID, #Company_ID)", conn);
parameter = new SqlParameter("#Subscription_ID", TestSubscriptionID); myCmd.Parameters.Add(parameter);
parameter = new SqlParameter("#Company_ID", KnownCompanyId); myCmd.Parameters.Add(parameter);
myCmd.ExecuteNonQuery();
What the heck is going on here? Did my command var just get tired???
What clued me to the "fix" was I noticed in my tracing that in my "read the id" block, my cmd.Parameters block had only ONE parameter in it, the 2nd one added, and when I forced the first cmd.Parameters.Add line to execute again, the number of parameters in the list dropped to 0. That's what prompted me to try a method level SqlCommand...cause I had the crazy idea that my cmd was tired... Imagine my shock when I apparently turned out to be right!
Edit: I'm not recycling any objects here - just the variable reference itself (static SqlCommand at the class level). My apologies for the earlier confusion in my wording of the question.
use one command per query and call dispose (or better yet, wrap in a using statement). you don't want to be "reusing" ado.net components.
Big Edit:
From: http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqldatareader.close.aspx
You must explicitly call the Close method when you are through using
the SqlDataReader to use the associated SqlConnection for any other
purpose.
The Close method fills in the values for output parameters, return
values and RecordsAffected, increasing the time that it takes to close
a SqlDataReader that was used to process a large or complex query.
When the return values and the number of records affected by a query
are not significant, the time that it takes to close the SqlDataReader
can be reduced by calling the Cancel method of the associated
SqlCommand object before calling the Close method.
so try:
using (dr = cmd.ExecuteReader())
{
while (dr.Read())
{
TestSubscriptionID = dr.GetInt32(dr.GetOrdinal("Subscription_ID"));
}
dr.Close();
}
Check that you haven't set the DataReader to CommandBehavior.CloseConnection since you mentioned that you're re-using the connection for your test initialization.
Also, the DataReader does take resources, so utilize Dispose
Do you really need to do make a new connection object after each try?
myCmd = new SqlCommand(...)
//your code
myCmd = new SqlCommand(...)
//etc
You can just say:
myCmd.CommandText = "INSERT INTO SubscriptionCompany (Subscription_ID, Company_ID) VALUES (#Subscription_ID, #Company_ID)";
so that you may re-use your command object. Additionally you can reset your parameters as well after each call. Just call myCmd.Parameters.Clear().
Also, make sure you wrap your SqlCommand in a using statement so they will be properly cleaned up.
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "some proc"
cmd.Connection = conn;
//set params, get data, etc
cmd.CommandText = "another proc"
cmd.Parameters.Clear();
//set params, get date, etc.
}

Categories