SQL statement error in VBA - sql

I have an Access form which contains an insert statement.
The code works very good, but the problem when I enter a text that contains a single quote ':
strSQL = "INSERT INTO student (stname) VALUES ('" & stname.Value & "')"
DoCmd.RunSQL strSQL
when stname.value = Ra'ed or ka'l
then statement becomes wrong

Generally I would have to agree with marc_s regarding the SQL injection warning. However for a quick and dirty solution on a non-mission critical db that you don't mind other users potentially hacking into or otherwise messing with, you would use
strSQL = "INSERT INTO student (stname) VALUES ('" & Replace (stname.Value, "'", "''") & "')"

Consider a DAO parameterized query which allows binding values without quote enclosure. Access queries allows the PARAMETERS clause which can be binded with external values:
Dim db As Database
Dim qdef As QueryDef
Dim strSQL As String
Set db = CurrentDb
' PREPARE STATEMENT (STRING CAN BE A SAVED QUERY)
strSQL = "PARAMETERS [strValParam] Text(255);" _
& " INSERT INTO student (stname) VALUES ([strValParam]);"
' INITIALIZE QUERYDEF OBJECT (REPLACE EMPTY STRING "" FOR SAVED QUERY NAME AND NO STRSQL)
Set qdef = db.CreateQueryDef("", strSQL)
' BIND VALUE (SINGLE/DOUBLE/SPECIAL CHARS ALL ALLOWED)
qdef!strValParam = stname.Value
' EXECUTE ACTION QUERY
qdef.Execute
Set qdef = Nothing
Set db = Nothing

Related

SQL statement in ms access db bringing up InputBox

I have VBA for a form.
I'm trying to take the information in a textbox on the form and update a particular field in a table. (haven't figured out how to do that properly)
This line of code is my current try but I'm getting unexpected behavior
The program doesn't continue executing after this
If (Not IsNull([New_Value_Box].Value)) Then
DoCmd.RunSQL "Update [Export_NDC_Certification] Set " & [Field_List].Value & " = " & [New_Value_Box].Value & " WHERE SellerLoanIdentifier = " & Current_Loan
End If
it does however open an input box with the value of Current_Loan as the caption. It doesn't appear to do anything with the input and it doesn't execute any further code. I've used MsgBox's for debugging and its definitely coming from this line. This line was what I came across for taking a value and updating a particular table value with it. if this isn't the way to do it any push in the right direction would be appreciated. Thank you!
First, I would recommend using the Execute method (of either DAO.Database or DAO.QueryDef), instead of using DoCmd.RunSQL. This makes debugging a lot easier (here's a forum post with more information).
Also, since it seems that you need values in all your controls ([Field_List], [New_Value_Box], and Current_Loan), you should do a null check on all of those.
As noted by #HansUp, your actual SQL string is likely causing the issue, so you probably want to store that in a separate variable you can then output to the immediate window.
With all that being said, revised code might look something like this:
Dim db As DAO.Database, qdf As DAO.QueryDef
Dim strSQL As String
If _
IsNull([New_Value_Box].value) Or _
IsNull([Field_List].value) Or _
IsNull([Current_Loan].value) _
Then
' handle missing input
Else
' we know all required fields have values, so can proceed
strSQL = _
"UPDATE [Export_NDC_Certification " & _
"SET " & [Field_List].value & "=" & [New_Value_Box].value & " " & _
"WHERE SellerLoanIdentifier=" & Current_Loan
Debug.Print strSQL
Set db = CurrentDb
Set qdf = db.CreateQueryDef("")
qdf.SQL = strSQL
qdf.Execute dbFailOnError
End If
' clean up DAO objects
Set qdf = Nothing: Set qdf = Nothing: Set db = Nothing

MS ACCESS, VBA SQL Insert command semicolon issue

I am trying to sort out some VBA in Access today with very limited knowledge. I have constructed the code below for a simple insert into a table within the same access database.
I am getting the error
"Missing semicolon (;) at end of SQL statement."
However I have the semicolon in there. I can only assume I have made a rookie error with syntax somewhere but after spending far too long trying I am stumped, any pointers much appreciated!
Dim StrSQL As String
Dim InDate As Date
Dim VacNum As String
Dim Stage As String
InDate = Now()
VacNum = Me.Vacancy_No
Stage = Me.Current_Stage
StrSQL = "INSERT INTO Stage (Vacancy_ID,StageDate,Stage) VALUES ('" & VacNum & "','" & InDate & "','" & Stage & "' );"
DoCmd.SetWarnings False
DoCmd.RunSQL StrSQL
DoCmd.SetWarnings True
Your syntax is at risk for SQL injection, and that's probably why you're getting this message.
The likely cause of this error is that one of your field contains a single quote, making the SQL malfunction.
The proper solution to this is to parameterize:
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDb
Set qdf = db.CreateQueryDef("", "INSERT INTO Stage (Vacancy_ID,StageDate,Stage) VALUES (#Value1,#Value2,#Value3 );")
qdf.Parameters("#Value1") = VacNum
qdf.Parameters("#Value2") = InDate
qdf.Parameters("#Value3") = Stage
qdf.Execute

Getting identity auto-number from SQL in VBA

I've been messing with an Access unbound form with SQL back-end. I add a new record using VBA but want to retrieve the Identity value created. At first I simply tried "tbField0 = rs.fields(0).value" but after the rs.update is shows record is deleted. I tried adding rs.bookmark = rs.lastmodified but same result.
Found this article
Access: Get newly created auto number in DAO and a comment by Rick about BIGINT & Access which I knew about. I don't use BIGINT because of it but NUMERIC instead. So, since no suggestions would work I tried to change the field type to INT and test. Works as required.
Therefore my question is how can I retrieve an incremented identity field from SQL which is not a datatype if INT using VBA in Access. I saw some mention of an OUTPUT command but not sure how to use or if applicable.
I have created two tables, one called tbl1_Int and the other tbl2_Num. Both contain two fields IndexID and Field1. Both Field1 are nchar and as you might surmise IndexID is a Int in tbl1_Int and a Numeric in tbl2_Num.
Created a blank form with two unbound fields txtIndex and txtField1 as well as two buttons btnInt and btnNumeric with the following code.
Private Sub btnInt_Click()
Dim DB As Database
Dim RS As Recordset
Dim strSQL As String
strSQL = "INSERT INTO dbo_tbl1_Int (Field1) VALUES ('" & txtField1 & "')"
Set DB = CurrentDb
DB.Execute strSQL
txtIndex = DB.OpenRecordset("SELECT ##IDENTITY")(0)
DB.Close
End Sub
Private Sub btnNumeric_Click()
Dim DB As Database
Dim RS As Recordset
Dim strSQL As String
strSQL = "INSERT INTO dbo_tbl2_Num (Field1) VALUES ('" & txtField1 & "')"
Set DB = CurrentDb
DB.Execute strSQL
txtIndex = DB.OpenRecordset("SELECT ##IDENTITY")(0)
DB.Close
End Sub
The records get created in the tables however it will only capture (thus populate) the index from tbl1 which is when the identity is a field type of Int. Which leads back to my original question of how do I capture the index when it is not an Integer?
I've gotten it to work with the following.
Private Sub btnNumeric_Click()
Dim DB As Database
Dim RS As Recordset
Dim strSQL As String
strSQL = "select * from dbo_tbl2_Num where false"
Set DB = CurrentDb
Set RS = DB.OpenRecordset(strSQL, dbOpenDynaset, dbSeeChanges)
RS.AddNew
RS.Fields(1) = txtField1
RS.Update
RS.Move 0, RS.LastModified
txtIndex = Null
txtIndex = RS.Fields(0).Value
RS.Close
DB.Close
End Sub

VBA Append Query Using Access

I am attempting to add a button to a form to add the contents of the form as a new line in my table. I have written this line of code before, but this time it isn't working.
My form contains text and integers. 3 boxes on the form are auto-populated when the form loads. (Will the auto populated boxes change anything?)
Instead of trying to make the whole string work, I have reduced my code to just add one box (one of the auto-populated boxes). I get a Rune-time error '438': Object doesn't support this property or method.
I've tried googling the error, but I cannot find anything that applies.
The code is as follows:
Dim strInsert As String
strInsert = "INSERT INTO NLog(IDKEY) " & _
" Values(" & Me.TxtIdKey & ")"
Debug.Print strInsert
CurrentProject.Execute strInsert, dbFailOnError
MsgBox ("Entry Added")
When I look at the debug screen it shows the following:
INSERT INTO NLog(IDKEY) Values(OH08801405)
I am so frustrated! I am still very new to this, and I feel totally out of my element.
You could execute your INSERT statement with ADO like this ...
CurrentProject.Connection.Execute strInsert
Note CurrentProject.Connection.Execute, not CurrentProject.Execute, and don't include the DAO constant dbFailOnError when executing from ADO.
Or with DAO like this ...
CurrentDb.Execute strInsert, dbFailOnError
Also, you were attempting to insert a text value into the IDKEY field. Assuming text is the correct datatype for that field, add quotes around the value you're inserting ...
strInsert = "INSERT INTO NLog(IDKEY) " & _
" Values('" & Me.TxtIdKey & "')"
Then you should see Debug.Print output similar to this ...
INSERT INTO NLog(IDKEY) Values('OH08801405')
Without quotes surrounding OH08801405, the db engine will not understand it is supposed to be a string value it should insert, and instead will assume it is a parameter for which you haven't supplied a value.
I have to assume that the error message is happening at CurrentProject.Execute strInsert, dbFailOnError since your debug actually shows something.
You will need to set up a connection to your database and use db.Execute strInsert, dbFailOnError.
You declare a connection like this:
Dim db As DAO.Database
Set db = CurrentDb
So you should end up with something like:
Dim strInsert As String
Dim db As DAO.Database
strInsert = "INSERT INTO NLog(IDKEY) " & _
" Values(" & Me.TxtIdKey & ")"
Debug.Print strInsert
Set db = CurrentDb
db.Execute strInsert, dbFailOnError
MsgBox ("Entry Added")

Inserting into a different table from a form

I am trying to make an event when iputing data in a form on access, after the text box looses focus, if the box is not null I want the ID and the value to get stored into another table. After trying with the code below I get "Runtime error 3061 Too few parameters Expected 1". I have checked in debug mode and the values are getting carried over and brought to the string.
Private Sub Consolidate_LostFocus()
Dim queryString As String
queryString = "INSERT INTO [ReportMasterTable]([#], [Notes]) VALUES(" & [#].Value & ", " & [Consolidate].Value & ")"
If Consolidate.Text <> vbNullString Then
CurrentDb.Execute (queryString)
End If
End Sub
If either the # or the Notes fields in ReportMasterTable is text data type, you must add quotes around the values you attempt to INSERT.
For example, if both fields are text type:
queryString = "INSERT INTO [ReportMasterTable]([#], [Notes])" & vbCrLf & _
"VALUES ('" & [#].Value & "', '" & [Consolidate].Value & "')"
The situation will be more complicated if either [#].Value or [Consolidate].Value contains a single quote. You could double up the single quotes within the inserted values. However it might be easier to just switch to a parameterized query ... the quoting problem would go away.
Dim db As DAO.database
Dim qdf As DAO.QueryDef
Dim strInsert As String
strInsert = "PARAMETERS hash_sign Text (255), note_value Text (255);" & vbCrLf & _
"INSERT INTO [ReportMasterTable]([#], [Notes])" & vbCrLf & _
"VALUES (hash_sign, note_value)"
Set db = CurrentDb
Set qdf = db.CreateQueryDef("", strInsert)
qdf.Parameters("hash_sign").value = Me.[#]
qdf.Parameters("note_value").value = Me.[consolidate]
qdf.Execute dbFailOnError
Set qdf = Nothing
Set db = Nothing
You could also save the SQL statement as a named query and open and execute that instead of rebuilding the statement every time your procedure runs.
Is there any reason why you do not wish ti bind the form to the ReportMasterTable?
If you really have a control and field called #, you are facing a world of trouble.
If you have bound the form to ReportMasterTable and are also updating in a query, you are going to run into problems.
The lost focus event is a very bad event to choose, any time anyone tabs through the form, the code will run. After update would be better.
You are updating a text data type, but you have not used quotes.
"INSERT INTO [ReportMasterTable]([#], [Notes]) VALUES(" & [#].Value _
& ", '" & [Consolidate].Value & "')"