Bit of a newbie to vbscript, not particularly fond of it but my client uses it so I can't do much about it! I'm having trouble using parameterized queries to add data into the database! Please save me guys!!
So far, the existing code is
function ecaddupdateDEV (thistable, idvar, vararray)
for each varname in vararray
valstring = valstring & ", session(""" & varname & """)"
thesefields = thesefields & ", " & varname
next
thesefields = idvar & thesefields
valstring = " array( " & ecremovel(valstring, 2) & ")"
vals = eval(valstring)
set temprs = Server.CreateObject("ADODB.RecordSet")
if session(idvar) = 0 then
'response.Write("chid is 0 add new record")
' ADD THIS REC
temprs.open thistable, db,1,3,2
temprs.AddNew vararray, vals
ecaddupdateDEV = temprs(idvar)
temprs.close
set temprs = ecquery("select " & idvar & " from " & thistable & " order by " & idvar & " desc ")
ecaddupdateDEV = temprs(idvar)
else
' UPDATE THIS REC
selectclause = "select " & thesefields & " from " & thistable & " where " & idvar & " = " & session(idvar)
temprs.open selectclause, db ,1,3
temprs.update vararray, vals
ecaddupdateDEV = temprs(idvar)
temprs.close
end if
set temprs = nothing
end function
The temprs variable I want to make parameterized for security purposes, obviously lol! I just have no clue how to do it! What I've read I just found confusing, please help!! Many thanks in advance!
Instead of a Recordset, use a Command. Here's the example, that will get you going, but you may have to tweak it, as from experience, named parameters don't really work, so you assign their value in the order in which they appear in the SQL statement.
How To Call a Parameterized Query to an Access Database with ADO
Related
I'm currently trying to use a db (.accdb-file) in my vbscript.
my function from a .vbs-file that's executed by a hta-file:
function dbCall(sAction, sPayload, sTable, sConCol, sConVal)
updateLocalDB()
Dim sConnectionString, objConnection, objRecordset, dbQuery, lTemp
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")
sConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & localDB
'Query für die DB zusammenbauen
Select Case sAction
Case "get"
If sConCol = False Then
dbQuery = "SELECT " & sPayload & " FROM " & sTable
Else
dbQuery = "SELECT " & sPayload & " FROM " & sTable & " WHERE " & sConCol & " = '" & sConVal & "'"
End If
End Select
'do DB-Stuff
objConnection.open sConnectionString
objRecordset.Open dbQuery, objConnection
IF objRecordset.fields.Count = 1 Then
lTemp = objRecordset.fields(0)
End If
objRecordset.close
objConnection.close
dbCall = lTemp
End function
the results are used to decide some things for the design of my hta-file.
I have multiple uses for it.
calling it like this:
getSlotAmount = dbCall("get", "value", "config", "name", "MiPaCount")
returns a number according to
name (short String)
value (Integer)
MiPaCount
5
but if I call it with
iStart = dbCall("get", "startzeit", "slots", "ID", tmp)
I get the error from the top.
The table currently looks like
ID (Integer, Byte)
Startzeit (short String)
1
11:30
previously the "startzeit"-column was a time-type but since I'm only storing and not calculating Data in the DB it's not that important
I tried to use an integer and a string as tmp but in all these cases it gives me an error on the line where I try to objRecordset.open (german: "Datentypenkonflikt in Kriterienausdruck", translating it by google resulted in the title).
While creating this question SO offered me multiple similar posts that lead me to two more experiments.
When I tried to change the string "dbQuery = ..." like this:
dbQuery = "SELECT " & sPayload & " FROM " & sTable & " WHERE " & sConCol & " = '" & sConVal
it said that a required value is missing.
When I tried this:
dbQuery = "SELECT " & sPayload & " FROM " & sTable & " WHERE " & sConCol & " = """ & sConVal & """"
I again got the error from the title so I returned to my original string (since it works fine with my first example of using dbCall).
What am I missing?
EDIT:
Found a solution based on the accepted answer. with this function it works:
function dbCall(sAction, sPayload, sTable, conCol, conVal, conType)
updateLocalDB()
Dim sConnectionString, objConnection, objRecordset, dbQuery, lTemp
Set objConnection = CreateObject("ADODB.Connection")
Set objRecordset = CreateObject("ADODB.Recordset")
sConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & localDB
'Query für die DB zusammenbauen
Select Case sAction
Case "get"
dbQuery = "SELECT " & sPayload & " FROM " & sTable
End Select
Select Case conType
Case "str"
dbQuery = dbQuery & " WHERE " & ConCol & " = '" & ConVal & "'"
Case "int"
dbQuery = dbQuery & " WHERE " & ConCol & " = " & ConVal
End Select
'do DB-Stuff
objConnection.open sConnectionString
objRecordset.Open dbQuery, objConnection
IF objRecordset.fields.Count = 1 Then
lTemp = objRecordset.fields(0)
End If
objRecordset.close
objConnection.close
dbCall = lTemp
End function
You are missing that you wish to handle several data types, and to take care of reserved words for field names. So, for example, you would need:
' For text:
dbQuery = "SELECT " & sPayload & " FROM " & sTable & " WHERE [" & sConCol & "] = '" & sConVal & "'"
' For numbers:
dbQuery = "SELECT " & sPayload & " FROM " & sTable & " WHERE [" & sConCol & "] = " & Str(sConVal) & ""
' For dates:
dbQuery = "SELECT " & sPayload & " FROM " & sTable & " WHERE [" & sConCol & "] = #" & Format(DateValue(sConVal), "yyyy\/mm\/dd") & "#"
You may be able to simplify this by using my function CSql, but I haven't tested it in a scenario like this.
Try replacing this line:
iStart = dbCall("get", "startzeit", "slots", "ID", tmp)
with this:
iStart = dbCall("get", "startzeit", "slots", "ID", "tmp")
You're looking for a value in that parameter and tmp (without quotations) is expected to be a numerical one.
I'm trying to update a table, via docmd.RunSql, and can't get it to update.
idlook = DLookup("[ID]", "119_review", "[todays_date] = #" & Format("" & Me.Combo87 & " " & Me.Combo89 & " 20" & Me.Combo91 & "", Medium) & "#")
MySQL = "UPDATE 119_review SET [Earned_Income]=" & Val(EarnedIncome) & " AND [Earned_income_withcal]=" & Val(EarnedIncomeCal) & " WHERE [ID]= " & idlook & ";"
Debug.Print MySQL
DoCmd.RunSQL MySQL
I've tried it both with and without brackets on the fields, the immediate window reads:
UPDATE 119_review SET Earned_Income=62 AND Earned_income_withcal=58.4 WHERE ID= 23;
UPDATE 119_review SET [Earned_Income]=62 AND [Earned_income_withcal]=58.4 WHERE [ID]= 23;
any idea where I'm going wrong?
You've made a simple syntax error.
Different columns in an update statement should be separated by ,, not by AND.
Weirdly enough, doing this wrong doesn't throw a syntax error, but just doesn't update anything.
Change the row setting your SQL string to the following:
MySQL = "UPDATE 119_review SET [Earned_Income]=" & Val(EarnedIncome) & " , [Earned_income_withcal]=" & Val(EarnedIncomeCal) & " WHERE [ID]= " & idlook & ";"
I trying to create Add,update,Delete operation on MS Access form.I found this code on internet where Insert and update is happening on the same button. I am not getting what is exactly happening in below line and how it's identifying it is for update or insert.
Not getting following line : = Me.txtid.Tag & "" = ""
Please find below code which works perfect as per requirement.
'When we click on button Add there are two options
'1. for insert
'2. for update
If Me.txtid.Tag & "" = "" Then
' this is for insert new
' add data in table
CurrentDb.Execute "insert into student(stdid,stdname,gender,phone,address)" & _
" values(" & Me.txtid & ",' " & Me.txtname & " ',' " & Me.cmbgender & " ','" & _
Me.txtphone & "', '" & Me.txtaddress & "')"
'refresh data in list on form
subform_student.Form.Requery
Else
CurrentDb.Execute "UPDATE student " & _
" set stdid = " & Me.txtid & _
", stdname = '" & Me.txtname & "' " & _
", gender = '" & Me.cmbgender & " ' " & _
", phone = ' " & Me.txtphone & " ' " & _
", address = ' " & Me.txtphone & " ' " & _
" WHERE stdid = " & Me.txtid.Tag
End If
The .Tag property is a general-purpose string property of every form and control object in VBA/VB6. It is provided as a place for developers to "put stuff" to support the operation of their applications.
The original code from which you copied your sample must have written a value to Me.txtid.Tag when the record was loaded (e.g., perhaps in the form's Current event) to indicate whether the record is an existing record or a new record (empty="new", non-empty="existing"). The line
If Me.txtid.Tag & "" = "" Then
simply checks to see if the .Tag property is empty, and then performs the INSERT or UPDATE accordingly.
BTW, re:
below code which works perfect as per requirement
No, it doesn't. Try adding a record where [stdname] is Tam O'Shanter and see for yourself. You should ditch the dynamic SQL and use one of
a bound form (as Gustav suggests),
a parameterized query, or
a recordset update.
Forget/remove all this code and bind the form to table Student to make this all happen automatically.
If a bound form is not familiar to you, browse for a tutorial for "Beginning with Microsoft Access" or the like.
I have this simple code of vba access to update product in the database. But when I debug, it stops at the DoCmd statement and got run-time error. I've made research about this kind of error and code, and had changed the code but still caused an error. Below is my simple code to update the product value.
Sub UpdateProduct()
Dim mySql As String
mySql = "UPDATE " & Forms!UPDATE_PRODUCT!cbxLensType _
& " SET LOT_NO = " & Forms!UPDATE_PRODUCT!txtLotNo _
& " WHERE EAN_CODE = " & Forms!UPDATE_PRODUCT!txtEan & ";"
DoCmd.RunSQL mySql
End Sub
Could you help me to explain what is the problem to my code? Is it because of the update syntax?
Thanks in advance.
**New to access vba
Since EAN_CODE is Text type you need to enclose it inside single quotes.
Sub UpdateProduct()
Dim mySql As String
mySql = "UPDATE [" & Forms!UPDATE_PRODUCT!cbxLensType _
& "] SET LOT_NO = " & Forms!UPDATE_PRODUCT!txtLotNo _
& " WHERE EAN_CODE = '" & Forms!UPDATE_PRODUCT!txtEan & "';"
DoCmd.RunSQL mySql
End Sub
If LOT_NO is also a Text type, make sure that it is also enclosed in Single quotes.
I have a data entry form (Access 2007) which is designed to find out if the captured animal already has an existing WHno. Unfortunately, the data is messy and these is not a single unique identifier so several tests must be performed to narrow the search.
The animal could have 1 to 10 different pieces of information which will help identify the animal’s existence in the database. (The script only tests for about half of them thus far) I was thinking the best way to do this would to be to “build” a DCount and/or SQL statement based on which fields the user selects. I hope test to see if a particular text field box (unbound) has been filled out, and if yes, concatenate that section of code to the DCount/SQL statement, then move on to the next text field box to test.
Once the statement has been completely built, I want to test to see how many records have been counted/selected. If one record has been selected, I want to display the results in FormA. If 2 or more records are found, I want to display the records in a multi-listing form (FormB) from which the user can select the correct animal based on additional information not tested but displayed in FormB. If zero records are found, I want to create a new record with the data entered into the form updated into the table.
The hurdle I am struggling with now is building the DCount statements. I keep getting syntax errors . I do not know how to put this together piecemeal when the function bombs out because the syntax is incomplete (which it will be until I finish “building” it.)
I know the data is a mess. The scene out in the field is chaotic, different people gather different kinds of information, and not all the data that should be entered on the paper forms get filled out completely - if at all. The data gathering procedures are unlikely to change anytime soon.
Ideas? A different but easier approach idea is also welcome. New to this and not sure of all my programming options.
Also, how long can this statement be before it bombs out?
Code so far:
Private Sub GenerateWHno_Click()
Dim rs As DAO.Recordset
If IsNull(Forms!F_HotelEntry!txtSpecies) Or (Forms!F_HotelEntry!txtSpecies) = "" Then
MsgBox "Species is a required field. Please enter a species"
Exit Sub
End If
MsgBox txtSpecies
' Each line of code below indicates a data entry field(s) that needs testing and appended to SpeciesCount if "true". The first line is unchanging and is declared upfront.
'SpeciesCount = DCount("[Species]", "AnimalInfo", "(nz([Status])= '' OR [Status] = 'Alive' OR [Status] = 'Unknown') AND ([Species]= '" & txtSpecies & "')" _
' & "AND (((nz([L_ET_Color1])= '" & Nz(txtL_ET_Color1) & "' AND nz([L_ET_No1])= '" & nz(txtL_ET_No1) & "')" _
' & "AND (((nz([R_ET_Color1])= '" & Nz(txtR_ET_Color1) & "' AND nz([R_ET_No1])= '" & nz(txtR_ET_No1) & "')" _
' & "AND nz([L_ET_No2])= '" & nz(txtL_ET_No2) & "')" _
' & "AND nz([R_ET_No2])= '" & nz(txtR_ET_No2) & "')" _
' & "")
'If txtL_ET_Color Is Not Null Or txtL_ET_No Is Not Null Then
'LET1 = & "AND (((nz([L_ET_Color1])= '" & Nz(txtL_ET_Color1) & "' AND nz([L_ET_No1])= '" & nz(txtL_ET_No1) & "')" _
'Species Count = SpeciesCount & LET1
'End If
'If txtR_ET_Color Is Not Null Or txtR_ET_No Is Not Null Then
'RET1 = & "AND (((nz([R_ET_Color1])= '" & Nz(txtR_ET_Color1) & "' AND nz([R_ET_No1])= '" & nz(txtR_ET_No1) & "')" _
'Species Count = SpeciesCount & RET1
'End If
'If txtL_ET_No2 Is Not Null Then
'LET2 = AND nz([L_ET_No2])= '" & nz(txtL_ET_No2) & "')" _
'Species Count = SpeciesCount & LET2
'End If
'If txtR_ET_No2 Is Not Null Then
'RET2 = AND nz([R_ET_No2])= '" & nz(txtR_ET_No2) & "')" _
'Species Count = SpeciesCount & RET2
'End If
'There are about 4 more options/fields to add to the script but you get the idea.
'Thus: If user selected Species, and filled out L_ET_Color1 and/or L_ET_No1, the final concatenation (DCount statement)would look like this:
SpeciesCount = DCount("[Species]", "AnimalInfo", "([Status]= 'Alive' OR [Status] = 'Unknown' OR nz([Status]) = '') AND [Species]= '" & txtSpecies & "' AND (nz([L_ET_Color1])= '" & Nz(txtL_ET_Color1) & "' AND nz([L_ET_No1])= '" & Nz(txtL_ET_No1) & "')")
If SpeciesCount > 1 Then
MsgBox SpeciesCount & " Greater than 1. Please select correct animal"
'Create SQL statement that mimics DCount statement and display all fields from AnimalInfo table as multilisting to select from
ElseIf SpeciesCount = 0 Then
MsgBox "You need a new WHno"
WHno = Nz(DMax("WHno", "AnimalInfo")) + 1
MsgBox WHno
Set rs = CurrentDb.OpenRecordset("AnimalInfo")
rs.AddNew
rs!WHno = WHno
rs!Species = txtSpecies
rs!L_ET_Color1 = txtL_ET_Color1
rs!L_ET_No1 = txtL_ET_No1
rs.Update
rs.Close
Else
'Create SQL statement that mimics DCount statement and display all fields from AnimalInfo table as single listing in a form.
MsgBox "You're WHno is " & WHno & " Is this the correct WHno?"
End If
Forms!F_HotelEntry!txtSpecies = ""
Forms!F_HotelEntry!txtL_ET_Color1 = ""
Forms!F_HotelEntry!txtL_ET_No1 = ""
End Sub
I would suggest to first compose the condition into a string variable. There you can print its content via Debug.Print and see what the problem might be.
If you cannot spot the problem via inspection alone, paste the generated string to the Sql view of a proper query and see if Access gives you helpful information on switching to design view.