I was having problem when using "Date" property.
My class here:
public bool ChuyenDSChamCong()
{
try
{
DataTable dta = DSChamCong();
if (dta == null)
return false;
foreach (DataRow r in dta.Rows)
{
try
{
string sql = "delete FROM tk_dlchamcong where MD5(CONCAT(ma_chamcong,ma_nv, tg_check)) = md5('" + r["CardID"] + r["StaffID"] + r["TransDT"].ToString() + "')";
MYSQLDB.query(sql);
while (((DateTime)r["TransDT"]).Date == (DateTime.Today).Date)
{
string sql1 = "INSERT INTO tk_dlchamcong(ID,ma_chamcong, ma_nv, tg_check)values(md5('" + r["CardID"] + r["StaffID"] + r["TransDT"].ToString() + "'),'" + r["CardID"] + "', '" + r["StaffID"] + "', '" + r["TransDT"] + "')";
MYSQLDB.query(sql1);
}
}
catch {
}
}
return true;
}
catch { }
return false;
}
I cannot use Date() property, it accept with Date only. But when I debug it show like this and jump to catch error.
It cannot compare, r["TransDT"] is DateTime. Here is image show error.
Updated: r["TransDT"] is object{string} in database has values: 11/11/2015 18:03:11
I was format this with query like:
FORMAT(TransDT,'dd/MM/yyyy HH:mm:ss') as TransDT from Transact
Error when debug:
Animate screenshot gif
The value could be null(DBNull.Value), you coudl try to cast it to a DateTime? with the as-operator. When the cast fails you get a Nullable<DateTime> with HasValue=false:
DateTime? TransDT = r["TransDT"] as DateTime?;
if(TransDT.HasValue && TransDT.Value.Date == DateTime.Today)
{
// ...
}
You don't need a while, an if is sufficient since you have a single DataRow.
Related
I would like to remove first two chatracter of a string but it is not working. Can i know why was this issue
while (rdr.Read())
{
if (rdr.HasRows)
{
sqlNew = sqlNew + "', '" + rdr.GetString(0);
}
else
{
break;
}
}
if (!(sqlNew == ""))
{
sqlNew = sqlNew + "'";
sqlNew.Substring(2);
}
textBox1.Text = sqlNew;
Substring doesn't modify the string (since strings are immutable), it returns a new string with the result, so:
sqlNew = sqlNew.Substring(2);
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")
Invalid attempt to call Read when reader is closed. getting this error asp.net with c#?
i have used this code
string catalogNo = string.Empty;
string deleteID = string.Empty;
Globals.Initialize("Text", "select CatelogNo,DeleteID from tbl_admin_quotation where QuotationID='" + quotation3 + "' order by id asc");
Globals.dr = Globals.cmd.ExecuteReader();
while (Globals.dr.Read() == true)
{
catalogNo = Globals.dr[0].ToString();
deleteID = Globals.dr[1].ToString();
decimal taqty = 0;
Globals.Initialize("Text", "select qty from tbl_admin_quotation where DeleteID='" + deleteID + "'");
Globals.dr3 = Globals.cmd.ExecuteReader();
if (Globals.dr3.Read() == true)
{
taqty = Convert.ToDecimal(Globals.dr3[0].ToString());
}
Globals.dr3.Dispose();
Globals.dr3.Close();
Globals.Initialize("Text", "select Pqty,Hqty from tbl_admin_stock where CatelogNo='" + catalogNo + "'");
Globals.dr = Globals.cmd.ExecuteReader();
if (Globals.dr.Read() == true)
{
if (Convert.ToDecimal(Globals.dr[0].ToString()) != 0)
{
Globals.Initialize("Text", "update tbl_admin_stock set Pqty=Pqty+'" + Convert.ToDecimal(taqty) + "' where CatelogNo='" + catalogNo + "'");
Globals.cmd.ExecuteNonQuery();
}
else if (Convert.ToDecimal(Globals.dr[1].ToString()) != 0)
{
Globals.Initialize("Text", "update tbl_admin_stock set Hqty=Hqty-'" + Convert.ToDecimal(taqty) + "' where CatelogNo='" + catalogNo + "'");
Globals.cmd.ExecuteNonQuery();
}
}
Globals.dr.Dispose();
Globals.dr.Close();
}
Globals.dr.Dispose();
Globals.dr.Close();
Globals.Initialize("Text", "delete from tbl_admin_quotation where QuotationId=#QuotationId");
Globals.cmd.Parameters.AddWithValue("#QuotationId", quotation3);
Globals.cmd.ExecuteNonQuery();
UpdatePanelMain.Update();
GridviewBind();
If you've code with obvious problems and problems you can't find, fix the obvious problems first and then the obscure problems will likely become obvious:
Get rid of the globals rubbish and put using in the appropriate places and then having the Dispose() called from that rather than explicitly will also fix this problem.
this problem is a bit of a difficult one to explain but here it goes. I have a function which adds a record to a MySQL Database online from a local SQLiteDatabase. A function is first called to retrieve the local data and each line is sent to the upload function which adds the record to the online MySQL Database. When these functions are called from a another function A it works fine but when called from a different function. Function B duplicate records are entered into the database.
During debugging to try and resolve the problem I find that when it is duplicating records it is going to cmd.executeNonQuery() then going to the next couple of line but then for no reason will go back up to cmd.executeNonQuery() therefore duplicating the record. The code is below
private void uploadDatabase(string company, string oldCompany, string companyURL, string loginUsername, string oldUsername, string password, string type, string perform, string direction)
{
Boolean recordFound = false;
recordFound = checkRecordNotExist(company, loginUsername);
MySQLDBWork dbase = new MySQLDBWork();
try
{
dbase.openConnection();
if (perform == "insert" && !recordFound)
{
string query = "INSERT INTO `" + username + "` (pas_company, pas_companyURL, pas_username, pas_password, pas_type) "
+ "VALUES ('" + company + "', '" + companyURL + "', '" + loginUsername + "', '" + password + "', '" + type + "')";
Console.WriteLine("Query: " + query);
MySqlCommand cmd = new MySqlCommand(query, dbase.conn);
cmd.ExecuteNonQuery();
recordFound = true;
query = "";
company = "";
loginUsername = "";
cmd.Dispose();
}
if (perform == "delete")
{
string query = "DELETE FROM `" + username + "` WHERE pas_company='" + company + "' AND pas_username='" + loginUsername + "'";
dbase.performQuery(query);
}
}
catch (MySqlException ex)
{
Console.WriteLine("Adding Online Error: " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("General Exception: " + ex.Message);
}
finally
{
dbase.closeConnection();
//dbase.conn.Dispose();
company = null;
loginUsername = null;
}
}
The problem is within the if statement perform == "insert" && !recordFound.
I'm not sure if the code above will help to solve the problem but this is the function that is going wrong when called from function b but works fine from function A. Thanks for any help and suggestions you can offer.
then going to the next couple of line
but then for no reason will go back up
to cmd.executeNonQuery()
That sounds like a simple multithreading problem. The function is accessed again from a different thread. So what's happening is that it goes through your check exists in both threads before it is inserted in either, and then it is inserted in both.
So, create a lock, and lock the code... something like this:
private System.Object uploadLock = new System.Object();
private void uploadDatabase(string company, string oldCompany, string companyURL, string loginUsername, string oldUsername, string password, string type, string perform, string direction)
{
lock(uploadLock ) {
Boolean recordFound = false;
recordFound = checkRecordNotExist(company, loginUsername);
MySQLDBWork dbase = new MySQLDBWork();
try
{
dbase.openConnection();
if (perform == "insert" && !recordFound)
{
string query = "INSERT INTO `" + username + "` (pas_company, pas_companyURL, pas_username, pas_password, pas_type) "
+ "VALUES ('" + company + "', '" + companyURL + "', '" + loginUsername + "', '" + password + "', '" + type + "')";
Console.WriteLine("Query: " + query);
MySqlCommand cmd = new MySqlCommand(query, dbase.conn);
cmd.ExecuteNonQuery();
recordFound = true;
query = "";
company = "";
loginUsername = "";
cmd.Dispose();
}
if (perform == "delete")
{
string query = "DELETE FROM `" + username + "` WHERE pas_company='" + company + "' AND pas_username='" + loginUsername + "'";
dbase.performQuery(query);
}
}
catch (MySqlException ex)
{
Console.WriteLine("Adding Online Error: " + ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("General Exception: " + ex.Message);
}
finally
{
dbase.closeConnection();
//dbase.conn.Dispose();
company = null;
loginUsername = null;
}
}
}
The lock will allow access to the code to only on thread at a time. So no more duplications.
My advice to you:
Always use transactions and you won't be able make duplications. You also may make LoginName column unique and properly handle db error.
DO NOT concatenate string to build query, please. Use command parameters - simplest way escape SQL injection. Currently you have at least 4 vulnerable parameter. Awesome ;)
I would suggest putting a breakpoint on cmd.ExecuteNonQuery(); and inspecting the call stack each time it is hit, paying special attention to the second/duplicate hit. Also pay attention to which thread the breakpoint is being hit on. Doing these things should point you to the problem.
First of all, please help me out! I can not take this anymore. I could not find where the error is located. Here is my problem:
I'm trying to update a row via c# winform application. The update query generated from the application is formatted correctly. I tested it in the sql server environment, it worked well. When i run it from the application i get 0 rows updated.
Here is the snippet that generates the update statement using reflection - don't try to figure it out. Carry on reading after the code portion:
public void Update(int cusID)
{
SqlCommand objSqlCommand = new SqlCommand();
Customer cust = new Customer();
string SQL = null;
try
{
if ((cusID != 0))
{
foreach (PropertyInfo PropertyItem in this.GetType().GetProperties())
{
if (!(PropertyItem.Name.ToString() == cust.PKName))
{
if (PropertyItem.Name.ToString() != "TableName")
{
if (SQL == null)
{
SQL = PropertyItem.Name.ToString() + " = #" + PropertyItem.Name.ToString();
}
else
{
SQL = SQL + ", " + PropertyItem.Name.ToString() + " = #" + PropertyItem.Name.ToString();
}
}
else
{
break;
}
}
}
objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL + " WHERE " + cust.PKName + " = #cusID AND PhoneNumber = " + "'" + "#phNum" + "'";
foreach (PropertyInfo PropertyItem in this.GetType().GetProperties())
{
if (!(PropertyItem.Name.ToString() == cust.PKName))
{
if (PropertyItem.Name.ToString() != "TableName")
{
objSqlCommand.Parameters.AddWithValue("#" + PropertyItem.Name.ToString(), PropertyItem.GetValue(this, null));
}
else
{
break;
}
}
}
objSqlCommand.Parameters.AddWithValue("#cusID", cusID);
objSqlCommand.Parameters.AddWithValue("#phNum", this.PhoneNumber);
DAL.ExecuteSQL(objSqlCommand);
}
else
{
//AppEventLog.AddWarning("Primary Key is not provided for Update.")
}
}
catch (Exception ex)
{
//AppEventLog.AddError(ex.Message.ToString)
}
}
This part below:
objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL + " WHERE " + cust.PKName + " = #cusID AND PhoneNumber = " + "'" + "#phNum" + "'";
generates dml:
UPDATE CustomerPhone SET PhoneTypeID = #PhoneTypeID, PhoneNumber = #PhoneNumber WHERE CustomerID = #cusID AND PhoneNumber = '#phNum'
#PhoneTypeID and #PhoneNumber are gotten from two properties. We assigned the value to these properties in the presentation layer from the user input text box. The portion below where fetches the values:
objSqlCommand.Parameters.AddWithValue("#" + PropertyItem.Name.ToString(), PropertyItem.GetValue(this, null));
The code below fills the values of WHERE:
objSqlCommand.Parameters.AddWithValue("#cusID", cusID);
objSqlCommand.Parameters.AddWithValue("#phNum", this.PhoneNumber);
The final code should look as:
UPDATE CustomerPhone
SET PhoneTypeID = 7, PhoneNumber = 999444
WHERE CustomerID = 500 AND PhoneNumber = '911';
Phone type id is 7 - user value that is taken from text box
Phone number is 999444 - user value that is taken from text box
The above final update statement works on the sql environment, but when running
via the application, the execute non query runs ok and gets 0 rows updated! I wonder why?
This is the problem:
AND PhoneNumber = '#phNum'
That's looking for a phone number which is exactly the text '#phNum' - it's not using a parameter called phNum. You want
AND PhoneNumber = #phNum
You're also breaking up your string literals for no obvious reason. This statement:
objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL +
" WHERE " + cust.PKName + " = #cusID AND PhoneNumber = " +
"'" + "#phNum" + "'";
would be more easily readable as:
objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL +
" WHERE " cust.PKName + " = #cusID AND PhoneNumber = '#phNum'";
Obviously you want to drop the single quotes from it, to make it just:
objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL +
" WHERE " cust.PKName + " = #cusID AND PhoneNumber = #phNum";
A little refactoring wouldn't go amiss, either. This loop:
foreach (PropertyInfo PropertyItem in this.GetType().GetProperties())
{
if (!(PropertyItem.Name.ToString() == cust.PKName))
{
if (PropertyItem.Name.ToString() != "TableName")
{
if (SQL == null)
{
SQL = PropertyItem.Name.ToString() + " = #" + PropertyItem.Name.ToString();
}
else
{
SQL = SQL + ", " + PropertyItem.Name.ToString() + " = #" + PropertyItem.Name.ToString();
}
}
else
{
break;
}
}
}
would be more simpler and more readable like this:
StringBuilder sqlBuilder = new StringBuilder();
foreach (PropertyInfo property in this.GetType().GetProperties())
{
string name = property.Name;
// I believe you had a bug before - the properties being updated
// would depend on the ordering of the properties - if it
// ran into "TableName" first, it would exit early!
// I *suspect* this is what you want
if (name != cust.PKName && name != "TableName")
{
sqlBuilder.AppendFormat("{0} = #{0}, ", name);
}
}
// Remove the trailing ", "
if (sqlBuilder.Length > 0)
{
sqlBuilder.Length -= 2;
}
You can do something similar with the final loop too.
Is PhoneNumber a string, or an integer?
I see you're SETting as a integer, but checking in the WHERE as a literal. Could this not be the problem?
If it's an integer, try:
UPDATE CustomerPhone
SET PhoneTypeID = 7, PhoneNumber = 999444
WHERE CustomerID = 500 AND PhoneNumber = 911;
If it's a string, try:
UPDATE CustomerPhone
SET PhoneTypeID = 7, PhoneNumber = '999444'
WHERE CustomerID = 500 AND PhoneNumber = '911';