Incorrect Syntax near Where for an Update query - c#

Here is the update query which i am using to update a table. It throws me an exception "Incorrect Syntax near Where" Why is that exception for? i have no idea.
public bool UpdateLocationCountintoMerchantPackage(int PackageID, long MerchantID,int LocationCount)
{
try
{
SqlParameter[] parameters = new SqlParameter[]
{
new SqlParameter("#packageID",PackageID),
new SqlParameter("#merchantID",MerchantID ),
new SqlParameter("#locationCount",LocationCount )
};
string CommandText = string.Empty;
CommandText = "Update Merchant_Package SET LocationCount Where MerchantID=#MerchantID";
string ConnectionString = DbConnectionStrings.GetDbConnectionString();
SqlHelper.ExecuteNonQuery(ConnectionString, System.Data.CommandType.Text, CommandText, parameters);
return true;
}
catch (SqlException ex)
{
LogError("Error Occurred When Saving Merchant Location Count Data : MerchantID:" + MerchantID.ToString(), ex);
return false;
}
}
this function is called from
protected void imgbtnSubmit_Click(object sender, ImageClickEventArgs e)
{
UpdatePaymentInfo();
string QueryString = Request.QueryString.ToString();
if (string.Equals(QueryString, "MerchantProfilePages"))
{
Response.Redirect(ApplicationData.URL_ADD_PROFILE_PAGE, false);
Merchant mrchnt = new Merchant();
int PackId = mrchnt.PackageID;
int x = GetLocationCount() + 1;
mrchnt.UpdateLocationCountintoMerchantPackage(PackId, merchantId, x);
}

It's an issue with your "SET LocationCount" - you're not setting it equal to anything. That's why it's complaining about the WHERE.

Use SQL like:
Update Merchant_Package SET LocationCount=#LocationCount
Where MerchantID=#MerchantID
Your error on the 1st line was reported when WHERE was encountered

Related

Exception handling quandry

I am throwing a new exception when a database row is not found.
Class that was called:
public ProfileBO retrieveProfileByCode(string profileCode)
{
return retrieveSingleProfile("profile_code", profileCode);
}
private ProfileBO retrieveSingleProfile(string termField, string termValue)
{
ProfileBO profile = new ProfileBO();
//Query string is temporary. Will make this a stored procedure.
string queryString = " SELECT * FROM GamePresenterDB.gp.Profile WHERE " + termField + " = '" + termValue + "'";
using (SqlConnection connection = new SqlConnection(App.getConnectionString()))
{
connection.Open();
SqlCommand command = new SqlCommand(queryString, connection);
SqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
profile = castDataReadertoProfileBO(reader, profile);
}
else
{
// No record was selected. log it and throw the exception (We'll log it later, for now just write to console.)
Console.WriteLine("No record was selected from the database for method retrieveSingleProfile()");
throw new InvalidOperationException("An exception occured. No data was found while trying to retrienve a single profile.");
}
reader.Close();
}
return profile;
}
However, when I catch the exception in the calling class, 'e' is now null. What am I doing wrong? I believe this works fine in Java, so C# must handle this differently.
Calling class:
private void loadActiveProfile()
{
try
{
ProfileBO profile = profileDAO.retrieveProfileByCode(p.activeProfileCode);
txtActiveProfileName.Text = profile.profile_name;
}
catch (InvalidOperationException e)
{
}
}
Now all the code has been put in the question, you can move the try catch outside of your 'loadActiveProfile' method and place it into 'retrieveSingleProfile'.
private void loadActiveProfile()
{
ProfileBO profile = profileDAO.retrieveProfileByCode(p.activeProfileCode);
txtActiveProfileName.Text = profile.profile_name;
}
removed the try catch^
private ProfileBO retrieveSingleProfile(string termField, string termValue)
{
try {
ProfileBO profile = new ProfileBO();
//Query string is temporary. Will make this a stored procedure.
string queryString = " SELECT * FROM GamePresenterDB.gp.Profile WHERE " + termField + " = '" + termValue + "'";
using (SqlConnection connection = new SqlConnection(App.getConnectionString()))
{
connection.Open();
SqlCommand command = new SqlCommand(queryString, connection);
SqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
profile = castDataReadertoProfileBO(reader, profile);
}
else
{
// No record was selected. log it and throw the exception (We'll log it later, for now just write to console.)
Console.WriteLine("No record was selected from the database for method retrieveSingleProfile()");
throw new InvalidOperationException("An exception occured. No data was found while trying to retrienve a single profile.");
}
reader.Close();
}
return profile;
}
catch(InvalidOperationException e)
{
}
}
Added try catch in the correct place.
You need to step into the catch block for e to be set to the thrown InvalidOperationException:
catch (System.InvalidOperationException e)
{
int breakPoint = 0; //<- set a breakpoint here.
//Either you reach the breakpoint and have an InvalidOperationException, or you don't reach the breakpoint.
MessageBox.Show(e.Message);
}
Also make sure that the InvalidOperationException you throw is actually a System.InvalidOperationException and not some custom type of yours called "InvalidOperationException".
Like #Clemens said, you need to show all the relevant code.
As a quick test, this works just fine:
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Throwing error");
ThrowException();
}
catch (InvalidOperationException e)
{
Console.WriteLine(e.Message);
}
Console.ReadKey(true);
}
static void ThrowException()
{
throw new InvalidOperationException("Blah blah blah");
}
}

Parameter '?user_email' not found in the collection

I am using MySql 5.6x with Visual Studio 2015, windows 10, 64-bit. C# as programming language. In my CRUD.cs (Class file) i have created the following method:
public bool dbQuery(string sql,string[] paramList= null)
{
bool flag = false;
try
{
connect();
cmd = new MySqlCommand(sql,con);
cmd.Prepare();
if(paramList != null){
foreach(string i in paramList){
string[] valus = i.Split(',');
string p = valus[0];
string v = valus[1];
cmd.Parameters[p].Value = v;
}
}
if (cmd.ExecuteNonQuery() > 0)
{
flag = true;
}
}
catch (Exception exc)
{
error(exc);
}
}
I am passing the query and Parameters List like this:
protected void loginBtn_Click(object sender, EventArgs e)
{
string sql = "SELECT * FROM dept_login WHERE (user_email = ?user_email OR user_cell = ?user_cell) AND userkey = ?userkey";
string[] param = new string[] {
"?user_email,"+ userid.Text.ToString(),
"?user_cell,"+ userid.Text.ToString(),
"?userkey,"+ userkey.Text.ToString()
};
if (db.dbQuery(sql, param))
{
msg.Text = "Ok";
}
else
{
msg.Text = "<strong class='text-danger'>Authentication Failed</strong>";
}
}
Now the problem is that after the loop iteration complete, it directly jumps to the catch() Block and generate an Exception that:
Parameter '?user_email' not found in the collection.
Am i doing this correct to send params like that? is there any other way to do the same?
Thanks
EDIT: I think the best way might be the two-dimensional array to collect the parameters and their values and loop then within the method to fetch the parameters in cmd.AddWidthValues()? I may be wrong...
In your dbQuery you don't create the parameters collection with the expected names, so you get the error when you try to set a value for a parameter that doesn't exist
public bool dbQuery(string sql,string[] paramList= null)
{
bool flag = false;
try
{
connect();
cmd = new MySqlCommand(sql,con);
cmd.Prepare();
if(paramList != null){
foreach(string i in paramList){
string[] valus = i.Split(',');
string p = valus[0];
string v = valus[1];
cmd.Parameters.AddWithValue(p, v);
}
}
if (cmd.ExecuteNonQuery() > 0)
flag = true;
}
catch (Exception exc)
{
error(exc);
}
}
Of course this will add every parameter with a datatype equals to a string and thus is very prone to errors if your datatable columns are not of string type
A better approach would be this one
List<MySqlParameter> parameters = new List<MySqlParameter>()
{
{new MySqlParameter()
{
ParameterName = "?user_mail",
MySqlDbType= MySqlDbType.VarChar,
Value = userid.Text
},
{new MySqlParameter()
{
ParameterName = "?user_cell",
MySqlDbType= MySqlDbType.VarChar,
Value = userid.Text
},
{new MySqlParameter()
{
ParameterName = "?userkey",
MySqlDbType = MySqlDbType.VarChar,
Value = userkey.Text
},
}
if (db.dbQuery(sql, parameters))
....
and in dbQuery receive the list adding it to the parameters collection
public bool dbQuery(string sql, List<MySqlParameter> paramList= null)
{
bool flag = false;
try
{
connect();
cmd = new MySqlCommand(sql,con);
cmd.Prepare();
if(paramList != null)
cmd.Parameters.AddRange(paramList.ToArray());
if (cmd.ExecuteNonQuery() > 0)
{
flag = true;
}
}
catch (Exception exc)
{
error(exc);
}
}
By the way, unrelated to your actual problem, but your code doesn't seem to close and dispose the connection. This will lead to very nasty problems to diagnose and fix. Try to use the using statement and avoid a global connection variable
EDIT
As you have noticed the ExecuteNonQuery doesn't work with a SELECT statement, you need to use ExecuteReader and check if you get some return value
using(MySqlDataReader reader = cmd.ExecuteReader())
{
flag = reader.HasRows;
}
This, of course, means that you will get troubles when you want to insert, update or delete record where instead you need the ExecuteNonQuery. Creating a general purpose function to handle different kind of query is very difficult and doesn't worth the work and debug required. Better use some kind of well know ORM software like EntityFramework or Dapper.
Your SQL Commands' Parameters collection does not contain those parameters, so you cannot index them in this manner:
cmd.Parameters[p].Value = v;
You need to add them to the Commands' Parameters collection in this manner: cmd.Parameters.AddWithValue(p, v);.

Fatal Error Encountered using LINQ and mysqlconnection

I'm quite new to c# so please any help would be great. I made a simple console code to update to mysql database, rest assured my database is done setting up, App.config is done. Now, the problem is when I run to test my code this error occurred. "Fatal error encountered during command execution"
below is my code:
class library:
public class DBEntity
{
private MySqlConnection DBConnection { get; set; }
public string INSERT = "insert";
public string SELECT = "select";
public string UPDATE = "update";
public void Get_Connection(string ConnectionString)
{
DBConnection = new MySqlConnection(ConnectionString);
}
public void Close_Connection()
{
DBConnection.Close();
}
public void Query(string operation, string query, params object[] values)
{
try
{
DBConnection.Open();
switch (operation)
{
case "update":
try
{
using (MySqlCommand cmd = new MySqlCommand(query, DBConnection))
{
IEnumerable<string> tokens = query.Split(new char[] { ' ', '\'', ';', ',' }).Where(str => str.Contains('#'));
var zipTwoTokens = tokens.Zip(values, (token, vals) => cmd.Parameters.AddWithValue(token, vals)).ToList();
cmd.ExecuteNonQuery();
DBConnection.Close();
}
}
catch (MySqlException e)
{
DBConnection.Close();
Console.WriteLine(e.Message);
}
break;
default:
break;
}
}
catch (MySqlException)
{
}
}
}
The Main class:
class Program
{
static void Main(string[] args)
{
DBEntity database = new DBEntity();
database.Get_Connection(ConfigurationManager.ConnectionStrings["MySQLConnection"].ConnectionString);
database.Query(database.UPDATE, "UPDATE RoyDB.Products SET Products.Name = #productName WHERE Products.ProductID = #product;", "Kayak", 1);
Console.Read();
}
}
Now, the problem is when I run to test my code this error occurred. "Fatal error encountered during command execution"
can anyone help me? I dont seem to get the cause of the error.
any help would be great! Thanks!
The way you split the query up to determine the parameters is not quite correct. In this case it is including the semicolon so you get parameters called #productName and #product;. Add in semicolon to the split string like this:
IEnumerable<string> tokens =
query.Split(new char[] { ' ', '\'', ';'}).Where(str => str.Contains('#'));
Additionally, you need to actually force the Zip method to be called as Linq uses deferred execution. To to this, add ToList on the end of the zip:
var zipTwoTokens =
parameterToken.Zip(values, (prmtoken, vals) =>
cmd.Parameters.AddWithValue(prmtoken, vals)).ToList();

Get exception when add to database in Linq-to-SQL

My database is in SQL Server and I use Linq-to-SQL. I used from SP(Save cards) .
I put breakpoint in my code, when arrive at rdr = cmm.ExecuteReader(); get me exception!!!
private void btnSave_Click(object sender, EventArgs e)
{
PersianCalendar jc = new PersianCalendar();
string SaveDate = jc.GetYear(DateTime.Now).ToString();
int from=Convert.ToInt32(txt_barcode_f.Text);
int to=Convert.ToInt32(txt_barcode_t .Text);
int quantity=Convert.ToInt32(to-from);
int card_Type_ID=Convert.ToInt32(cmb_BracodeType .SelectedValue);
int[] arrCardNum = new int[quantity];
arrCardNum[0]=from;
for (int i = from; i < to;i++ )
{
for(int j=0; j<quantity ;j++)
{
arrCardNum[j]=from+j;
int r = arrCardNum[j];
sp.SaveCards(r, 2, card_Type_ID, SaveDate, 2);
}
}
}
public void SaveCards(int Barcode_Num, int Card_Status_ID, int Card_Type_ID, string Save_Date, int Save_User_ID)
{
IDbCommand cmm;
cmm = Linq.Connection.CreateCommand();
try
{
cmm.Parameters.Add(new SqlParameter("#Barcode_Num", Barcode_Num));
cmm.Parameters.Add(new SqlParameter("#Card_Status_ID", 2));
cmm.Parameters.Add(new SqlParameter("#Card_Type_ID", Card_Type_ID));
cmm.Parameters.Add(new SqlParameter("#SaveDate", Save_Date));
cmm.Parameters.Add(new SqlParameter("#Save_User_ID", Save_User_ID));
cmm.CommandText = "SaveCards";
cmm.Connection.Open();
cmm.Connection = Linq.Connection;
cmm.CommandType = CommandType.StoredProcedure;
IDataReader rdr = null;
**rdr = cmm.ExecuteReader();**
while (rdr.Read())
{
Console.Write(" All Insert ! " + "\n");
}
}
catch (SqlException ex)
{
SqlExceptionHandler(ex, Save_User_ID);
}
catch (Exception ex)
{
PopularEexceptionHandler(ex, Save_User_ID);
}
finally
{ cmm.Connection.Close(); }
}
when excute sp, show no result and display this:
when execute sp , display this:The INSERT statement conflicted with the CHECK constraint "CK_BarCode_Num". The conflict occurred in database "Parking", table "dbo.TBL_Cards", column 'BarCode_Num'. The statement has been terminated. No rows affected. (0 row(s) returned) #RETURN_VALUE = -6
You're a bit chaotic on how you set up your connection and command..... e.g. you open the connection before you even assign it! How is that going to work??
My recommendation would be this order (based on the principle first do all the setup before opening the connection, and furthermore open the connection as late as possible, close it as quickly as possible) :
IDbCommand cmm = Linq.Connection.CreateCommand();
try
{
// define name and type of command
cmm.CommandText = "SaveCards";
cmm.CommandType = CommandType.StoredProcedure;
// assign connection
cmm.Connection = Linq.Connection;
// define parameters
cmm.Parameters.Add(new SqlParameter("#Barcode_Num", Barcode_Num));
cmm.Parameters.Add(new SqlParameter("#Card_Status_ID", 2));
cmm.Parameters.Add(new SqlParameter("#Card_Type_ID", Card_Type_ID));
cmm.Parameters.Add(new SqlParameter("#SaveDate", Save_Date));
cmm.Parameters.Add(new SqlParameter("#Save_User_ID", Save_User_ID));
// only now - after all the setup - open the connection, read the data
cmm.Connection.Open();
IDataReader rdr = rdr = cmm.ExecuteReader();
while (rdr.Read())
{
....
}
}
To catch the errors that the execution throws, replace your catch block for the SqlException with this:
catch (SqlException ex)
{
StringBuilder sbErrors = new StringBuilder();
foreach (SqlError error in ex.Errors)
{
sbErrors.AppendLine(error.Message);
}
string allErrors = sbErrors.ToString();
}
and debug into that catch block - what is the allErrors string in the end??
Update: after a chat session, we know finally know what the message in the SQL exception is:
The INSERT statement conflicted with the CHECK constraint "CK_BarCode_Num". The conflict occurred in database "Parking", table "dbo.TBL_Cards", column 'BarCode_Num'.
Now we're trying to find out what that constraint is / does and why it gets violated....
I think it could be that you have open the connection and assigning another connection before executing the reader.
cmm.CommandText = "SaveCards";
//cmm.Connection.Open(); You should open the connection after assigning it
cmm.Connection = Linq.Connection;
cmm.CommandType = CommandType.StoredProcedure;
cmm.Connection.Open(); //Open it here
SqlDataReader rdr = cmm.ExecuteReader();

Listbox Selected Value Issue

I have a list box on my WinForms application which populates with the following SQL code in C#:
private void PopulateClients()
{
string sqlText = "SELECT ClientID, ClientName FROM tblClients;";
cSqlQuery cS = new cSqlQuery(sqlText, "table");
lbxClient.DataSource = cS.cTableResults;
lbxClient.DisplayMember = "ClientName";
lbxClient.ValueMember = "ClientID";
}
So whilst the list box displays client names, the value it should return when selected is the numerical clientID.
However, later in the code -
private void btnAddNewJob_Click(object sender, EventArgs e)
{
try
{
string strNewJobName = txtNewJobName.Text;
string strNewJobRef = txtNewJobRef.Text;
int intNewJobClient = (int)lbxClient.SelectedValue;
string sqlText = "INSERT INTO tblJobs (JobID, JobClient, JobRef, JobName) " +
"VALUES (#JobID, #JobClient, #JobRef, #JobName);";
SqlCommand sqlCom = new SqlCommand(sqlText);
sqlCom.Parameters.Add("#JobID", SqlDbType.Int);
sqlCom.Parameters.Add("#JobClient", SqlDbType.Int);
sqlCom.Parameters.Add("#JobRef", SqlDbType.Text);
sqlCom.Parameters.Add("#JobName", SqlDbType.Text);
cConnectionString cS = new cConnectionString();
sqlCom.Parameters["#JobID"].Value = cS.NextID("JobID", "tblJobs");
sqlCom.Parameters["#JobClient"].Value = intNewJobClient;
sqlCom.Parameters["#JobRef"].Value = strNewJobRef;
sqlCom.Parameters["#JobName"].Value = strNewJobName;
cSqlQuery cQ = new cSqlQuery(sqlCom, "non query");
PopulateJobs();
txtNewJobName.Text = "";
txtNewJobRef.Text = "";
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Fails on the third line
int intNewJobClient = (int)lbxClient.SelectedValue;
With an invalid cast. As far as I can see the listbox is still returning the Client Name, whereas it should be returning then numerical clientID (int).
Any ideas?
Your code should work - just tested that.
Make sure that the data you are binding to is correct - especially ClientID
also make sure that the value is selected before casting to int
Hope it helps
lbxClient.SelectedValue is a string. It should be converted to an int like so:
int intNewJobClient = Convert.ToInt32(lbxClient.SelectedValue);
Hope this helps.
In the end I had to do this:
int intClient = 0;
try
{
intClient = (int)lbxClient.SelectedValue;
}
catch (Exception)
{
intClient = 0;
}
Which I feel like is a bit of a fudge - but it works!
You code should work, However you should place a sanity check on the SelectedValue on the index.
if (lbxClient.SelectedIndex != -1)
{
int intClient = 0;
try
{
intClient = Convert.ToInt32(lbxClient.SelectedValue);
}
catch (Exception)
{
// catch if the value isn't integer.
intClient = -1;
}
}
I had the same problem but its resolved now by doing this
Replace this
lbxClient.DataSource = cS.cTableResults;
lbxClient.DisplayMember = "ClientName";
lbxClient.ValueMember = "ClientID";
With
lbxClient.DisplayMember = "ClientName";
lbxClient.ValueMember = "ClientID";
lbxClient.DataSource = cS.cTableResults;
Just place the first line "DataSource=" in last and the you will get rid out of it :)
The reason is doing this explained in #Sebastian answer.

Categories

Resources