There is something wrong with the following update query.
string sql = "update Car set plate = '" + textBox2.Text + "' , color='"
+ textBox3.Text + "' , model='"+textBox5.Text+ "' , year= "
+ textBox4.Text;
sql += " where carid= " + textBox1.Text;
int res = CarDatabase.executeOthers(sql);
if (res > 0)
{
string sql2 = "select * from Car";
DataTable dt = CarDatabase.executeSelect(sql2);
mainframe.DataGridView1.DataSource = dt;
MessageBox.Show("Updated Successfully");
}
Actually, I encounter the same problem when I add year to my query. Why? :S
The simple answer is that one of your TextBoxes probably has content that is breaking this. The better answer is to never, ever write a query this way because it is vulnerable to SQL injection attacks. You need to look at how to do parameterized queries.
Start by reading the How to: Execute a Parameterized Query article on MSDN.
Related
I am trying to add datatable if the data is not existing before
public async Task saveBetEntity(List<BetEntity> betList)
{
DataTable dt = new DataTable();
// dt.Columns.Add("ItemId");
dt.Columns.Add("Player_no");
dt.Columns.Add("PLAYER_BET_NUMBER");
dt.Columns.Add("BET_PLACED_DATE");
dt.Columns.Add("OVER_1000_SEK");
dt.Columns.Add("EVENT_NAME");
dt.Columns.Add("LEAGUE");
dt.Columns.Add("BET_OFFER_TYPE");
dt.Columns.Add("CRITERIA_NAME");
dt.Columns.Add("IS_LIVE");
dt.Columns.Add("BET_LABEL");
dt.Columns.Add("ODDS");
dt.Columns.Add("BET_OUTCOME");
if (betList != null && betList.Count > 0)
{
foreach (var item in betList)
{
DataRow dr = dt.NewRow();
dr["Player_no"] = item.Player_no;
dr["PLAYER_BET_NUMBER"] = item.PLAYER_BET_NUMBER;
dr["BET_PLACED_DATE"] = item.BET_PLACED_DATE;
dr["OVER_1000_SEK"] = item.OVER_1000_SEK;
dr["EVENT_NAME"] = item.EVENT_NAME;
dr["LEAGUE"] = item.LEAGUE;
dr["BET_OFFER_TYPE"] = item.BET_OFFER_TYPE;
dr["CRITERIA_NAME"] = item.CRITERIA_NAME;
dr["IS_LIVE"] = item.IS_LIVE;
dr["BET_LABEL"] = item.BET_LABEL;
dr["ODDS"] = item.ODDS;
dr["BET_OUTCOME"] = item.BET_OUTCOME;
dt.Rows.Add(dr);
}
for (int i = 0; i < dt.Rows.Count; i++)
{
string InsertQuery = string.Empty;
InsertQuery =
"IF NOT EXISTS (SELECT * FROM BetEntities WHERE Player_no =dt.Rows[i][\"Player_no\"].ToString() BEGIN" +
"INSERT INTO BetEntities " +
"(Player_no, PLAYER_BET_NUMBER, BET_PLACED_DATE, OVER_1000_SEK, EVENT_NAME," +
" LEAGUE, BET_OFFER_TYPE, CRITERIA_NAME, IS_LIVE, BET_LABEL, ODDS, BET_OUTCOME) " +
"VALUES ('" + dt.Rows[i]["Player_no"].ToString() + "','" + dt.Rows[i]["PLAYER_BET_NUMBER"].ToString() + "','" + dt.Rows[i]["BET_PLACED_DATE"].ToString()
+ "','" + dt.Rows[i]["OVER_1000_SEK"].ToString() + "','" + dt.Rows[i]["EVENT_NAME"].ToString() + "','" + dt.Rows[i]["LEAGUE"].ToString() +
"','" + dt.Rows[i]["BET_OFFER_TYPE"].ToString() + "','" + dt.Rows[i]["CRITERIA_NAME"].ToString() + "','" + dt.Rows[i]["IS_LIVE"].ToString() +
"','" + dt.Rows[i]["BET_LABEL"].ToString() + "','" + dt.Rows[i]["ODDS"].ToString() + "','" + dt.Rows[i]["BET_OUTCOME"].ToString() + "')" +
" WHERE NOT EXISTS ( SELECT * FROM BetEntities WHERE Player_no =dt.Rows[i][\"Player_no\"].ToString()" +
" AND PLAYER_BET_NUMBER = dt.Rows[i][\"PLAYER_BET_NUMBER\"].ToString() " +
" AND BET_PLACED_DATE =dt.Rows[i][\"BET_PLACED_DATE\"].ToString()" +
" AND OVER_1000_SEK =dt.Rows[i][\\\"OVER_1000_SEK\\\"].ToString()\"" +
" AND EVENT_NAME =dt.Rows[i][\\\"EVENT_NAME\\\"].ToString()\"" +
" AND LEAGUE =dt.Rows[i][\\\" LEAGUE\\\"].ToString()\"" +
" AND BET_OFFER_TYPE =dt.Rows[i][\\\"BET_OFFER_TYPE\\\"].ToString()\"" +
" AND CRITERIA_NAME =dt.Rows[i][\\\"CRITERIA_NAME\\\"].ToString()\"" +
" AND IS_LIVE =dt.Rows[i][\\\" IS_LIVE\\\"].ToString()\"" +
" AND BET_LABEL =dt.Rows[i][\\\"BET_LABEL\\\"].ToString()\"" +
" AND BET_OUTCOME=dt.Rows[i][\\\" BET_OUTCOME\\\"].ToString()\"" +
");";
using (SqlConnection destinationConnection = new SqlConnection(_configuration.GetConnectionString("ConnectionAPIConeectionString")))
using (var BetEntities = new SqlCommand(InsertQuery, destinationConnection))
{
destinationConnection.Open();
BetEntities.ExecuteNonQuery();
}
}
}
await Task.CompletedTask;
}
The code works fine if I delete
" WHERE NOT EXISTS ( SELECT * FROM BetEntities WHERE Player_no =dt.Rows[i][\"Player_no\"].ToString()" +
" AND PLAYER_BET_NUMBER = dt.Rows[i][\"PLAYER_BET_NUMBER\"].ToString() " +
" AND BET_PLACED_DATE =dt.Rows[i][\"BET_PLACED_DATE\"].ToString()" +
" AND OVER_1000_SEK =dt.Rows[i][\\\"OVER_1000_SEK\\\"].ToString()\"" +
" AND EVENT_NAME =dt.Rows[i][\\\"EVENT_NAME\\\"].ToString()\"" +
" AND LEAGUE =dt.Rows[i][\\\" LEAGUE\\\"].ToString()\"" +
" AND BET_OFFER_TYPE =dt.Rows[i][\\\"BET_OFFER_TYPE\\\"].ToString()\"" +
" AND CRITERIA_NAME =dt.Rows[i][\\\"CRITERIA_NAME\\\"].ToString()\"" +
" AND IS_LIVE =dt.Rows[i][\\\" IS_LIVE\\\"].ToString()\"" +
" AND BET_LABEL =dt.Rows[i][\\\"BET_LABEL\\\"].ToString()\"" +
" AND BET_OUTCOME=dt.Rows[i][\\\" BET_OUTCOME\\\"].ToString()\"" +
I don't want to add the data over and over, that's why I added this code.
You have many errors in your code.
First error is related to not using verbatim string. Without a verbatim string, your SQL Command is a mess and and it is very hard to see the basic errors there that would cause a syntax error on the SQL server side and wouldn't execute at all. You said it works if that "where" didn't exist, but your code is already erroenous without it.
Next there is error from T-SQL point of view if you didn't miss a single quote or double quote and wrote the command string perfectly correct. Your command would conceptually look like:
IF NOT EXISTS ( SELECT * FROM BetEntities WHERE Player_no ... )
BEGIN
INSERT INTO BetEntities
( Player_No, ... ) VALUES ( 1, ... )
WHERE NOT EXISTS (Select ... )
END;
However this is invalid T-SQL syntax. You can't use
... VALUES (...) WHERE
To overcome that limitation, you just need to change the syntax a bit and move that "NOT EXISTS" check to the "IF NOT EXISTS" check at top. That is what you are doing after all.
Third error is the one that you might have passed if you put all those + single and double quotes right in your code and that would be a guaranteed disaster in future if not today. You were lucky, indirectly it didn't work and you are here. As I said in comments, never ever write an SQL command like that concatenating strings and putting user inputs within that. That is because:
It makes your SQL code wide open to bad things, widely known as SQL Injection Attack.
Many users get away ignoring the use parameters saying, thinking it is only for SQL Injection Attacks and their code is never open to a real user input from outside or they think they are sanitizing it with some way (well hackers know ways against sanitization if I do know as one mere coder). However, it doesn't only prevent SQL Injection Attack but also take care of the formatting of input values themselves. For datetimes for example, if you were passing it as a string (don't), then it should be in a specific format in order to be independent of server settings. Or with a string, if the string itself contained quote or double quote (ie: O'Hara, 24" pipe) then it would fail or be interpreted in a very different way, although it was an innocent query.
You decide which one of the above reasons are more important in order to use parameters, but at the end I repeat:
Never ever write an SQL command like that concatenating strings and putting user inputs within that.
(I even have a tendency to write that in capitals:)
Then comes another question, why would you ever need a DataTable in between? Directly use the list itself.
A side note by the way, with a list or DataTable or whatever (like
json, xml, ...), if there are many rows to write, then instead of a
loop, you would surely want to do this with the SqlBulkCopy class or
T-SQL Bulk copy or using JSON, XML ...
OK, having said all these, here is a revised version of your code with parameters and verbatim string. You can see the difference in readability at least:
public async Task saveBetEntity(List<BetEntity> betList)
{
if (betList == null)
{
return;
}
string insertQuery = #"IF NOT EXISTS
(
SELECT *
FROM BetEntities
WHERE Player_no = #Player_no
AND PLAYER_BET_NUMBER = #PLAYER_BET_NUMBER
AND BET_PLACED_DATE = #BET_PLACED_DATE
AND OVER_1000_SEK = #OVER_1000_SEK
AND EVENT_NAME = #EVENT_NAME
AND LEAGUE = #LEAGUE
AND BET_OFFER_TYPE = #BET_OFFER_TYPE
AND CRITERIA_NAME = #CRITERIA_NAME
AND IS_LIVE = #IS_LIVE
AND BET_LABEL = #BET_LABEL
AND BET_OUTCOME = #BET_OUTCOME
)
BEGIN
INSERT INTO BetEntities
(
Player_no, PLAYER_BET_NUMBER, BET_PLACED_DATE,
OVER_1000_SEK, EVENT_NAME, LEAGUE,
BET_OFFER_TYPE, CRITERIA_NAME, IS_LIVE,
BET_LABEL, ODDS,BET_OUTCOME
)
VALUES
(#Player_no, #PLAYER_BET_NUMBER, #BET_PLACED_DATE,
#OVER_1000_SEK, #EVENT_NAME, #LEAGUE,
#BET_OFFER_TYPE, #CRITERIA_NAME, #IS_LIVE,
#BET_LABEL, #ODDS, #BET_OUTCOME);
END;
";
using (SqlConnection destinationConnection = new SqlConnection(_configuration.GetConnectionString("ConnectionAPIConeectionString")))
using (var insertCommand = new SqlCommand(insertQuery, destinationConnection))
{
insertCommand.Parameters.Add("#Player_no", SqlDbType.Int);
insertCommand.Parameters.Add("#PLAYER_BET_NUMBER", SqlDbType.Int);
insertCommand.Parameters.Add("#BET_PLACED_DATE", SqlDbType.DateTime);
insertCommand.Parameters.Add("#OVER_1000_SEK", SqlDbType.Text);
insertCommand.Parameters.Add("#EVENT_NAME", SqlDbType.Text);
insertCommand.Parameters.Add("#LEAGUE", SqlDbType.Text);
insertCommand.Parameters.Add("#BET_OFFER_TYPE", SqlDbType.Text);
insertCommand.Parameters.Add("#CRITERIA_NAME", SqlDbType.Text);
insertCommand.Parameters.Add("#IS_LIVE", SqlDbType.Bit);
insertCommand.Parameters.Add("#BET_LABEL", SqlDbType.Text);
insertCommand.Parameters.Add("#ODDS", SqlDbType.Text);
insertCommand.Parameters.Add("#BET_OUTCOME", SqlDbType.Text);
destinationConnection.Open();
foreach (var item in betList)
{
insertCommand.Parameters["#Player_no"].Value = item.Player_no;
insertCommand.Parameters["#PLAYER_BET_NUMBER"].Value = item.PLAYER_BET_NUMBER;
insertCommand.Parameters["#BET_PLACED_DATE"].Value = item.BET_PLACED_DATE;
insertCommand.Parameters["#OVER_1000_SEK"].Value = item.OVER_1000_SEK;
insertCommand.Parameters["#EVENT_NAME"].Value = item.EVENT_NAME;
insertCommand.Parameters["#LEAGUE"].Value = item.LEAGUE;
insertCommand.Parameters["#BET_OFFER_TYPE"].Value = item.BET_OFFER_TYPE;
insertCommand.Parameters["#CRITERIA_NAME"].Value = item.CRITERIA_NAME;
insertCommand.Parameters["#IS_LIVE"].Value = item.IS_LIVE;
insertCommand.Parameters["#BET_LABEL"].Value = item.BET_LABEL;
insertCommand.Parameters["#ODDS"].Value = item.ODDS;
insertCommand.Parameters["#BET_OUTCOME"].Value = item.BET_OUTCOME;
insertCommand.ExecuteNonQuery();
}
}
await Task.CompletedTask;
}
Note: I made guesses on the real SqlDbTypes. Reality might be different, and your list content might not be checked already (ie: It may contain a string value for something that is DateTime or a number, I skipped checking things like that which you should control with TryParse, if that is a possibility. With proper Lists it shouldn't be).
You will need to do it as you were doing before, otherwise, you are sending a string that SQL does not interpret:
Instead of this:
" WHERE NOT EXISTS ( SELECT * FROM BetEntities WHERE Player_no =dt.Rows[i][\"Player_no\"].ToString()" +
Do this for each value from the datatable:
" WHERE NOT EXISTS ( SELECT * FROM BetEntities WHERE Player_no = " + dt.Rows[i]["Player_no"].ToString() +
How to update bool in a database a sql query
below is the code i have but i am unsure of how to implement the checkbox.
Thank you for any help.
i have updated the code to remove the sql injection problems.
con.Open();
OleDbCommand cmd = new OleDbCommand(String.Concat("Select * From ", comboBox1.Text), con);
cmd.CommandType = CommandType.Text;
string tableName = comboBox1.Text.ToString();
cmd.CommandText = #"UPDATE [" + tableName + "] SET"
+"People_Call_Status = #People_Call_Status,"
+"Research_Date=#Research_Date,"
+ "tblCompanies_Area_Dialling_Code = #tblCompanies_Area_Dialling_Code,"
+ "Work_Number = #Work_Number,"
+ "building_Address = #building_Address,"
+ "[Street Address] = #[Street Address],"
+ "suburb = #suburb,"
+ "city = #city,"
+ "res_Code = #res_Code,"
+ "industry_Vertical_ID = #industry_Vertical_ID,"
+ "pO_Box = #pO_Box,"
+ "post_Office = #post_Office,"
+ "postal_Code = #postal_Code,"
+ "country_ID = #country_ID,"
+ "province_ID = #province_ID," //this line
+ "prospect = #prospect"
+ "WHERE Company_ID = #Company_ID ";
cmd.Parameters.AddWithValue("#People_Call_Status", Status_textBox1.Text);
cmd.Parameters.AddWithValue("#Research_Date", Date_textBox.Text);
cmd.Parameters.AddWithValue("#Company_Name", company_NameTextBox.Text);
cmd.Parameters.AddWithValue("#tblCompanies_Area_Dialling_Code", tblCompanies_Area_Dialling_CodeTextBox.Text);
cmd.Parameters.AddWithValue("#Work_Number", work_NumberTextBox.Text);
cmd.Parameters.AddWithValue("#building_Address", building_AddressTextBox.Text);
cmd.Parameters.AddWithValue("#[Street Address]", street_AddressTextBox.Text);
cmd.Parameters.AddWithValue("#suburb", suburbTextBox.Text);
cmd.Parameters.AddWithValue("#city", cityTextBox.Text);
cmd.Parameters.AddWithValue("#res_Code", res_CodeTextBox.Text);
cmd.Parameters.AddWithValue("#industry_Vertical_ID", industry_Vertical_IDTextBox.Text);
cmd.Parameters.AddWithValue("#pO_Box", pO_BoxTextBox.Text);
cmd.Parameters.AddWithValue("#post_Office", post_OfficeTextBox.Text);
cmd.Parameters.AddWithValue("#postal_Code", postal_CodeTextBox.Text);
cmd.Parameters.AddWithValue("#country_ID", country_IDTextBox.Text);
cmd.Parameters.AddWithValue("#province_ID", province_IDTextBox.Text);
cmd.Parameters.AddWithValue("#prospect", prospectCheckBox.Checked);
cmd.Parameters.AddWithValue("#Company_ID", company_IDTextBox.Text);
cmd.ExecuteNonQuery();
{
MessageBox.Show("Update Success!");
con.Close();
}
In SQL Server, bool is mapped as a bit datatype with 0 and 1 values.
So what you need to do is:
"', prospect = '" + prospectCheckBox.Checked ? 1 : 0
Side-Note:
Don't concatenate strings to build up your query from user data input, this is vulnerable to SQL injection. Instead, use parameterized queries or stored procedures.
What DBMS platform are you using, and can you show the DDL for the table?
I can't guarantee this will work, but instead of using AddWithValue try using the Add method with explicit types declared:
cmd.Parameters.Add(new OleDbParameter("#People_Call_Status", OleDbType.VarChar));
cmd.Parameters.Add(new OleDbParameter("#Research_Date", OleDbType.VarChar));
...
cmd.Parameters.Add(new OleDbParameter("#prospect", OleDbType.Boolean));
cmd.Parameters.Add(new OleDbParameter("#Company_ID", OleDbType.VarChar));
cmd.Parameters[0].Value = Status_textBox1.Text;
cmd.Parameters[1].Value = Date_textBox.Text;
...
cmd.Parameters[16].Value = prospectCheckBox.Checked;
cmd.Parameters[17].Value = company_IDTextBox.Text;
Also, with regards to SQL Injection, you still have a theoretical vulnerability:
cmd.CommandText = #"UPDATE [" + tableName + "] SET"
+ "People_Call_Status = #People_Call_Status,"
+ "Research_Date=#Research_Date,"
...
+ "prospect = #prospect"
+ "WHERE Company_ID = #Company_ID ";
I realize it's an obscure possibility, but if the tableName variable were to contain this string or something like it:
Table1 set foo = 'bar';
truncate table ba2;
update table3
You could see how it would compile, execute and do something other than what you had in mind. Again, I realize this is reaching, and your input does come from a combo box, but it's still a theoretical risk.
I am trying to update database records over a range in Access using SQL and C#. Using an UPDATE query keeps giving me an error
Syntax error (missing operator) in query expression
All of the query criteria is from user input. I have tried a number of sources to find an answer but I believe my SQL statement is correct. Below is the method that is performing the task that I need.
private void btnUpdate_Click(object sender, EventArgs e)
{
int teamYear = Convert.ToInt32(this.textBoxBegYear.Text);
int endYear = Convert.ToInt32(this.textBoxEndYear.Text);
string teamName = this.textBoxTeamName.Text;
string league = this.textBoxLeague.Text;
string conference = this.textBoxConf.Text;
string division = this.textBoxDivision.Text;
try
{
dbConn = new OleDbConnection();
dbConn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
+ ch + openFileDialog1.FileName + ch;
dbConn.Open();
sql = "UPDATE " + this.comboBox1.SelectedItem.ToString()
+ " SET LeagueName = #leagueName, ConferenceName = #conferenceName,
DivisionName = #divisionName WHERE TeamName = " + this.textBoxTeamName.Text
+ " AND TeamYear BETWEEN " + this.textBoxBegYear.Text
+ " AND " + this.textBoxEndYear.Text;
dbCmd = new OleDbCommand(sql, dbConn);
for (int i = teamYear; i <= endYear; i++)
{
dbCmd.Parameters.AddWithValue("#leagueName", league);
dbCmd.Parameters.AddWithValue("#conferenceName", conference);
dbCmd.Parameters.AddWithValue("#divisionName", division);
dbCmd.ExecuteNonQuery();
}
dbCmd.Connection.Close();
dbConn.Close();
}
catch (Exception err)
{
MessageBox.Show("Error: " + err.Message.ToString());
}
}
The exception comes from the second half of the SQL statement after the WHERE clause asking for a missing operator.
Can anyone happen to see what I may be missing? Any help would be appreciated.
Why don't you replace the code in the "try" block to this:
dbConn = new OleDbConnection();
dbConn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source="
+ ch + openFileDialog1.FileName + ch;
dbConn.Open();
sql = "UPDATE " + this.comboBox1.SelectedItem.ToString()
+ " SET LeagueName = #leagueName, ConferenceName = #conferenceName,
DivisionName = #divisionName WHERE TeamName = #teamName AND TeamYear BETWEEN #begYear AND #endYear";
dbCmd = new OleDbCommand(sql, dbConn);
for (int i = teamYear; i <= endYear; i++)
{
dbCmd.Parameters.AddWithValue("#leagueName", league);
dbCmd.Parameters.AddWithValue("#conferenceName", conference);
dbCmd.Parameters.AddWithValue("#divisionName", division);
dbCmd.Parameters.AddWithValue("#teamName", this.textBoxTeamName.Text);
dbCmd.Parameters.AddWithValue("#begYear", int.Parse(this.textBoxBegYear.Text));
dbCmd.Parameters.AddWithValue("#endYear", int.Parse(this.textBoxBegYear.Text));
dbCmd.ExecuteNonQuery();
}
dbCmd.Connection.Close();
dbConn.Close();
Therefore, you have better idea what the SQL query looks like, and you parameterize users' input to improve security (prevent any sql injection).
To troubleshoot your issue, you may need to debug into this piece of code and see what's the SQL query is, and try to execute it from your SQL client tool (such as Sql management studio), you will have better idea what goes wrong.
Hope this helps.
Henry Liang
You might be missing single quotes '...
TeamName = '" + this.textBoxTeamName.Text + "'
Also, I'm assuming this is just a project you're playing around with and nothing that will be available online? Reason I ask is that the SQL query is vulnerable to SQL injection attacks.
You need to escape the text from the user input with single quotes.
WHERE TeamName = '" + this.textBoxTeamName.Text
+ "' AND TeamYear BETWEEN " + this.textBoxBegYear.Text
+ " AND " + this.textBoxEndYear.Text;
(Notice the single quotes).
Please do not use the code you posted. Please read up on SQL Injection attacks and why your code is very unsafe and replace it with some properly cleaned input handling.
Im using this code
updt = new SqlCommand("update dailysale set totalunit1 = totalunit1 - " + double.Parse(textBox3.Text) +" where material = '" + comboBox4.SelectedItem.ToString() +"' AND sn > '" + enmbr + "' ", agr, transac);
but this doesn't make update whereas
SqlCommand up2 = new SqlCommand("update dailysale set sn = sn +2 where sn > '" + enmbr + "' ", agr,transac);
is working for me
Using a parameterized query avoid subtle syntax errors hidden in the string concatenation and prevent any possibility of Sql Injections
string cmdText = "update dailysale set totalunit1 = totalunit1 - #sold " +
"where material = #mat AND sn > #emb";
updt = new SqlCommand(cmdText, agr);
updt.Transaction = transac;
updt.Parameters.AddWithValue("#sold", Convert.ToDouble(textbox1.Text));
updt.Parameters.AddWithValue("#mat", comboBox4.SelectedItem.ToString());
updt.Parameters.AddWithValue("#emb", embr);
int rowsUpdated = updt.ExecuteNonQuery();
if(rowsUpdated > 0)
MessageBox.Show("Record updated!");
In your original text you miss the double quotes before the AND and probably the conversion of your textbox to a double introduces a decimal separator not understood by your database. Instead a parameterized query leaves the work to correctly quote the values to the framework code and your query text is no more obscured by the string concatenations and quoting
Did you check the result count?
if updt.ExecuteNonQuery() <> 0 Then
If it's zero then your where clause didn't select any records
If it's not zero then maybe you didn't commit your transaction.
transact.Commit()
I am having problem with my asp.net app, in which I am dynamically building SQL query where I am using WHERE clause and adding OR depending on the fields which is entered. here is the scenario.
I have a Four TextBox, out of 2 is DateTime
i would like to search in the database if there is a value in any one text-box and return the results that is bind to a GridView. Now, if there is more than one text-box value then i need to add that as well and build OR in where clause. if there are no values in any one of the text-box then need to return all the results. BUT i am having problem in building the query as i have to go through the if else loop to see if there is any value or null. here is my code.
StringBuilder selectQuery = new StringBuilder();
disCode = SearchTextCouponCode.Text;
disName = SearchTextCouponName.Text;
if(StartDate.SelectedDate != null)
startDate = StartDate.SelectedDate.ToString("yyyy-MM-dd");
if(EndDate.SelectedDate != null)
endDate = EndDate.SelectedDate.ToString("yyyy-MM-dd");
// here is the main thing where i am getting the error
if (!string.IsNullOrEmpty(disCode))
{
selectQuery.Append("DISCOUNTCode = '" + disCode + "'");
}
if (!string.IsNullOrEmpty(disName))
{
selectQuery.Append(" OR DISCOUNTName = '" + disName + "'");
}
if (startDate != "0001-01-01")
{
selectQuery.Append(" OR StartDate = '" + startDate + "'");
}
if(endDate != "0001-01-01")
selectQuery.Append(" OR EndDate = '" + endDate + "'");
// I am using Object Data Source and the method i am passing is taking care of the SQL injection
DataSourceDis.SelectParameters["sqlCriteria"].DefaultValue = selectQuery.ToString();
GridDis.DataBind();
now, when i run the app, and leave the disCode text-box empty, then the query start with OR and gives me the error that incorrect syntax near where ..
please help.
/////////////////////////////////////////////////////////
i am calling another method after building up this query which is taking care of SQL Injection
/////////////////////////////////////////////////////////
The easiest thing you could do is change WHERE to:
WHERE 1=0
And then ensure all of your WHERE conditions start with OR
As Richard has pointed out however, this is not best practice, and you would be better using a stored procedure or LINQ. Using stored procedures you could pass all these parameters to the procedure and then do something like:
AND (#disName IS NULL OR DiscountName=#disName)
You could set all lines to have " OR " at the end (instead of the start), such as...
selectQuery.Append("DISCOUNTCode = '" + disCode + "' OR ");
And then before using the .ToString() have...
if(selectQuery.Length > 0)
{
selectQuery.Length -= 4;
}
If you use the WHERE 1=0 OR solution, you may get performance impacts.
I'd recommend creating a variable to mark the conjunction and changing it when you add a condition
string conjuction = " ";
if (!string.IsNullOrEmpty(disCode))
{
selectQuery.Append(conjunction);
selectQuery.Append("DISCOUNTCode = '" + disCode + "'");
conjuction = " OR ";
}
if (!string.IsNullOrEmpty(disName))
{
selectQuery.Append(conjunction);
selectQuery.Append("DISCOUNTName = '" + disName + "'");
conjuction = " OR ";
}
etc.
I don't know where your inputs are coming from, but be aware of the potential for a SQL injection attack in your current code.
I'd generally do it like this;
var conds = new List<string> ();
// here is the main thing where i am getting the error
if (!string.IsNullOrEmpty(disCode))
{
conds.Add("DISCOUNTCode = '" + disCode + "'");
}
if (!string.IsNullOrEmpty(disName))
{
conds.Add("DISCOUNTName = '" + disName + "'");
}
if (startDate != "0001-01-01")
{
conds.Add("StartDate = '" + startDate + "'");
}
if(endDate != "0001-01-01")
conds.Add("EndDate = '" + endDate + "'");
selectQuery.Append(String.Join(" OR ",conds));
It's a bit hideous building queries like this - better to use prepared statements or LINQ or your own query building class.
A valid Sql query e.g. SELECT * FROM EMPLOYEE WHERE Name = 'Hat' OR SURNAME = 'SOFT'
Looks like you case when the query starts with OR your StringBuilder Appends the query like this
SELECT * FROM EMPLOYEE WHERE OR SURNAME = 'SOFT' and its invalid becuase the OR KEYWORD directly after WHERE
when your disCode text-box is empty then Condition will be "OR DISCOUNTName" which is wrong you can not use "OR" after where
if (!string.IsNullOrEmpty(disCode))
{
selectQuery.Append("DISCOUNTCode = '" + disCode + "'");
}
if (!string.IsNullOrEmpty(disName))
{
selectQuery.Append(" OR DISCOUNTName = '" + disName + "'");
}