I am using a C# program that calls a SQL statement that is executed on an instance of SQL Server 2008 R2. Here is the SQL Call:
SELECT TOP 1 as1.AssetTagID, as1.TagID, as1.CategoryID, as1.Description,
as1.HomeLocationID, as1.ParentAssetTagID
FROM Assets AS as1 ORDER BY ar.DateScanned DESC
INNER JOIN AssetsReads AS ar
ON as1.AssetTagID = ar.AssetTagID
WHERE (ar.ReadPointLocationID='Readpoint1' OR ar.ReadPointLocationID='Readpoint2')
AND as1.TagID!='000000000000000000000000';
I am getting an SQLException around INNER. The exception text is the following:
System.Data.SqlClient.SqlException: Incorrect syntax near the keyword 'INNER'.
I can put the stack trace on here as well, but I felt like it would clutter the question. Here is the actual string in the C# code that I am using with the call:
"SELECT TOP 2 as1.AssetTagID, as1.TagID, " +
"as1.CategoryID, as1.Description, as1.HomeLocationID," +
"as1.ParentAssetTagID FROM Assets AS as1 ORDER BY ar.DateScanned DESC\n" +
"INNER JOIN AssetsReads AS ar ON as1.AssetTagID = ar.AssetTagID\n" +
"WHERE (ar.ReadPointLocationID='" + IntegrationService.Lane2Zones[0] +
"' OR ar.ReadPointLocationID='" + IntegrationService.Lane2Zones[1] + "')\n" +
"AND as1.TagID!='000000000000000000000000';"
Your ORDER BY statement can't be there. Move it to the end
I'll also give the obligatory "Don't do this" speech. Concatenating SQL strings like this opens you up to SQL injection attacks. There is plenty of information about that on SO and Google so I won't go into it, but you should definitely consider making this a parameterized query.
Like he said... your order by clause was out of order :)
SELECT TOP 1 as1.AssetTagID,
as1.TagID,
as1.CategoryID,
as1.Description,
as1.HomeLocationID,
as1.ParentAssetTagID
FROM Assets AS as1
INNER JOIN AssetsReads AS ar
ON as1.AssetTagID = ar.AssetTagID
WHERE ( ar.ReadPointLocationID = 'Readpoint1'
OR ar.ReadPointLocationID = 'Readpoint2' )
AND as1.TagID != '000000000000000000000000'
ORDER BY ar.DateScanned DESC;
I'll also note that using schema qualified objects is recommended by Microsoft (http://technet.microsoft.com/en-us/library/ms190387(v=sql.105).aspx). Also you should use parenthesis around your top (value) statement.
SELECT TOP (1) [as1].[AssetTagID],
[as1].[TagID],
[as1].[CategoryID],
[as1].[Description],
[as1].[HomeLocationID],
[as1].[ParentAssetTagID]
FROM [<schema>].[Assets] AS [as1]
INNER JOIN [<schema>].[AssetsReads] AS [ar]
ON [as1].AssetTagID = [ar].[AssetTagID]
WHERE ( [ar].[ReadPointLocationID] = 'Readpoint1'
OR [ar].[ReadPointLocationID] = 'Readpoint2' )
AND cast([as1].TagID AS [INT]) != 0
ORDER BY [ar].[DateScanned] DESC;
Related
This question already has answers here:
SQL multiple join statement
(3 answers)
Closed 4 years ago.
I'm trying to make an SQL query with an OleDbCommand into an Access database (.accdb).
While this command works fine (in a OleDbCommand.ExecuteReader()):
string command =
"SELECT cred.* " +
"FROM TB_CREDENTIALS cred " +
"INNER JOIN TB_REL_USERS_CREDENTIALS rel ON cred.CRED_ID = rel.REL_USR_CRED_CRED_ID ";
This other doesn't, and I can't understand why (all examples I see around use the exact same syntax):
string command =
"SELECT cred.* " +
"FROM TB_CREDENTIALS cred " +
"INNER JOIN TB_REL_USERS_CREDENTIALS rel ON cred.CRED_ID = rel.REL_USR_CRED_CRED_ID " +
"INNER JOIN TB_USERS usr ON usr.USR_ID = rel.REL_USR_CRED_USER_ID ";
The exception given is the following System.Data.OleDb.OleDbException:
Syntax error (missing operator) in query expression 'cred.CRED_ID = rel.REL_USR_CRED_CRED_ID INNER JOIN TB_USERS usr ON usr.USR_ID = rel.REL_USR_CRED_USER_I' (message is cut here)
Version and details:
The database is a .accdb file created on Access 2010
The connection is created in C# with System.Data.OleDb.OleDbConnection
The connection provider is "Microsoft.ACE.OLEDB.12.0"
(This seems like a useless query, but of course I'll add a WHERE usr.SOME_FIELD = some_condition)
"For multi-table joins, you have to nest the extra joins in brackets:"
SQL multiple join statement
I have a problem with SQL query in C#.
In my database I have tables: Supplier, ApplicationForm, SupplierAdress. I was trying to join these three tables but I got an syntax error with the inner join.
Also my method in C# have input parameter AppFormID. With that parameter I have to open particular Application Form from database on Windows app.
This is my SQL query:
command.CommandText = "select ApplicationForm.Date,ApplicationForm.About,ApplicationForm.Supplier," +
" Supplier.IDSupplier,Supplier.Name,Supplier.Email,Supplier.Phone," +
" Supplier.SupplierAdress,SupplierAdress.AdressID,SupplierAdress.Name" +
" from ApplicationForm" +
" inner join Supplier on ApplicationForm.Supplier=Supplier.IDSupplier" +
" inner join SupplierAdress on ApplicationForm.Supplier.SupplierAdress = SupplierAdress .AdressID" +
" where ApplicationForm.ApplicatonFormID=" + AppFormID;
I hope that someone will help me.
This is wrong ApplicationForm.Supplier.SupplierAdress
try this, dunno exact field names:
from
ApplicationForm
inner join Supplier on ApplicationForm.Supplier=Supplier.IDSupplier
inner join SupplierAdress on Supplier.IdAdress =SupplierAdress.AdressID
I have three tables, one holds a list of available products with relevant details such as product price, the other holds orders and the last holds specific order details including the items purchased in an order.
I am trying to create a query to calculate the total price of an order by linking the two of the tables with an inner join and then updating the order table with the value. The code I have written contains syntax errors, being a novice I have probably made an obvious mistake but any help would be appreciated.
"SELECT Sum(ProductTable.prodPrice) AS Total, OrderDetailTable.orderID " +
"FROM ProductTable INNER JOIN OrderDetailTable " +
"ON ProductTable.prodID = OrderDetailTable.prodID " +
"GROUP BY OrderDetailTable.orderID " +
"HAVING OrderDetailTable.orderID = ? " +
"UPDATE OrderTable " +
"SET " +
"totalPrice = Total " +
"WHERE OrderTable.orderID = ? ";
I am using Access.
I also forgot to mention that the ? is represented using a Dataview parameter
pc.Add(new Parameter("?", TypeCode.Int32, basketId.ToString()));
EDIT: Using PaqoGomez's suggestion to declare Total as a value I now get the error : Syntax error (missing operator) in query expression '0WHERE OrderTable.orderID = ?'.
Comment made before OP described this as MS Access:
Haven't tried this but you had the Select and update the wrong way round. This should be quite close. Its been a while for me but you may need to change the FROM clause to reference the table you are updating and INNER JOIN the sub-select instead of the WHERE clause.
"UPDATE OrderTable " +
"SET totalPrice = Sum(ProductTable.prodPrice)" +
"FROM (" +
"SELECT OrderDetailTable.orderID, Sum(ProductTable.prodPrice)" +
"FROM ProductTable INNER JOIN OrderDetailTable " +
"ON ProductTable.prodID = OrderDetailTable.prodID " +
"GROUP BY OrderDetailTable.orderID " +
") x" +
"WHERE x.orderID = OrderTable.OrderId"
UPDATE :
Based on OPs update regarding MS Access you can do an update with a sub-query, but I think it depends on the version of MS Access you are using and how you do it. Posts below seem to indicate it's quite problematic:
SQL Subqueries (Microsoft Access SQL)
How do I perform update query with subquery in Access?
Can It Be Done - Access 2007 SQL Update Query Using a Subquery?
By declaring a variable you can save the total value so that you can use it in the later update.
declare #Total int;
SELECT #Total = Sum(ProductTable.prodPrice)
//...
"SET " +
"totalPrice = #Total "
You dont mention which database platform you are using, I'm assuming MSSQL, other platforms would require a slightly different syntax.
You might also be interested to know that if you use the # symbol you can have a multiline string. This would allow you to avoid the concatenation that you are doing. eg.
var sql = #"some
sql
string"
So I'm retrieving data from the database using odbc. One of my fields, which was causing the problem, is AutoNumber. In my query when I use, '" convert.toint64(empid)"', I get an error of data type missmatch. But when I used parameter, it worked perfectly. Can someone tell me what is the difference. As far as I know, AutoNumber is a long integer and long int is 64, right?
here are both of my queries:
string cmdText = "SELECT p.projID, p.projName, a.wageperday " +
"FROM ((projects p INNER JOIN assigns a ON p.projID = a.projname) " +
"INNER JOIN empos e ON a.employeeID= e.ID) " +
"WHERE a.employeeID = ?";
OdbcCommand assignslist = new OdbcCommand(cmdText, _connection);
assignslist.Parameters.AddWithValue("#empID", empid);
OdbcDataReader readassigns = assignslist.ExecuteReader();
GridView1.DataSource = readassigns;
GridView1.DataBind();
(this one works fine)
string cmdText = "SELECT p.projID, p.projName, a.wageperday " +
"FROM ((projects p INNER JOIN assigns a ON p.projID = a.projname) " +
"INNER JOIN empos e ON a.employeeID= e.ID) " +
"WHERE a.employeeID = '" + convert.toint64( empid ) + "';
OdbcCommand assignslist = new OdbcCommand(cmdText, _connection);
OdbcDataReader readassigns = assignslist.ExecuteReader();
GridView1.DataSource = readassigns;
GridView1.DataBind();
for this one, i get an error even if I removed the conversion, I get an error.
One more question, I don't understand INNER JOIN perfectly and the above code was from a user here who helped me. I don't understand why did he use "FROM ((projects p INNER JOIN assigns a ON p.projID = a.projname) " +
"INNER JOIN empos e ON a.employeeID= e.ID)"
two brackets -- I mean a bracket inside a bracket. And if I wanna join a 4th or 5th table do I have to put it inside a bracket aside from the main bracket? An example would be much appreciated!
If a.employeeID is a number then your problem are the quotes and the concatenation of a number to a string.
"WHERE a.employeeID = " + convert.toint64(empid).ToString()
but this make no sense because you have a string to build so, you could simply write
"WHERE a.employeeID = " + empid.ToString();
however use always the parameterized query. That is the correct way to go.
A parameterized query allows the Framework code to pass the parameters with the correct format and you don't have to worry about quoting values, format of dates and decimal separators. (And last but not least, you avoid any possibilities of Sql Injection)
For the second part of your question, JOIN is used to put togheter data from two tables, when you have more than one JOIN the parenthesys help to understand how the grouping from the tables are perfomed. First the data from projects and assigns are grouped together following the rules of the INNER JOIN then the resulting set of data is joined with the data from the employee table following the rules of the second join.
In your second query, instead of using convert.toint64( empid ) try using empid.ToString():
"WHERE a.employeeID = " + empid.ToString();
The error you were receiving was due to the fact that you were trying to concatenate a string with an integer.
With regards to the INNER JOINs you are using, the use of the brackets is dependant upon the database you are using. In most cases, you will not need the brackets at all and they can be removed without any issue, so you could rewrite the query to:
string cmdText = "SELECT p.projID, p.projName, a.wageperday " +
"FROM projects p " +
"INNER JOIN assigns a ON p.projID = a.projname " +
"INNER JOIN empos e ON a.employeeID = e.ID " +
"WHERE a.employeeID = " empid.ToString();
You're trying to add a string and an integer, which isn't allowed automatically. You'd have to convert the number to a string first, like this:
"WHERE a.employeeID = '" + empid.ToString() + "';
But, using parameters is the better way for other reasons (best habit to be in, to avoid SQL-injection attacks, etc.).
So i learned how to do a bulk insert using data from one table as the userId from another table. Now i tried to do the same thing but i have a SQL(ite) error. I took a guess at the syntax and i got it wrong. After i bulk insert into the subscription i want to add 1 to each of the users media count. I have a left join error. How do i correct it?
-edit- I haven't solve this yet. Please help.
NOTE: I am using sqlite ATM but I am switching to mysql or MS sql
void updateMediaForSubscribers(long userId, long mediaId, Media_Base.Catagory cat, DateTime currentDate)
{
command.CommandText =
"INSERT INTO user_media_subscription (recipientId, mediaId, catagory) " +
"SELECT watcher, #mediaId, #category " +
"FROM user_watch WHERE watched=#watched;";
command.Parameters.Add("#mediaId", DbType.Int64).Value = mediaId;
command.Parameters.Add("#category", DbType.Int64).Value = cat;
command.Parameters.Add("#watched", DbType.Int64).Value = userId;
command.ExecuteNonQuery();
//near "LEFT": syntax error
command.CommandText =
"UPDATE user_data SET mediaMsgCount=mediaMsgCount+1 " +
"LEFT JOIN user_watch AS w ON w.watcher=user_data.userId " +
"WHERE w.watched=#watched;";
command.Parameters.Add("#watched", DbType.Int64).Value = userId;
command.ExecuteNonQuery();
}
UPDATE user_data
SET mediaMsgCount=mediaMsgCount+1
LEFT JOIN user_watch AS w ON w.watcher=user_data.userId
WHERE w.watched=#watched
Looks like it won't work to me, because you're joining in an UPDATE query but without a "FROM" clause, have you tried:
UPDATE u
SET u.mediaMsgCount = u.mediaMsgCount+1
FROM user_data u
LEFT JOIN user_watch AS w ON w.watcher=u.userId
WHERE w.watched=#watched
UPDATE user_data
SET mediaMsgCount = u.mediaMsgCount + 1
FROM user_data u LEFT OUTER JOIN user_watch w ON w.watcher = u.userId
WHERE w.watched=#watched
Honestly, I'm not really sure why you're using a left outer join since the update is dependant on user_watch... might want to change the "LEFT OUTER JOIN" to an "INNER JOIN".
Also, its a good idea to prefix your table name with the owner, I.E. dbo.user_data ... if you dont do that then sql server has to do a lookup.