incorrect syntax error near , - sql

I have recently changed my database from access to a .mdf and now I am having problems getting my code to work.
One of the problems im having is this error "incorrect syntax near ,".
I have tried different ways to try fix this for example putting brackets in, moving the comma, putting spaces in, taking spaces out but I just cant get it.
I would be so grateful if anyone could help me.
My code is:
SqlStr = "INSERT INTO UserTimeStamp ('username', 'id') SELECT ('username', 'id') FROM Staff WHERE password = '" & passwordTB.Text & "'"

Assuming you're looking for username and id columns, then that's not proper SQL syntax.
The main issues are that you're column names are enclosed in single quotes and in parentheses in your select. Try changing it to this:
SqlStr = "INSERT INTO UserTimeStamp (username, id) SELECT username, id FROM Staff WHERE password = '" & passwordTB.Text & "'"
That will get sent off to SQL like this:
INSERT INTO UserTimeStamp (username, id)
SELECT username, id
FROM Staff
WHERE password = 'some password'

There are a number of issues I potentially see.
Column names shouldn't be quoted, i.e. INTO UserTimeStamp('username','id') should be INTO UserTimeStamp(username, id)
Column fields, unless literal strings, shouldn't be quoted either. i.e. SELECT ('username','id') should be SELECT username, id.
You are putting yourself at risk for T-SQL injection by quoting your parameter like that. You should consider using a stored procedure, or use a well tested function to secure your parameters if you are doing ad-hoc queries.
SqlStr = "INSERT INTO UserTimeStamp (username, id) SELECT username, id FROM Staff WHERE password = " + MyQuoteFunction(passwordDB.Text);

Try wrapping column names in square brackets like so:
INSERT INTO employee ([FirstName],[LastName]) SELECT [FirstName],[LastName] FROM Employee where [id] = 1
Edit: Also drop the parentheses surrounding the selected fields.

Related

Is it possible to do an INSERT INTO SELECT statement using data from more than 1 table?

Question as above. The SQL code I am currently using is as follows:
"INSERT INTO [tblClasses/Students] (StudentID, ClassID) " & _
"SELECT StudentID FROM tblStudent WHERE Username = #StudentUser " & _
"SELECT ClassID FROM tblClasses WHERE ClassName = #ClassName ;"
When I try to run this query, I receive the following error message:
'Number of query values and destination fields are not the same'
Clearly, the method I am using does not work, so does anyone know the correct way of writing the query?
You need a single SELECT .. FROM .. statement as source. Normally you'd use a JOIN, but if the tables aren't related, use a cartesian product.
INSERT INTO [tblClasses/Students] (StudentID, ClassID)
SELECT tblStudent.StudentID, tblClasses.ClassID
FROM tblStudent, tblClasses
WHERE tblStudent.Username = #StudentUser
AND tblClasses.ClassName = #ClassName
Not sure if this will create duplicate records. If necessary, use SELECT DISTINCT.
How to use SQL parameters in VB.Net
To test the query in Access, use [StudentUser] and [ClassName] for the parameters and supply the values when asked for them.
For some reason, Access trips over [ClassName] unless explicitly specified as parameter. Use this:
PARAMETERS StudentUser Text ( 255 ), ClassName Text ( 255 );
INSERT INTO [tblClasses/Students] ( StudentID, ClassID )
SELECT tblStudent.StudentID, tblClasses.ClassID
FROM tblStudent, tblClasses
WHERE tblStudent.Username = [StudentUser]
AND tblClasses.ClassName = [ClassName];

SQL Injection Method

The Injection Procedures are :
SELECT UserId, Name, Password FROM Users WHERE UserId = 105 or 1=1;
But, My Question Is how the injection query is working in the sql?
its when you have your query as string in your code, something like this
Query = "SELECT UserId, Name, Password FROM Users WHERE UserId = '" + sUserID + "'"
So you pass sUserID = "ABC' OR 1=1;"
this will be translated like
SELECT UserId, Name, Password FROM Users WHERE UserId = 'ABC' OR 1=1
Since the condition 1=1 is always true, adding it at the end of a WHERE statement renders it irrelevant, and always true, as if the WHERE statement does not exist at all. Thus, the query is always executed, regardless of any other conditions added to the WHERE statement.
In the example you provided, If you allow your users to write down their own userID, they can write 105 or 1=1 in the input fields or in a website's URL address, and since or 1=1 makes UserId=105 useless, and the query will always select the data, hence the SQL injection.

How does union select statement output vulnerable columns

Consider a SQL vulnerable site.
Let the number of columns in the query be 3.
So the statement goes, www.test.com?php.id=-1' union select 1,2,3 --+-
My understanding of this statement is like this.
There are 2 statements
Union is used to join both statements.
(-) is used to null the value of the first statement.
' is used to break the query and input a second statement and --+- is used to comment out the rest of the statement.
Upon inputting this statement, The website displays 2 and 3 as vulnerable columns.
What I don't get is that how a select statement displays the vulnerable columns.
Suppose your back-end code did something like:
sql = "SELECT UserId, UserName, Password from Users where UserID = " + id + " AND password = '" + password + "'"
So it would only return results if the User ID and password matched.
Then "injecting" the code above would result in a SQL statement of
SELECT UserId, UserName, Password from Users
where UserID = -1 union select 1,2,3 --+- AND password = 'anything'
Presumably the UI might then display 1 and 2 in the "username" and "password" fields, identifying them as "vulnerable"
It's a technique used to determine how SQL statements are built in back-end code in order to define a true SQL injection attack to retrieve sensitive data.

String concatenation not working as expected in SELECT statement

I'm using MS Access to work with an SQL Server database through an ODBC connection on Windows 7.
The ultimate goal is to append a string literal to one of the fields for a subset of rows. Initially, though, I'm just trying to do a SELECT so I can make sure I have everything correct. I'm having trouble trying to append a string literal to the field.
The below simple SQL works well.
SELECT Name FROM Customers WHERE CustomerType = 1;
Next step was to try and modify the displayed name slightly.
SELECT Name, 'PREFIX' & Name FROM Customers WHERE CustomerType = 1;
The above also worked. Then I tried the following.
SELECT Name, Name & 'SUFFIX' FROM Customers WHERE CustomerType = 1;
This does not work. The output shows just the Name field with nothing appended. I looked around and found SQL Server seems to support CONCATENATE('a' + 'b'). I tried using that in the query but it failed with an error from Access about there not being a CONCATENATE function.
I also tried double quotes instead and + instead of &.
Seems odd that the prefix case worked and the suffix case did not.
The eventual goal, again, would be to construct something like the below.
UPDATE Customers SET Name = Name & 'SUFFIX' WHERE CustomerType = 1;
This would append a suffx to a text field for a subset of rows in the table.
Any ideas?
In SQL Server, & is for binary masks. You want the + operator
UPDATE Customers
SET Name = Name + 'SUFFIX'
WHERE CustomerType = 1;
I don't know where you got CONCATENATE from - There is a CONCAT function in SQL 2012, but nothing like that in any other version
My impression is you have an Access query with Customers as an ODBC link to a SQL Server table. If that is correct, either of these 2 query versions should work.
SELECT
[Name],
[Name] & 'SUFFIX'
FROM Customers
WHERE CustomerType = 1;
SELECT
c.Name,
c.Name & 'SUFFIX'
FROM Customers AS c
WHERE c.CustomerType = 1;
The reason for this suggestion is that Name is a reserved word. One thing that makes reserved words frustrating is that you don't know when they will bite you. A reserved word might not cause trouble in one context but cause the same SQL statement to fail in another context. Enclosing the name in square brackets or qualifying the name with an alias (or the table name) avoids confusing Access' db engine.
Try this for your UPDATE.
UPDATE Customers
SET [Name] = [Name] & 'SUFFIX'
WHERE CustomerType = 1;

SQL to Query text in access with an apostrophe in it

I am trying to query a name (Daniel O'Neal) in column names tblStudents in an Access database, however Access reports a syntax error with the statement:
Select * from tblStudents where name like 'Daniel O'Neal'
due to the apostrophe in the name.
How do I overcome this?
You escape ' by doubling it, so:
Select * from tblStudents where name like 'Daniel O''Neal'
Note that if you're accepting "Daniel O'Neal" from user input, the broken quotation is a serious security issue. You should always sanitize the string or use parametrized queries.
When you include a string literal in a query, you can enclose the string in either single or double quotes; Access' database engine will accept either. So double quotes will avoid the problem with a string which contains a single quote.
SELECT * FROM tblStudents WHERE [name] Like "Daniel O'Neal";
If you want to keep the single quotes around your string, you can double up the single quote within it, as mentioned in other answers.
SELECT * FROM tblStudents WHERE [name] Like 'Daniel O''Neal';
Notice the square brackets surrounding name. I used the brackets to lessen the chance of confusing the database engine because name is a reserved word.
It's not clear why you're using the Like comparison in your query. Based on what you've shown, this should work instead.
SELECT * FROM tblStudents WHERE [name] = "Daniel O'Neal";
Escape the apostrophe in O'Neal by writing O''Neal (two apostrophes).
...better is declare the name as varible ,and ask before if thereis a apostrophe in the string:
e.g.:
DIM YourName string
YourName = "Daniel O'Neal"
If InStr(YourName, "'") Then
SELECT * FROM tblStudents WHERE [name] Like """ Your Name """ ;
else
SELECT * FROM tblStudents WHERE [name] Like '" Your Name "' ;
endif
How about more simply: Select * from tblStudents where [name] = replace(YourName,"'","''")
I was looking for how to find all records where there was an apostrophe in the column value. Using the double ' suggested by #Alex K, I came up with
SELECT * FROM [table] WHERE ([column] LIKE '%''%')
Adding it to this question for others who maybe looking for the same resolution.