I am quite new to ASP.NET and C#, so I still do not have much of an idea as to how things work. I basically get an error when I run my program and create a maintenance task. My code is shown right below:
private DataTable getMaintenance()
{
DataTable maintenance_dt = new DataTable();
maintenance_dt.Columns.Add("maintenance_ID");
maintenance_dt.Columns.Add("DAILY_MAINTENANCE");
maintenance_dt.Columns.Add("ADMIN_COMMENT");
string SQLstr = "SELECT MAINTENANCE_ID,DAILY_MAINTENANCE,ADMIN_COMMENT FROM " + maintenance_table + " where " + key + " like " + value + " order by MAINTENANCE_ID ";
using (DataTableReader objDataReader = OS.OSFunctions.executeSQLQuery(SQLstr))
{
while (objDataReader.Read())
{
DataRow mItem = maintenance_dt.NewRow();
mItem[0] = objDataReader["MAINTENANCE_ID"].ToString();
mItem[1] = objDataReader["DAILY_MAINTENANCE"].ToString();
if (objDataReader["ADMIN_COMMENT"] != DBNull.Value)
{
mItem[2] = objDataReader["ADMIN_COMMENT"].ToString();
}
else
{
mItem[2] = "";
}
maintenance_dt.Rows.Add(mItem);
}
}
return maintenance_dt;
}
The error I get from running this states
Object reference not set to an instance of an object. objDataReader was null
This occurs when I attempt to create a maintenance task. The code for that is also below right here:
protected void createMaintenance_Click(object sender, System.EventArgs e)
{
string SQLstr;
if (txtMaintenanceName.Text.Length > 0)
{
if (maintenance_table == "ACTIVE_DAILYMAINTENANCE")
{
SQLstr = "SELECT TOP(1) MAINTENANCE_ID FROM ACTIVE_DAILYMAINTENANCE WHERE SCHEDULE_DATE = " + value + " ORDER BY MAINTENANCE_ID desc";
using (DataTableReader objDataReader = OS.OSFunctions.executeSQLQuery(SQLstr))
{
if (objDataReader.Read())
{
int id = Convert.ToInt32(objDataReader["Maintenance_ID"]) + 1;
SQLstr = "insert into " + maintenance_table + " (maintenance_id, DAILY_MAINTENANCE, " + key + ", ADMIN_COMMENT) values ('" + id + "',"
+ " '" + txtMaintenanceName.Text + "'," + value + ",'" + txtAdminMaintenanceComment.Text + "')";
OS.OSFunctions.executeSQLNonQuery(SQLstr);
}
}
}
else
{
SQLstr = "insert into " + maintenance_table + "(DAILY_MAINTENANCE, " + key + ", ADMIN_COMMENT) values ('" + txtMaintenanceName.Text + "'," + value + ",'" + txtAdminMaintenanceComment.Text + "')";
OS.OSFunctions.executeSQLNonQuery(SQLstr);
}
}
Again, it is the getMaintenance() method giving me the error. This also isn't all my code, I do call the getMaintenance() function sometime later in the code for CreateMaintenance. Any help would be greatly appreciated.
EDIT: CODE TRYING OUT DATA SET
private DataSet getMaintenance()
{
DataSet maintenance_ds = new DataSet();
string SQLstr= "SELECT MAINTENANCE_ID,DAILY_MAINTENANCE,ADMIN_COMMENT FROM " + maintenance_table + " where " + key + " like " + value + " order by MAINTENANCE_ID ";
using(SqlConnection connection=new SqlConnection(ConfigurationManager.ConnectionStrings["SQLConnectionString"].ConnectionString))
{
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = new SqlCommand(SQLstr, connection);
adapter.Fill(maintenance_ds);
return maintenance_ds;
}
}
So, you execute
DataTableReader objDataReader = OS.OSFunctions.executeSQLQuery(SQLstr)
in your using. SQLstr is
"SELECT MAINTENANCE_ID,DAILY_MAINTENANCE,ADMIN_COMMENT FROM " + maintenance_table + " where " + key + " like " + value + " order by MAINTENANCE_ID ";
You will need to use a debugger and jump to this line just before the error is thrown. First of all, you will need to find out what maintenance_table, key and value is. Try finding out what the generated query is and run it in your RDBMS, I think it will most likely return a null for some reason.
It is possible that you are just missing a wildcard character of % being wrapped around value if you have the intention to have a "contains" rather than an "equals" check.
Anyway, in order to detect what the error is you will need to find out what is being generated and why your query results in a null. Once you know what the problem is, you will also know what you need to fix, which largely simplifies the problem.
Since you do not use a parameterized query, I have to mention that if any of the dynamic values you concatenate to the query may come from untrusted sources, such as user input, then your query is vulnerable to SQL injection and you will need to protect your project against this potential exploit.
You do realize that you can send the sql to a datatable, and the columns and the data table is created for you.
so, use this code to get/return a data table.
It not clear if you "else" is to update a existing row, or insert a new one, but the code can look somthing like this:
protected void createMaintenance_Click(object sender, System.EventArgs e)
{
DateTime value = DateTime.Today;
string maintenance_table = "";
string SQLstr = "";
string key = "";
if (txtMaintenanceName.Text.Length > 0)
{
if (maintenance_table == "ACTIVE_DAILYMAINTENANCE")
{
// add new row
int id = NextMaintID(value);
string strSQL = #"SELECT * FROM " + maintenance_table + " WHERE Maintenance_ID = 0";
DataTable rstSched = MyRst(strSQL);
DataRow MyNewRow = rstSched.NewRow();
MyNewRow["maintenance_id"] = id;
MyNewRow["DAILY_MAINTENANCE"] = txtMaintenanceName.Text;
MyNewRow["ADMIN_COMMENT"] = txtAdminMaintenanceComment.Text;
rstSched.Rows.Add(MyNewRow);
MyUpdate(rstSched, strSQL);
}
}
else
{
// update (or add to daily?????
string strSQL = #"SELECT * FROM " + maintenance_table + " WHERE Maintenance_ID = " + key;
DataTable rstSched = MyRst(strSQL);
DataRow MyRow = rstSched.Rows[0];
MyRow["DAILY_MAINTENANCE"] = txtMaintenanceName.Text;
MyRow["ADMIN_COMMENT"] = txtAdminMaintenanceComment.Text;
MyUpdate(rstSched, strSQL);
}
}
So, I only need a few helper routines - (make them global in a static class - you can then use it everywhere - saves boatloads of code.
so these were used:
public DataTable MyRst(string strSQL)
{
// return data table based on sql
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
cmdSQL.Connection.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
public DataTable MyRstP(SqlCommand cmdSQL)
{
// return data table based on sql command (for parmaters)
DataTable rstData = new DataTable();
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (cmdSQL)
{
cmdSQL.Connection = conn;
conn.Open();
rstData.Load(cmdSQL.ExecuteReader());
}
}
return rstData;
}
void MyUpdate(DataTable rstData, string strSQL)
{
using (SqlConnection conn = new SqlConnection(Properties.Settings.Default.TEST4))
{
using (SqlCommand cmdSQL = new SqlCommand(strSQL, conn))
{
conn.Open();
SqlDataAdapter da = new SqlDataAdapter(cmdSQL);
SqlCommandBuilder daU = new SqlCommandBuilder(da);
da.Update(rstData);
}
}
}
and of course this:
int NextMaintID (DateTime value)
{
int result = 0;
string SQLstr = #"SELECT TOP(1) MAINTENANCE_ID FROM ACTIVE_DAILYMAINTENANCE
WHERE SCHEDULE_DATE = #scDate ORDER BY MAINTENANCE_ID desc";
SqlCommand cmdSQL = new SqlCommand(SQLstr);
cmdSQL.Parameters.Add("#scDate", SqlDbType.Date).Value = value;
DataTable rstNextID = MyRstP(cmdSQL);
result = ((int)rstNextID.Rows[0]["Maintenance_ID"]) + 1;
return result;
}
So, how do you eat a elephant?
Answer: One bite at a time!!!
So, break out just a "few" helper routines that allows data operations against a data table object. That update command will work with edits, adds to rows, and even delete row method of a single row. All such updates can be thus be done with ONE simple update command.
Related
I had the following implementation of filling a DataTable with SQL:
var con = new SqlConnection();
var cmd = new SqlCommand();
var dt = new DataTable();
string sSQL = #"SELECT LogID, Severity, Title
FROM dbo.Log
WHERE UPPER(LogID) LIKE '%" + searchPhrase.ToUpper() + #"%' OR UPPER(Severity) LIKE '%" + searchPhrase.ToUpper() + #"%' OR UPPER(Title) LIKE '%" + searchPhrase.ToUpper() + #"%' ORDER BY " + orderBy + " " + orderFrom + #"
OFFSET ((" + (Convert.ToInt32(current) - 1).ToString() + ") * " + rowCount + #") ROWS
FETCH NEXT " + rowCount + " ROWS ONLY;";
try
{
using (var connection = THF.Models.SQLConnectionManager.GetConnection())
{
using (var command = new SqlCommand(sSQL, connection))
{
connection.Open();
command.CommandTimeout = 0;
var da = new SqlDataAdapter(command);
da.Fill(dt);
}
}
}
catch { }
This works nicely but I've realized that this is dangerous due to SQL Injection. So I've tried to solve that danger using parameterized queries like this:
var con = new SqlConnection();
var cmd = new SqlCommand();
var dt = new DataTable();
cmd.Parameters.Add(new ObjectParameter("#searchPhrase", searchPhrase.ToUpper()));
cmd.Parameters.Add(new ObjectParameter("#orderBy", orderBy));
cmd.Parameters.Add(new ObjectParameter("#orderFrom", orderFrom));
cmd.Parameters.Add(new ObjectParameter("#current", current));
cmd.Parameters.Add(new ObjectParameter("#rowCount", rowCount));
string sSQL = #"SELECT LogID, Severity, Title
FROM dbo.Log
WHERE UPPER(LogID) LIKE '%" + searchPhrase.ToUpper() + #"%' OR UPPER(Severity) LIKE '%" + searchPhrase.ToUpper() + #"%' OR UPPER(Title) LIKE '%" + searchPhrase.ToUpper() + #"%' ORDER BY " + orderBy + " " + orderFrom + #"
OFFSET ((" + (Convert.ToInt32(current) - 1).ToString() + ") * " + rowCount + #") ROWS
FETCH NEXT " + rowCount + " ROWS ONLY;";
try
{
using (var connection = THF.Models.SQLConnectionManager.GetConnection())
{
using (var command = new SqlCommand(sSQL, connection))
{
connection.Open();
command.CommandTimeout = 0;
var da = new SqlDataAdapter(command);
da.Fill(dt);
}
}
}
catch { }
Unfortunately now my data table doesn't fill. What am I doing wrong?
You are using multiple command and connection references, not sure if thats a copy/paste problem or your actual code is like that. In the second case it will not even compile.
Reference the parameters directly in your query, see below. Sql Server uses named parameters so the same parameter can be reused in multiple locations.
Desc/Asc cannot be used as a parameter. You should double check the value though or use an enum and pass that (recommended).
The same is true of the numeric values for rowcount, pass those in as numbers or check their values using a TryParse to ensure it is numeric and not malicious code.
The default install options for Sql Server is for a case insensitive coalition. This means you do not have to UPPER a string to do a comparison. If you do have a case sensitive install then do not change this, otherwise remove all calls to UPPER when doing comparisons.
Finally you well never know why your code is not working if you surround your code in try/catch and have an empty catch block. Your code will fail silently and you will be left scratching your head. Do not do this anywhere in your code, it is bad practice!! Either catch the exception and handle it (do something so code can recover) OR log it and rethrow using throw; OR do not catch it at all. I chose the later and removed it.
Code
var currentNum = Convert.ToInt32(current) - 1;
var temp = 0;
if(!"desc".Equals(orderFrom, StringComparison.OrdinalIgnoreCase) && !"asc".Equals(orderFrom, StringComparison.OrdinalIgnoreCase))
throw new ArgumentException("orderFrom is not a valid value");
if(!int.TryParse(rowCount, out temp))
throw new ArgumentException("Rowcount is not a valid number");
var dt = new DataTable();
string sSQL = #"SELECT LogID, Severity, Title
FROM dbo.Log
WHERE UPPER(LogID) LIKE #searchPhrase
OR UPPER(Severity) LIKE #searchPhrase
OR UPPER(Title) LIKE #searchPhrase
ORDER BY #orderBy " + orderFrom + "
OFFSET ((" + currentNum.ToString() + ") * " + rowCount + #") ROWS
FETCH NEXT " + rowCount + " ROWS ONLY;";
using (var connection = THF.Models.SQLConnectionManager.GetConnection())
using (var command = new SqlCommand(sSQL, connection))
{
cmd.Parameters.Add(new SqlParameter("#searchPhrase", "%" + searchPhrase.ToUpper() + "%"));
cmd.Parameters.Add(new SqlParameter("#orderBy", orderBy));
connection.Open();
command.CommandTimeout = 0;
var da = new SqlDataAdapter(command);
da.Fill(dt);
}
Here is a simple example of how this should be done.
con.Open();
SqlCommand cmd = new SqlCommand(#"insert into tbl_insert values(#name,#email,#add)", con);
cmd.Parameters.AddWithValue("#name", txtname.Text);
cmd.Parameters.AddWithValue("#email", txtemail.Text);
cmd.Parameters.AddWithValue("#add", txtadd.Text);
cmd.ExecuteNonQuery();
con.Close();
This is an example of one of the buttons. [I am able to retrieve the artist, name and genre from the database but not the price. What should the code be to retrieve the price? I have set the price datatype to varchar(50) in the database then tried the decimal and int and non of them work
protected void btnSong6_Click(object sender, EventArgs e)
{
string Name = "In the end";
Product Music = new Product();
string constr = ConfigurationManager.ConnectionStrings["RegisterConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(constr);
con.Open();
string SelectCommand = "select Genre,Name,Artist, Price from Music WHERE name = '" + Name + "' ";
SqlCommand cmd = new SqlCommand(SelectCommand, con);
SqlDataReader read = cmd.ExecuteReader();
read.Read();
Music.Artist = read["artist"].ToString();
Music.Name = read["name"].ToString();
Music.Genre = read["genre"].ToString();
Music.Price= read["price"].ToString();
//ADD PRICE!!
listMusic.Items.Add(Music.Genre + " : " + Music.Artist + " - " + Music.Name);
}
Your code looks fine, you are not using 'price' for anything though. Not exactly sure what you would like to do with 'price, maybe add it to 'listMusic'?
If 'Music.Price'is a decimal you will need to convert it:
Music.Price = Convert.ToDecimal(read["price"]);
Then add it to 'listMusic':
listMusic.Items.Add(Music.Genre + " : " + Music.Artist + " - " + Music.Name + " $" + Music.Price);
You should also consider changing your database 'price' column to Decimal. Above code should work either way.
To reduce the amount of type conversions required when retrieving column values have a look at this article. DataReader provides a series of methods allowing you to access column values in their native data types.
Something like:
using (SqlConnection con = new SqlConnection(constr))
{
string SelectCommand = "select Genre,Name,Artist, Price from Music WHERE Name = '" + Name + "' ";
SqlCommand cmd = new SqlCommand(SelectCommand, con);
con.Open();
SqlDataReader read = cmd.ExecuteReader();
if (read.HasRows)
{
while (read.Read())
{
Music.Genre = read.GetString(0);
Music.Name = read.GetString(1);
Music.Artist = read.GetString(2);
Music.Price = read.GetDecimal(3);
listMusic.Items.Add(Music.Genre + " : " + Music.Artist + " - " + Music.Name + " $" + Music.Price);
}
}
}
I'm having trouble with this method. It returns empty string, what is wrong with this ?
I have this method:
public static string GetData(string Table1, string Column1, string WhereColumn, string WhereValue)
{
Table1 = Methods.cleaninjection(Table1); // Some injection method that cleans the string
SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["connection"].ConnectionString);
SqlCommand command = new SqlCommand("SELECT " + "#Column1" + " FROM " + Table1 + " WHERE " + "#WhereColumn" + " = " + "#WhereValue", connection);
command.Parameters.AddWithValue("Column1", Column1);
command.Parameters.AddWithValue("WhereColumn", WhereColumn);
command.Parameters.AddWithValue("WhereValue", WhereValue);
try
{
if ((connection.State == ConnectionState.Closed) || (connection.State == ConnectionState.Broken))
{
connection.Open();
}
string veri = Convert.ToString(command.ExecuteScalar());
return veri;
}
finally
{
connection.Close();
}
}
When I run this, the command string looks like this:
SELECT #Column1 FROM Table1 WHERE #WhereColumn = #WhereValue
It looks like correct but I couldn't find what is wrong.
Any ideas?
As commented, you cannot parameterize your column names and table names. Instead, do string concatenation:
"SELECT " + Column1 + " FROM " + Table1 + " WHERE " + WhereColumn + " = #WhereValue";
Here is how your code should be:
public static string GetData(string Table1, string Column1, string WhereColumn, string WhereValue)
{
Table1 = Methods.cleaninjection(Table1); // My injection method that cleans the string
string sql = "SELECT " + Column1 + " FROM " + Table1 + " WHERE " + #WhereColumn + " = #WhereValue";
using (SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["connection"].ConnectionString))
{
using (SqlCommand command = new SqlCommand(sql, connection))
{
command.Parameters.Add("#WhereValue", SqlDbType.VarChar, 50).Value = WhereValue;
connection.Open();
string veri = Convert.ToString(command.ExecuteScalar());
return veri;
}
}
}
Notes:
Please do not use AddWithValue. Use Parameters.Add() instead. According to this article:
There is a problem with the AddWithValue() function: it has to infer
the database type for your query parameter. Here’s the thing:
sometimes it gets it wrong.
Wrap your object in Using to ensure proper cleanup of resources.
For additional security purposes, you can wrap your column name and table name in square brackets [].
i was trying to update two tables at once, but i got some syntax error on update code could u give me some idea? the insert code works perfect and i tried to copy the insert code and edit on update button clicked
here is my code
private void button2_Click(object sender, EventArgs e)
{
System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection();
conn.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;" +
#"Data source= C:\Users\user\Documents\Visual Studio 2010\Projects\WindowsFormsApplication1\WindowsFormsApplication1\crt_db.accdb";
try
{
conn.Open();
String Name = txtName.Text.ToString();
String AR = txtAr.Text.ToString();
String Wereda = txtWereda.Text.ToString();
String Kebele = txtKebele.Text.ToString();
String House_No = txtHouse.Text.ToString();
String P_O_BOX = txtPobox.Text.ToString();
String Tel = txtTel.Text.ToString();
String Fax = txtFax.Text.ToString();
String Email = txtEmail.Text.ToString();
String Item = txtItem.Text.ToString();
String Dep = txtDep.Text.ToString();
String k = "not renwed";
String Remark = txtRemark.Text.ToString();
String Type = txtType.Text.ToString();
String Brand = txtBrand.Text.ToString();
String License_No = txtlicense.Text.ToString();
String Date_issued = txtDate.Text.ToString();
String my_querry = "update crtPro set Name='" + Name + "',AR='" + AR + "',Wereda='" + Wereda + "',Kebele='" + Kebele + "',House_No='" + House_No + "',P_O_BOX='" + P_O_BOX + "',Tel='" + Tel + "',Fax='" + Fax + "',Email='" + Email + "',Item='" + Item + "',Dep='" + Dep + "','" + k + "',Remark='" + Remark + "' where Name='" + Name + "' ";
OleDbCommand cmd = new OleDbCommand(my_querry, conn);
cmd.ExecuteNonQuery();
String my_querry1 = "SELECT max(PID) FROM crtPro";
OleDbCommand cmd1 = new OleDbCommand(my_querry1, conn);
string var = cmd1.ExecuteScalar().ToString();
String ki = txtStatus.Text.ToString();
String my_querry2 = "update crtItemLicense set PID=" + var + ",Type='" + Type + "',Brand='" + Brand + "',License_No='" + License_No + "',Date_issued='" + Date_issued + "' where PID=" + var + "";
OleDbCommand cmd2 = new OleDbCommand(my_querry2, conn);
cmd2.ExecuteNonQuery();
MessageBox.Show("Message added succesfully");
}
catch (Exception ex)
{
MessageBox.Show("Failed due to" + ex.Message);
}
finally
{
conn.Close();
}
The most likely problem based on the little information given (what database are you using for example - SQL Server 2012?), is that the datatype you are providing in the concatenated dynamic sql does not match the datatype of the column in the database. You've surrounded each value with quotes - which means it will be interpreted as a varchar. If you've got a date value in the wrong format (ie if Date_Issued is a date column) or if it is a number column, then it will error.
The solution is to replace your dynamic SQL with a parameterized query eg:
String my_querry = "update crtPro set Name=#name, AR=#ar, Wereda=#Wereda, etc ...";
OleDbCommand cmd = new OleDbCommand(my_querry, conn);
cmd.Parameters.Clear();
cmd.Parameters.AddWithValue("#name", Name);
cmd.Parameters.AddWithValue("#myParam", Convert.ToDateTime(txtDate.Text.Trim()));
...
cmd.ExecuteNonQuery();
You can read about it further here
PS Make sure your parameters are in the same order as they are used in the SQL, because oledbcommand doesn't actually care what you call them. see here
I have this assignation function where the admin can assign a police ID to a selected memberreportID. Firstly, the admin will select the case, select the location and choose the number of officers needed for this case. For example if the admin chose 2 officers, it would then display 2 dropdownlist all binded to list down the policeID available.
protected void ddllocation_SelectedIndexChanged(object sender, EventArgs e)
{
using (var connAdd = new SqlConnection("Data Source = localhost; Initial Catalog = MajorProject; Integrated Security= SSPI"))
{
connAdd.Open();
var sql = "Select policeid from PoliceAccount where status ='available' and handle ='offcase' and postedto='" + ddllocation.SelectedValue + "'";
using (var cmdAdd = new SqlDataAdapter(sql, connAdd))
{
DataSet ds2 = new DataSet();
cmdAdd.Fill(ds2);
ddlpid1.Items.Clear();
ddlpid1.DataSource = ds2;
ddlpid1.DataTextField = "policeid";
ddlpid1.DataValueField = "policeid";
ddlpid1.DataBind();
ddlpid1.Items.Insert(0, new ListItem("Police ID", ""));
ddlpid1.SelectedIndex = 0;
ddlpid2.Items.Clear();
ddlpid2.DataSource = ds2;
ddlpid2.DataTextField = "policeid";
ddlpid2.DataValueField = "policeid";
ddlpid2.DataBind();
ddlpid2.Items.Insert(0, new ListItem("Police ID", ""));
ddlpid2.SelectedIndex = 0;
}
}
The first SQL command is how i insert them into the assignto column of the selected memberreportID in my database. I'm inserting both policeID i have assigned into the same column, assignto.
protected void btnAssign_Click1(object sender, EventArgs e)
{
using (var connAdd = new SqlConnection("Data Source = localhost; Initial Catalog = MajorProject; Integrated Security= SSPI"))
{
String assign = ddlpid1.SelectedValue + ", " + ddlpid2.SelectedValue + ";
connAdd.Open();
var sql = "Update MemberReport Set assignto ='" + assign + "' where memberreportID='" + lbmemberreportid.Text + "'";
using (var cmdAdd = new SqlCommand(sql, connAdd))
{
cmdAdd.ExecuteNonQuery();
}
sql = "Update PoliceAccount Set handle ='" + assign + "' where policeid ='" + ddlpid1.SelectedValue + "' OR '" + ddlpid2.SelectedValue + "'";
using (var cmdAdd = new SqlCommand(sql, connAdd))
{
cmdAdd.ExecuteNonQuery();
}
connAdd.Close();
}
}
However i'm also trying to input this policeID into a table called policeaccount by including the 2nd sql command. This policeaccount has a column called handle which is suppose to show the memberreportID he is handling at the moment. I'm trying to let each policeID's account to receive the selected memberreportID into their handle column by using the OR function. I'm pretty sure there's a OR function for sql syntax. But when i tried to insert i got this error instead
An expression of non-boolean type specified in a context where a condition is expected, near ''.
it should be as below
sql = "Update PoliceAccount Set handle ='" + assign + "' where policeid ='" + ddlpid1.SelectedValue + "' OR policeid = '" + ddlpid2.SelectedValue + "'";
Syntax is
UPDATE tblName Set col1 ='value'
WHERE col2 ='value2'
OR col2 ='value3'