System.Data.SqlClient.SqlException: Incorrect syntax near ')' - c#

I am getting an error in my SQL command with which I am trying to retrieve values from a SQL Server database. It is showing a error in browser as mentioned in title. If I remove the brackets it shows error in AND operator
string jdate = (string)Session["jdate"];
string clas = (string)Session["class"];
string scode = (string)Session["scode"];
string dcode = (string)Session["dcode"];
cn = new SqlConnection(ConfigurationManager.ConnectionStrings["dummyConnectionString"].ToString());
// error shows up on this line
string slct = "SELECT Route.Route_Source, Route.Route_Destination, Flight.Flight_Name, Schedule.Depart_Time, Schedule.Arr_Time, Schedule.Route_rate_Ad , Seats." + jdate +
"Schedule.Sch_id FROM Schedule INNER JOIN Flight ON Schedule.Flight_Id = Flight.Flight_id INNER JOIN Route ON Schedule.Route_id = Route.Route_id INNER JOIN Seats ON Seats.Sch_id = Schedule.Sch_id WHERE (Route.Route_Source =" + scode + ") AND (Route.Route_Destination =" + dcode + ") AND (Seats.Class=" + clas + ") ORDER BY Schedule.Depart_Time, Schedule.Arr_Time, Flight.Flight_Name";
cn.Open();
SqlDataAdapter da = new SqlDataAdapter(slct, cn);
DataSet ds = new DataSet();
da.Fill(ds);
SearchView.DataSource = ds;
SearchView.DataBind();

You should use a parameterized query.
This would allow a more understandable query text, avoid simple syntax errors
(like the missing comma at the end of the first line (jdate)),
avoid Sql Injections and parsing problems with strings containing quotes or decimal separators
string slct = #"SELECT Route.Route_Source, Route.Route_Destination,
Flight.Flight_Name, Schedule.Depart_Time, Schedule.Arr_Time,
Schedule.Route_rate_Ad, Seats." + jdate + ", Schedule.Sch_id " +
#"FROM Schedule INNER JOIN Flight ON Schedule.Flight_Id = Flight.Flight_id
INNER JOIN Route ON Schedule.Route_id = Route.Route_id
INNER JOIN Seats ON Seats.Sch_id = Schedule.Sch_id
WHERE (Route.Route_Source = #scode)
AND (Route.Route_Destination =#dcode)
AND (Seats.Class=#class)
ORDER BY Schedule.Depart_Time, Schedule.Arr_Time, Flight.Flight_Name";
cn.Open();
SqlCommand cmd = new SqlCommand(slct, cn);
cmd.Parameters.AddWithValue("#scode", scode);
cmd.Parameters.AddWithValue("#dcode", dcode);
cmd.Parameters.AddWithValue("#class", clas);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);

Related

How can I use a Session string in a SQL command?

I'm trying to use a session string variable as a WHERE clause condition in a SQL command, code below in C#
static string strConn = ConfigurationManager.ConnectionStrings["pEAnUtWoRM"].ToString();
SqlConnection conn = new SqlConnection(strConn);
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
displayProfiles();
}
}
private void displayProfiles()
{
if (Session["email"] != null )
{
string email = Convert.ToString(Session["email"]);
SqlCommand cmd = new SqlCommand("SELECT Student.Name FROM Student " +
"LEFT JOIN Mentor ON Student.MentorID = Mentor.MentorID " +
"WHERE Mentor.EmailAddr = " + email.ToString(), conn);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet result = new DataSet();
conn.Open();
da.Fill(result, "StudentProfile");
conn.Close();
gvProfileList.DataSource = result.Tables["StudentProfile"];
gvProfileList.DataBind();
}
}
Connection strings and SqlConnection work fine (it's not in the method) as I've tested it out on other aspx pages. Error says:
System.Data.SqlClient.SqlException: The multi-part identifier could not be bound on da.Fill(result, "StudentProfile");
The exception is thrown because the query syntax is incorrect since the value of email.ToString() is not appropriately escaped, resulting in a query such as the following one:
SELECT
Student.Name
FROM
Student
LEFT JOIN
Mentor ON Student.MentorID = Mentor.MentorID
WHERE
Mentor.EmailAddr = email#outlook.com
My assumption is that your intent was to produce the following query, where the value of email.ToString() (e.g. email#outlook.com) is between single quotes:
SELECT
Student.Name
FROM
Student
LEFT JOIN
Mentor ON Student.MentorID = Mentor.MentorID
WHERE
Mentor.EmailAddr = 'email#outlook.com'
A possible fix would be adding a parameter (e.g. #EmailAddress) to the SQL command and assigning the email value to it as follows:
const string EMAIL_ADDRESS_PARAMETER_NAME = "#EmailAddress";
SqlCommand cmd = new SqlCommand("SELECT Student.Name FROM Student " +
"LEFT JOIN Mentor ON Student.MentorID = Mentor.MentorID " +
$"WHERE Mentor.EmailAddr={EMAIL_ADDRESS_PARAMETER_NAME}", conn);
cmd.Parameters.Add(EMAIL_ADDRESS_PARAMETER_NAME, SqlDbType.VarChar).Value = email;

Combo box Where Clause

i have a table of POMain po_no and a table of Shipping invoice, then when i search the po_no, i will add an invoice. the thing i want to do is if the po_no already have an invoice the po_no in search button will not appear
public AddForm()
{
InitializeComponent();
string ID = cb_po_search.SelectedValue.ToString();
string strPRSconn = ConfigurationManager.ConnectionStrings["POSdb"].ConnectionString;
SqlConnection sc = new SqlConnection(strPRSconn);
sc.Open();
string strQry = "SELECT POMain.po_no FROM POMain LEFT JOIN Shipping ON POMain.po_no = Shipping.po_no WHERE Shipping.invoice IS NULL AND POMain.po_no = '" + ID + "'";
SqlCommand scmd = new SqlCommand(strQry, sc);
SqlDataReader dr = scmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Columns.Add("po_no", typeof(string));
dt.Load(dr);
cb_po_search.ValueMember = "po_no";
cb_po_search.DisplayMember = "po_no";
cb_po_search.DataSource = dt;
sc.Close();
}
}
You need to use a LEFT OUTER join here instead of an INNER join
string strQry ="SELECT POMain.po_no FROM POMain INNER JOIN Shipping ON POMain.po_no = Shipping.po_no WHERE Shipping.invoice IS NULL";
And you need to add another condition to the WHERE clause at the end:
AND POMain.po_no = " + ID
Having said that, you would be much better off using a stored procedure instead of trying to form an inline query.

Syntax Error on INNER JOIN in MySQL

I get a error when trying to inner join databases from a MySqL server.
I get this error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'lines INNER JOIN snippets ON snippets.id = lines.snippetid_fk WHERE lines.snippe' at line 1
Im Coding in ASP.Net C#.
This is my function that gives the error:
MySqlConnection conn = new MySqlConnection();
string mysql = "Server=***;Database=***;User=***;pwd=***";
conn.ConnectionString = mysql;
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "SELECT * FROM lines " +
"INNER JOIN snippets ON snippets.id = lines.snippetid_fk " +
"WHERE lines.snippetid_fk = 1";
cmd.Connection = conn;
DataTable dt = new DataTable();
MySqlDataAdapter adapter = new MySqlDataAdapter(cmd);
adapter.Fill(dt);
Repeater_codebank.DataSource = dt;
Repeater_codebank.DataBind();
According to documentation, lines is in the list of MySQL reserved words.
For your query, to work, you must add backticks around the table name:
cmd.CommandText = "SELECT * FROM `lines` " +
"INNER JOIN snippets ON snippets.id = lines.snippetid_fk " +
"WHERE `lines`.snippetid_fk = 1";

Wildcards in T-SQL LIKE vs. ASP.net parameters

In my SQL statement I use wildcards. But when I try to select something, it never select something. While when I execute the query in Microsoft SQL Server Management Studio, it works fine.
What am I doing wrong?
Click handler
protected void btnTitelAuteur_Click(object sender, EventArgs e)
{
cvalTitelAuteur.Enabled = true;
cvalTitelAuteur.Validate();
if (Page.IsValid)
{
objdsSelectedBooks.SelectMethod = "getBooksByTitleAuthor";
objdsSelectedBooks.SelectParameters.Clear();
objdsSelectedBooks.SelectParameters.Add(new Parameter("title", DbType.String));
objdsSelectedBooks.SelectParameters.Add(new Parameter("author", DbType.String));
objdsSelectedBooks.Select();
gvSelectedBooks.DataBind();
pnlZoeken.Visible = false;
pnlKiezen.Visible = true;
}
}
In my Data Access Layer
public static DataTable getBooksByTitleAuthor(string title, string author)
{
string sql = "SELECT 'AUTHOR' = tblAuthors.FIRSTNAME + ' ' + tblAuthors.LASTNAME, tblBooks.*, tblGenres.GENRE "
+ "FROM tblAuthors INNER JOIN tblBooks ON tblAuthors.AUTHOR_ID = tblBooks.AUTHOR_ID INNER JOIN tblGenres ON tblBooks.GENRE_ID = tblGenres.GENRE_ID "
+"WHERE (tblBooks.TITLE LIKE '%#title%');";
SqlDataAdapter da = new SqlDataAdapter(sql, GetConnectionString());
da.SelectCommand.Parameters.Add("#title", SqlDbType.Text);
da.SelectCommand.Parameters["#title"].Value = title;
DataSet ds = new DataSet();
da.Fill(ds, "Books");
return ds.Tables["Books"];
}
Try this:
string sql = "SELECT 'AUTHOR' = tblAuthors.FIRSTNAME + ' ' + tblAuthors.LASTNAME, tblBooks.*, tblGenres.GENRE "
+ "FROM tblAuthors INNER JOIN tblBooks ON tblAuthors.AUTHOR_ID = tblBooks.AUTHOR_ID INNER JOIN tblGenres ON tblBooks.GENRE_ID = tblGenres.GENRE_ID "
+"WHERE (tblBooks.TITLE LIKE #title);";
SqlDataAdapter da = new SqlDataAdapter(sql, GetConnectionString());
da.SelectCommand.Parameters.Add("#title", SqlDbType.Text);
da.SelectCommand.Parameters["#title"].Value = "%" + title + "%";
You can't include your query parameter inside a string literal. Do it like this instead:
WHERE (tblBooks.TITLE LIKE '%' + #title + '%');
Also, whenever you have a leading wildcard you should look into a full text index instead. Your query as written is doomed to be much slower than it could be, because you can't use index when you have a leading wild card.
The answer from John Allers is correct. As an aside, you should wrap the SqlDataAdapter in a using block:
using (SqlDataAdapter da = new SqlDataAdapter(sql, GetConnectionString()))
{
da.SelectCommand.Parameters.Add("#title", SqlDbType.Text);
da.SelectCommand.Parameters["#title"].Value = title;
DataSet ds = new DataSet();
da.Fill(ds, "Books");
return ds.Tables["Books"];
}

Dataset returning ZERO results

I am trying to fill in a combobox on my winform app from the database. I know there is info in the DB. I know the SP works. It returns the correct ColumnNames. But the DataSet itself is empty? Help!?!?
Call from my form-->
cboDiagnosisDescription.Properties.DataSource = myDiagnosis.RetrieveDiagnosisCodes();
The RetrieveDiagnosisCodes -->
public DataSet RetrieveDiagnosisCodes()
{
string tableName = "tblDiagnosisCues";
string strSQL = null;
DataSet ds = new DataSet(tableName);
SqlConnection cnn = new SqlConnection(Settings.Default.CMOSQLConn);
//strSQL = "select * from " & tableName & " where effectivedate <= getdate() and (termdate >= getdate() or termdate is null)"
strSQL = "select tblDiagnosisCues.*, tblDiagnosisCategory.Description as CategoryDesc, tblDiagnosisSubCategory.Description as SubCategoryDesc " + "FROM dbo.tblDiagnosisCategory INNER JOIN " + "dbo.tblDiagnosisSubCategory ON dbo.tblDiagnosisCategory.Category = dbo.tblDiagnosisSubCategory.Category INNER JOIN " + "dbo.tblDiagnosisCues ON dbo.tblDiagnosisSubCategory.SubCategory = dbo.tblDiagnosisCues.SubCategoryID " + "where effectivedate <= getdate() and (termdate >= getdate() or termdate is null) order by tblDiagnosisCues.Description";
SqlCommand cmd = new SqlCommand(strSQL, cnn) {CommandType = CommandType.Text};
SqlDataAdapter da = new SqlDataAdapter(cmd);
try
{
//cnn.Open();
da.Fill(ds);
}
catch (Exception ex)
{
throw;
}
finally
{
cmd.Dispose();
da.Dispose();
//ds.Dispose();
cnn.Close();
cnn.Dispose();
}
return ds;
}
The reason I know it is returning the correct column names is that I tried the following with a DevExpress LookUpEdit box and it populates the correct columns from the DB -->
var myDiagnosis = new Diagnosis();
var ds = myDiagnosis.RetrieveDiagnosisCodes();
lkuDiagnosis.Properties.DataSource = ds;
lkuDiagnosis.Properties.PopulateColumns();
lkuDiagnosis.Properties.DisplayMember = ds.Tables[0].Columns[1].ColumnName;
lkuDiagnosis.Properties.ValueMember = ds.Tables[0].Columns[0].ColumnName;
Ideas? Mainly, I don't even know how to proceed tracking this down...How to debug it?
EDIT 1
Based on a comment I ran the following SQL by itself and it returned 650 results...
select tblDiagnosisCues.*,
tblDiagnosisCategory.Description as CategoryDesc,
tblDiagnosisSubCategory.Description as SubCategoryDesc
FROM dbo.tblDiagnosisCategory
INNER JOIN dbo.tblDiagnosisSubCategory
ON dbo.tblDiagnosisCategory.Category = dbo.tblDiagnosisSubCategory.Category
INNER JOIN dbo.tblDiagnosisCues ON dbo.tblDiagnosisSubCategory.SubCategory = dbo.tblDiagnosisCues.SubCategoryID
where effectivedate <= getdate() and (termdate >= getdate() or termdate is null) order by tblDiagnosisCues.Description
//cnn.open();
...
//ds.dispose();
There is no need to specify a table name in the dataset constructor. The fill method will add a table. Also no need to open the connection since the sqldataadapter will open and close the connection for you. Also, I prefer to return a datatable as opposed to dataset with one table.
The code could be refactored to the following...of coure add the try catch if you want to log the exception.
public DataTable RetrieveDiagnosisCodes()
{
//string tableName = "tblDiagnosisCues";
DataSet ds = new DataSet();
Datatable dt = null;
//strSQL = "select * from " & tableName & " where effectivedate <= getdate() and (termdate >= getdate() or termdate is null)"
string strSQL = "select tblDiagnosisCues.*, tblDiagnosisCategory.Description as CategoryDesc, tblDiagnosisSubCategory.Description as SubCategoryDesc " + "FROM dbo.tblDiagnosisCategory INNER JOIN " + "dbo.tblDiagnosisSubCategory ON dbo.tblDiagnosisCategory.Category = dbo.tblDiagnosisSubCategory.Category INNER JOIN " + "dbo.tblDiagnosisCues ON dbo.tblDiagnosisSubCategory.SubCategory = dbo.tblDiagnosisCues.SubCategoryID " + "where effectivedate <= getdate() and (termdate >= getdate() or termdate is null) order by tblDiagnosisCues.Description";
using(SqlDataAdapter da = new SqlDataAdapter(strSQL, Settings.Default.CMOSQLConn))
{
da.Fill(ds);
}
if (ds.Tables.Count > 0)
{
dt = ds.Tables[0];
}
return dt;
}
If the data is properly binding to another control, it indicates that there is an issue with the databinding process. What does your databinding setup look like for the combobox in question? Are all the column names properly spelled and setup?

Categories