Click here to Skip to main content
15,922,650 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
C#
private void LoadData_Click(object sender, EventArgs e)
{
   using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["cn"].ConnectionString))
   {
      if (db.State == ConnectionState.Closed)
         db.Open();
      string query = "select o.OrderID, c.CustomerID, c.ContactName, c.Address, c.PostalCode, c.City, c.Phone, o.OrderDate" +
         "from Orders o inner join Customers c on o.CustomerID = c.CustomerID" +
         $" Where o.OrderDate between convert(varchar(25),'{dtFromDate.EditValue}',103) and convert(varchar(25),'{dtToDate.EditValue}',103)";
      ordersBindingSource.DataSource = db.Query(query, commandType: CommandType.Text);
   }

please help me..? System.data.sqlclient.sqlexception: 'incorrect syntax near 'o'.' anyone know what problem is this?

What I have tried:

C#
private void LoadData_Click(object sender, EventArgs e)
{
   using (IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["cn"].ConnectionString))
   {
      if (db.State == ConnectionState.Closed)
         db.Open();
      string query = "select o.OrderID, c.CustomerID, c.ContactName, c.Address, c.PostalCode, c.City, c.Phone, o.OrderDate" +
         "from Orders o inner join Customers c on o.CustomerID = c.CustomerID" +
         $" Where o.OrderDate between convert(varchar(25),'{dtFromDate.EditValue}',103) and convert(varchar(25),'{dtToDate.EditValue}',103)";
      ordersBindingSource.DataSource = db.Query(query, commandType: CommandType.Text);
   }
Posted
Updated 20-Jan-20 5:55am
v2

Look at the value of "query", what SQL does it contain? Probably

select o.OrderID, c.CustomerID, c.ContactName, c.Address, c.PostalCode, c.City, c.Phone, o.OrderDatefrom Orders o


that's not valid, you're missing a space before "from".

string query = "select o.OrderID, c.CustomerID, c.ContactName, c.Address, c.PostalCode, c.City, c.Phone, o.OrderDate" +
            " from Orders o inner join Customers c on o.CustomerID = c.CustomerID" +
 
Share this answer
 
Don't do it like that! Never concatenate strings to build a SQL command. It leaves you wide open to accidental or deliberate SQL Injection attack which can destroy your entire database. Always use Parameterized queries instead.

When you concatenate strings, you cause problems because SQL receives commands like:
SQL
SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
The quote the user added terminates the string as far as SQL is concerned and you get problems. But it could be worse. If I come along and type this instead: "x';DROP TABLE MyTable;--" Then SQL receives a very different command:
SQL
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Which SQL sees as three separate commands:
SQL
SELECT * FROM MyTable WHERE StreetAddress = 'x';
A perfectly valid SELECT
SQL
DROP TABLE MyTable;
A perfectly valid "delete the table" command
SQL
--'
And everything else is a comment.
So it does: selects any matching rows, deletes the table from the DB, and ignores anything else.

So ALWAYS use parameterized queries! Or be prepared to restore your DB from backup frequently. You do take backups regularly, don't you?

In this specific case it won't risk your DB getting deleted, - it'll do something much worse. It risks your data being inaccurate, or mixed inaccurate with accurate, or failing at the end of the month, etc.
You are specifying a string based format European date - and that's fine (ish) until the database system is changed, upgraded, or reconfigured. If the date locale in use doesn't match European date format, then you will start to get real problems - and a new PC / new SQL Server installation will default to US dates, and your problems start ...
Just use parameters, and pass the actual value instead of a text string and all of this goes away.

And look at your code:
C#
string query = "select o.OrderID, c.CustomerID, c.ContactName, c.Address, c.PostalCode, c.City, c.Phone, o.OrderDate" +
"from Orders o inner join Customers c on o.CustomerID = c.CustomerID" +
Lets cut out the dross, so you can see where the problem is:
C#
string query = "... , o.OrderDate" +
"from Orders o ..." +
Join 'em together and the string passed to SQL is:
"... , o.OrderDatefrom Orders o ..."

You need a space in there.
 
Share this answer
 
A few suggestions for this, and for future development.

1. As has been pointed out, as-is this query is vulnerable to SQL Injection. Do not concatenate strings together to build an SQL Command. Your values should be added in via the SqlCommand Parameters collection.

2. Variables- Best practice says the values being passed in should be actual DateTime values in both the SQL Table as well as the values being passed in.

3. Instead of "string addition", consider using the StringBuilder class. It makes the code look a little cleaner; and by using the AppendLine method there is whitespace within the query if you should forget a space at the end of a line.

This would give you changes something like this to build your SQL statement
C#
StringBuilder qb = new StringBuilder();
qb.AppendLine("SELECT o.OrderID, c.CustomerID, c.ContactName, c.Address, c.PostalCode, c.City, c.Phone, o.OrderDate ");
qb.AppendLine("FROM   Orders o INNER JOIN Customers c ON o.CustomerID = c.CustomerID ");
qb.AppendLine("WHERE  o.OrderDate BETWEEN @DateFrom AND @DateTo ");

SqlCommand cmd = new SqlCommand(qb.ToString(), db);
// cmd.CommandType = CommandType.Text   // NOT NEEDED- this is default
cmd.Parameters.AddWithValue("@DateFrom", dtFromDate.EditValue); // VERIFY Type
cmd.Parameters.AddWithValue("@DateTo", dtToDate.EditValue);     // VERIFY Type

Further down the line; you may want to move the actual query out to your database, perhaps as a View or as a Stored Procedure(preferred). You would still need to have the parameters BUT you will find the code needed within C# to have a few less lines, but the parameters could be kept as is.

With that query defining a view, your code would change to
C#
string query = "SELECT * FROM vw_OrdersCustomers WHERE OrderDate BETWEEN @DateFrom AND @DateTo";

SqlCommand cmd = new SqlCommand(query, db);
cmd.Parameters.AddWithValue("@DateFrom", dtFromDate.EditValue);
cmd.Parameters.AddWithValue("@DateTo", dtToDate.EditValue);
And as a Stored Procedure it would look like this; please note that you will now need to define the CommandType
C#
string query = "dbo.OrdersCustomers_SelectByDateRange";

SqlCommand cmd = new SqlCommand(query, db);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@DateFrom", dtFromDate.EditValue);
cmd.Parameters.AddWithValue("@DateTo", dtToDate.EditValue);mmandType.Text);
 
Share this answer
 
To add a minor detail to previous answers. One problem you're facing is that after the concatenation you have no space before FROM.

Have a look at
C#
string query = "select o.OrderID, c.CustomerID, c.ContactName, c.Address, c.PostalCode, c.City, c.Phone, o.OrderDate" +
         "from Orders o inner join Customers c o

In overall, personally I prefer using verbatim strings which allow formatting the SQL statements nicely. In other words
C#
string query = @"
SELECT o.OrderID, 
       c.CustomerID, 
       c.ContactName, 
       c.Address, 
       c.PostalCode, 
       c.City, 
       c.Phone, 
       o.OrderDate
FROM Orders o 
INNER JOIN Customers c ON o.CustomerID = c.CustomerID ......

For more info, have a look at @ - C# Reference | Microsoft Docs[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900