Syntax Error in INSERT INTO Statement (Error 3134) - sql

I'm using MS Access 2013. My current issue is with the following code, I use to log user activity.
Table is called: tbl-activitylog and has five columns :
id
timestamps
Username
Activity
Additional
I checked code many times char after char and don't know what's wrong :(
TempVars("UserName").Value = "admin"
Logging("Logon", "system")
Public Sub Logging(Activity, Additional As String)
Dim sql_code As String
sql_code = "INSERT INTO tbl-activitylog(Username, Activity, Additional) VALUES('" & TempVars("UserName").Value & "','" & Activity & "','" & Additional & "')"
Debug.Print sql_code
CurrentDb.Execute sql_code
End Sub
Debug print shows:
INSERT INTO tbl-activitylog(Username, Activity, Additional) VALUES('admin','Logon','System')

Becaus of using "-" you have to do it in this way [tbl-activitylog]
sql_code = "INSERT INTO [tbl-activitylog](Username, Activity, Additional) VALUES('" & TempVars("UserName").Value & "','" & Activity & "','" & Additional & "')"

This 3134 error denotes a syntax error in your INSERT statement. As the name of your table contains a dash, you need to enclose it between brackets :
INSERT INTO [tbl-activitylog]
(Username, Activity, Additional)
VALUES('admin','Logon','System')
Generally speaking you may as well enclose all fields and table names, to avoid all risks of clashes with ms-access reserved words, like :
INSERT INTO [tbl-activitylog]
([Username], [Activity], [Additional])
VALUES('admin','Logon','System')

Consider a parameterized query, an industry best practice in any application layer language running SQL in any database. With QueryDefs, you can parameterize queries in MS Access.
Even more MS Access will not allow you to save queries with syntax issues. So, be sure to escape special characters and reserved words with square brackets or backticks.
SQL (save below as a query object)
PARAMETERS UsernameParam Text, ActivityParam Text, AdditionalParam Text;
INSERT INTO [tbl-activitylog] ([Username], [Activity], [Additional])
VALUES ([UsernameParam], [ActivityParam], [AdditionalParam])
VBA (reference above query and bind values without quotes or concatenation)
TempVars("UserName").Value = "admin"
Logging("Logon", "system")
Public Sub Logging(Activity, Additional As String)
Dim sql_code As String
Dim qdef As QueryDef
Set qdef = CurrentDb.QueryDefs("mySavedQuery")
' BIND PARAMS
qdef![UsernameParam] = TempVars("UserName")
qdef![ActivityParam] = Activity
qdef![AdditionalParam] = Additional
qdef.Execute dbFailOnError
Set qdef = Nothing
End Sub

Related

Avoiding SQL Injection in MS Access [duplicate]

This question already has answers here:
How do I use parameters in VBA in the different contexts in Microsoft Access?
(2 answers)
Closed 4 years ago.
I'm trying to better understand parameterized sql as a solution to SQL injection.
Lets say I have a tblCustomer with the fields CustName, Phone and Address. Lets also say I have an input form for new customers to enter their data, with controls called txtName, txtPhone and txtAddress.
I could run the following vba code:
dim strName, strPhone strAddress, strSQL as string
strName = me.txtName
strPhone = me.txtPhone
strAddress = me.txtAddress
strSQL = "INSERT INTO tblCustomer (CustName, Phone, Address) _
VALUES (" & strName & ", " & strPhone & ", " & strAddress & ");"
DoCmd.RunSQL strSQL
But then if someone nominated the address "Robert'); DROP TABLE tblCustomer; --" (wink) I'd have some serious problems.
I've used vba parameters, but they aren't helping me. So when people say use parameters to fix the issue, what do they mean?
Using a prepared statement with positional parameters eliminates the chance that someone may SQL inject you:
strSQL = "INSERT INTO tblCustomer (CustName, Phone, Address) " &
"VALUES ([str_name], [str_phone], [str_address]);"
Set qdf = db.CreateQueryDef(vbNullString, strSql)
With qdf
.Parameters("str_name").Value = strName
.Parameters("str_phone").Value = strPhone
.Parameters("str_address").Value = strAddress
.Execute dbFailOnError
End With
See here:
https://msdn.microsoft.com/en-us/library/office/ff845220.aspx
A longer winded explanation is that a parameterized query allows you to use a variable within your SQL query, and that variable will be properly escaped if it's a string or matched to your data type (for type checking), and prevent the problem that you've listed.

MS Access query assistance INSERT

This query keeps telling me I'm missing a semicolon at end of SQL statement, but when I add it, it tells me that there's a character found at the end of the SQL statement, what is wrong here? I'm used to working with SQL Server so this is just plain confusing to me. I'm not sure why Access needs to use a ";" to close the query. I'm just not sure where to include it.
strSQL = "Insert Into [tempCaseMgmt]Values([planID],[EdId],[OrID],[TheDate], [TypeID],[UserID],[TimeStart],[TimeEnd],[Unitsled],[Unitsid],[ClientID], [GenderID])" _
& " Select * from [dbo_tempDetail] where [userid]= " & [Forms]![frmx]! [txtClientID] & ";"
I'm just trying to make this work. The values I'm selecting and inserting are identical.
As suggested by #Martin in one of the comments to his answer, you are mixing up the two forms of INSERT INTO, specifically,
INSERT INTO ... VALUES ...
and
INSERT INTO ... SELECT ...
In my own simplified example this fails with "Run-time error '3137': Missing semicolon (;) at end of SQL statement."
Dim strSQL As String
strSQL = "Insert Into [tempCaseMgmt]Values([planID],[UserID])" _
& " Select * from [dbo_tempDetail] where [userid]=1" & ";"
Dim cdb As DAO.Database
Set cdb = CurrentDb
cdb.Execute strSQL, dbFailOnError
whereas this works
Dim strSQL As String
strSQL = "Insert Into [tempCaseMgmt] ([planID],[UserID])" _
& " Select * from [dbo_tempDetail] where [userid]=1" & ";"
Dim cdb As DAO.Database
Set cdb = CurrentDb
cdb.Execute strSQL, dbFailOnError
Note that the Values keyword has been omitted.
Without looking too deep into it, I would say, you are missing a white space directly in front of your select Statement.
Update:
You missed a second white space in front of the "Values" keyword. Did you copy pasted this query, or did you just wrote it in?
I would say, that you try to use a mixed up statement syntax for the Insert Into Statement. Values is used for single record appending. That means you should have an semicolon after the closing parenthesis. For the interpreter the Select is a completely new Statement. I goes that is not what you want.
Use the multi record syntax for insert into:
"Insert Into [tempCaseMgmt] \n
Select * from [dbo_tempDetail] where [userid]= " & [Forms]![frmx]![txtClientID] & ";"
In this case column naming should be identically
best regards
Martin

SQL statement in VBA

I am trying to run the following SQL statement in ACCESS 2013 VBA but am getting errors due to wrong formatting (in this case I get "Semicolon (;) missing from end of statement"). Could anybody tell me what I am doing wrong in the code below please?
Dim dbs As dao.Database
Set dbs = CurrentDb()
dbs.Execute "INSERT INTO TEMP2 ([Study_Date], [Created_By], [Part_Number],
[Upper_Tolerance], [Lower_Tolerance], [ID21_Number]) VALUES ([Study_Date],
[Created_By], [Part_Number], [Upper_Tolerance], [Lower_Tolerance], [ID21_Number])
FROM RAC_DATA_ENTRY
WHERE [RAC_CAP_VALS] = '" & Me.[RAC_CAP_VALS] & "'"
Don't use VALUES when you're pulling data from one table to INSERT into another. Use SELECT instead.
This example uses just two of your fields. Add in the others you need.
Dim strInsert As String
strInsert = "INSERT INTO TEMP2 ([Study_Date], [Created_By])" & _
" SELECT [Study_Date], [Created_By] FROM RAC_DATA_ENTRY" & _
" WHERE [RAC_CAP_VALS] = '" & Me.[RAC_CAP_VALS].Value & "';"
Debug.Print strInsert '<- view this in Immediate window; Ctrl+g will take you there
dbs.Execute strInsert, dbFailOnError
Notes:
A semicolon at the end of the statement is optional. Access will consider the statement valid with or without it.
Value is not actually required following Me.[RAC_CAP_VALS], since it's the default property. I prefer to make it explicit.
dbFailOnError gives you better information about failed inserts. Without it, a problem such as a primary key violation would fail silently.
Debug.Print strInsert allows you to inspect the statement you built and are asking the db engine to execute. If there is a problem, you can copy the statement text from the Immediate window and paste it into SQL View of a new Access query for testing.

Error "Too few parameters." when attempting to insert values into a database table using VBA in MS access

I've started to use access recently. I am trying to insert a few rows into the database; however, I am stuck as it is throwing an error:
Too few parameters.
I have a table test with only one column in it named start_date I want to insert all the dates between two dates for example if I consider 1/7/2014 to 3/7/2014 I need dates as 1/7/2014,2/7/2014,3/7/2014 in my table, but I have problem inserting the code I used is as follows
Private Sub createRec_Click()
Dim StrSQL As String
Dim InDate As Date
Dim DatDiff As Integer
Dim db As database
InDate=Me.FromDateTxt
'here I have used a code to find out the difference between two dates that i've not written
For i = 1 To DatDiff
StrSQL = "INSERT INTO Test (Start_Date) VALUES ('" & InDate & "' );"
StrSQL = StrSQL & "SELECT 'Test'"
db.Execute StrSQL
db.close
i=i+1
next i
End Sub
My code throws an error in the line Db.Execuite StrSQL
as too few parameters.
since you mentioned you are quite new to access, i had to invite you to first remove the errors in the code (the incomplete for loop and the SQL statement). Otherwise, you surely need the for loop to insert dates in a certain range.
Now, please use the code below to insert the date values into your table. I have tested the code and it works. You can try it too. After that, add your for loop to suit your scenario
Dim StrSQL As String
Dim InDate As Date
Dim DatDiff As Integer
InDate = Me.FromDateTxt
StrSQL = "INSERT INTO Test (Start_Date) VALUES ('" & InDate & "' );"
DoCmd.SetWarnings False
DoCmd.RunSQL StrSQL
DoCmd.SetWarnings True
You can't run two SQL statements into one like you are doing.
You can't "execute" a select query.
db is an object and you haven't set it to anything: (e.g. set db = currentdb)
In VBA integer types can hold up to max of 32767 - I would be tempted to use Long.
You might want to be a bit more specific about the date you are inserting:
INSERT INTO Test (Start_Date) VALUES ('#" & format(InDate, "mm/dd/yyyy") & "#' );"
Remove this line of code: For i = 1 To DatDiff. A For loop must have the word NEXT
Also, remove this line of code: StrSQL = StrSQL & "SELECT 'Test'" because its making Access look at your final SQL statement like this:
INSERT INTO Test (Start_Date) VALUES ('" & InDate & "' );SELECT 'Test'
Notice the semicolon in the middle of the SQL statement (should always be at the end. its by the way not required. you can also omit it). also, there is no space between the semicolon and the key word SELECT
in summary:
remove those two lines of code above and your insert statement will work fine. You can the modify the code it later to suit your specific needs. And by the way, some times, you have to enclose dates in pounds signs like #

Trying to use VB to automate some queries. Running into what looks like a string issue

I'm using MS Access 2003 and I'm trying to execute a few queries at once using VB. When I write out the query in SQL it works fine, but when I try to do it in VB it asks me to "Enter Parameter Value" for DEPA, then DND (which are the first few letters of a two strings I have). Here's the code:
Option Compare Database
Public Sub RemoveDupelicateDepartments()
Dim oldID As String
Dim newID As String
Dim sqlStatement As String
oldID = "DND-01"
newID = "DEPA-04"
sqlStatement = "UPDATE [Clean student table] SET [HomeDepartment]=" & newID & " WHERE [HomeDepartment]=" & oldID & ";"
DoCmd.RunSQL sqlStatement & ""
End Sub
It looks to me as though it's taking in the string up to the - then nothing else. I dunno, that's why I'm asking lol. What should my code look like?
Use (') character to set start and end of value
sqlStatement = "UPDATE [Clean student
table] SET [HomeDepartment]='" & newID
& "' WHERE [HomeDepartment]='" & oldID
& "';"
You probably want to insert quotes around the IDs.