Data type conflict in criteria expression - ms-access

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.

Related

Identify a data entry without changing the ID

I am trying to create an update form. It is supposed to take values from the text boxes on the form and update that registry using the ID's autonumber as an identifier. It says I cannot edit the ID even though I don't think I am.
Private Sub edit_Click()
'Will edit the currently selected record
CurrentDb.Execute "UPDATE DataInput " & _
" SET ID=" & Me.txtID & _
", [Date]='" & Me.Date & "'" & _
", [Time Up]='" & Me.txttimeup & "'" & _
", [Notes]='" & Me.CboNotes & "'" & _
", [Time Down]='" & Me.txtTimeDown & "'" & _
" WHERE ID=" & Me.txtID.Tag
Me.txtID.Tag = ""
'refresh data on form
DataInput_subform.Form.Requery
'Disable Update Button
Me.edit.Enabled = False
'Enable Edit Button
Me.cmdEdit.Enabled = True
'Clear texts
cmdClear_Click
Try formatting your code in a more readable way and add a debug like
Dim sSql As String
sSql = "UPDATE DataInput SET [Date]=#" & Format(Me.Date,"mm/dd/yyyy") & "#, "
sSql = sSql & "[Time Up] = '" & Me.txttimeup & "', [Notes] ='" & Me.CboNotes & "', "
sSql = sSql & "[Time Down] = '" & Me.txtTimeDown & "' "
sSql = sSql & "WHERE ID = " & Me.txtID & " ;"
Debug.Print sSql
CurrentDb.Execute sSql

Looping through folder with SQL query

strQuery = _
"SELECT * FROM [Sheet1$A15:E999] " & _
"IN '" & ThisWorkbook.Path & "\Source1.xlsx' " & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;ExtendedProperties='HDR=YES;'] " & _
"UNION " & _
"SELECT * FROM [Sheet1$A15:E999] " & _
"IN '" & ThisWorkbook.Path & "\Source2.xlsx' " & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=YES;'] " & _
"UNION " & _
"SELECT * FROM [Sheet1$A15:E999] " & _
"IN '" & ThisWorkbook.Path & "\Source3.xlsx' " & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;Extended Properties='HDR=YES;'] " & _
"ORDER BY A;"
Good morning,
I have one last nail to go on this coding I have and any help is much appreciated. I am gathering numerous files from a single folder and file names are different (although data order and data are same).
Question is:
Is it possible to get all files via the 'strQuery' without slowing down the code? How do I go on to do this? (eg: I think maybe loop but it might slow down? - see below)
Is it possible to get (say) 100 excel file data read at once? (although I do not know names of it?)
I can modify strQuery (via assigning it a text string) and input a loop to go through every file but I recon this would require me to create a connection for every single file rather than all at once?
Any help is appreciated!
Thanks in advance.
--
Full Code below (I didn't know where to put this in a visible manner)
Sub SqlUnionTest()
Dim strConnection As String
Dim strQuery As String
Dim objConnection As Object
Dim objRecordSet As Object, qText As String
strConnection = _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"User ID=Admin;" & _
"Data Source='" & ThisWorkbook.FullName & "';" & _
"Mode=Read;" & _
"Extended Properties=""Excel 12.0 Macro;"";"
Dim sFile As String
sFile = Dir(ThisWorkbook.Path & "\*.xlsx")
Do While sFile <> ""
strQuery = _
"SELECT * FROM [Sheet1$A15:E999] " & _
"IN '" & ThisWorkbook.Path & "\" & sFile & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;ExtendedProperties='HDR=YES;'] " & _
"UNION "
sFile = Dir()
Loop
strQuery = Left(strQuery, Len(strQuery) - 7) 'to remove last UNION which is not necessary
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open strConnection
Set objRecordSet = objConnection.Execute(strQuery)
RecordSetToWorksheet Sheets(1), objRecordSet
objConnection.Close
End Sub
Sub RecordSetToWorksheet(objSheet As Worksheet, objRecordSet As Object)
Dim i As Long
With objSheet
.Cells.Delete
For i = 1 To objRecordSet.Fields.Count
.Cells(1, i).Value = objRecordSet.Fields(i - 1).Name
Next
.Cells(2, 1).CopyFromRecordset objRecordSet
.Cells.Columns.AutoFit
End With
End Sub
You can use the DIR() function to loop through all the .xlsx files in the folder without knowing the specific file names. If you need to weed out any files, you can place conditional testing inside the loop.
Code untested
Dim sFile As String, strQuery As String
sFile = Dir(ThisWorkbook.Path & "\*.xlsx")
Do While sFile <> ""
strQuery = strQuery & _
"SELECT * FROM [Sheet1$A15:E999] " & _
"IN '" & ThisWorkbook.Path & "\" & sFile & _
"[Excel 12.0;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Read;ExtendedProperties='HDR=YES;'] " & _
"UNION;"
sFile = Dir()
Loop
strQuery = Left(strQuery, Len(strQuery) - 7) 'to remove last UNION which is not necessary

You have error syntax VB.Net MySql

I want update mysql database table in vb.net, i try and i got problem with that. this is my source
MysqlConn = New MySqlConnection
MysqlConn.ConnectionString =
"server=db4free.net;port=3306;userid=***;password=***;database=***"
Dim Reader As MySqlDataReader
Try
MysqlConn.Open()
Dim Query As String
Query = "update member set (Name='" & Val(TextBox1.Text) + Val(TextBox6.Text) & "' WHERE Username='" & TextBox8.Text & "'"
Command = New MySqlCommand(Query, MysqlConn)
Reader = Command.ExecuteReader
MysqlConn.Close()
Catch ex As Exception
MsgBox(ex.Message)
Finally
MysqlConn.Dispose()
End Try
If i do this source, i got error code like this
TextBox1.Text = 10
TextBox6.Text = 20
TextBox8.Text = John
Here's what you have
"update member set (Name='" & Val(TextBox1.Text) + Val(TextBox6.Text) & "' WHERE Username='" & TextBox8.Text & "'"
render:
update member set (Name='30' WHERE Username='John'
-
What you probably want is to remove the bracket
"update member set Name='" & Val(TextBox1.Text) + Val(TextBox6.Text) & "' WHERE Username='" & TextBox8.Text & "'"
resulting in :
update member set Name='30' WHERE Username='John'
My suggestion to you as a preference for building these strings is to separate the parameters more often. It keeps things neat and easy.
ex:
dim x as string = (Val(TextBox1.Text) + Val(TextBox6.Text)).tostring
dim cmd as string =
"update member " &
"set Name=" & "'" & x & "' " &
"WHERE Username=" & "'" & TextBox8.Text & "'"

Inserting string variable into sql string in vb.net

I am having a hard time inserting WONum into my sql string.
I have tried using ' and double '' around WONum. Someone also suggested # and [] around it, but nothing is working thus far.
I keep getting the following error: Incorrect syntax near '1577'
WONum value is actually WO-1577 during run time, but when DA.fill is executed I get that error. I starting to think that the dash is doing something in sql that I'm not aware of. Any help would help, because I have to do several more similar functions in my application.
Public Function GetTechTimes(ByVal WONum As String)
Dim strSQL As String = "Select customer_name, workorder_work_to_be_performed, workorder_work_performed, workorder_notes, workorder_warranty_work, workorder_open_date, workorder_status,workorder_completion_date, wo_tech_name, wo_tech_time, wo_parts_description from Customers, workorders, WorkOrder_Technicians, WorkOrder_Parts Where(customer_id = workorder_customer And wo_tech_wo_id = workorder_id And wo_parts_wo_id = workorder_id And workorder_number = " & WONum & ""
Dim DA As New SqlDataAdapter(strSQL, Conn)
Dim DS As New DataSet
DA.Fill(DS, "TechTimes")
Return DS
End Function
Use Sql-Parameters! That will avoid conversion or other issues and - more important - prevents SQL-Injection attacks.
Public Function GetTechTimes(ByVal WONum As String) As DataSet
Dim strSQL As String = "SELECT customer_name, " & Environment.NewLine & _
"workorder_work_to_be_performed," & Environment.NewLine & _
"workorder_work_performed, " & Environment.NewLine & _
"workorder_notes, " & Environment.NewLine & _
"workorder_warranty_work, " & Environment.NewLine & _
"workorder_open_date, " & Environment.NewLine & _
"workorder_status, " & Environment.NewLine & _
"workorder_completion_date," & Environment.NewLine & _
"wo_tech_name, " & Environment.NewLine & _
"wo_tech_time, " & Environment.NewLine & _
"wo_parts_description" & Environment.NewLine & _
"FROM(customers," & Environment.NewLine & _
" workorders," & Environment.NewLine & _
" workorder_technicians," & Environment.NewLine & _
" workorder_parts)" & Environment.NewLine & _
"WHERE customer_id = workorder_customer " & Environment.NewLine & _
"AND wo_tech_wo_id = workorder_id " & Environment.NewLine & _
"AND wo_parts_wo_id = workorder_id " & Environment.NewLine & _
"AND workorder_number = #workorder_number "
Using con = New SqlConnection(YourConnectionString)
Using da = New SqlDataAdapter(strSQL, con)
da.SelectCommand.Parameters.AddWithValue("#workorder_number", WONum)
Dim DS As New DataSet
da.Fill(DS)
Return DS
End Using
End Using
End Function
Note that i've also used Using-statements to ensure that all gets diposed even in case of an exception.
Bye the way, the reason for your exception: you had an opening brace here: Where(customer_id which was never closed.
As long as workorder_number is a string then putting single quote ' around the WONum is all you need.
You won't need # or square brackets.
If it's not working with the single quote then ensure you've identified/isolated your problem correctly. Remove the And workorder_number = " & WONum & "" from the end of your sql and see if it works without that. If not, then your problem isn't in the WONum, it's earlier in the string.

What's causing my UPDATE statement not to work?

Good evening all,
I'm using the following as an attempt to update records in my MySQL database, but the records aren't being updated and I'm not catching any exceptions either. Your help would be kindly appreciated:
dbConn = New MySqlConnection("Server=" & FormLogin.ComboBoxServerIP.SelectedItem & ";Port=3306;Uid=trojan;Password=horse;Database=accounting")
Try
If dbConn.State = ConnectionState.Open Then
dbConn.Close()
Else
Try
dbConn.Open()
Dim dbAdapter As New MySqlDataAdapter("UPDATE customer " & _
"SET accountNumber= '" & TextBoxAccount.Text & "', nameLAST='" & TextBoxLastName.Text & "', nameFIRST='" & TextBoxFirstName.Text & "'" & _
"nameSALUTATION='" & ComboBoxSalutation.SelectedItem & "', nameCOMPANY='" & TextBoxCompanyName.Text & "', addressSTREET='" & TextBoxAddress1.Text & "'" & _
"addressSTREET1='" & TextBoxAddress2.Text & "', addressCITY='" & TextBoxCity.Text & "', addressSTATE='" & ComboBoxState.SelectedItem & "'" & _
"addressZIPCODE='" & MaskedTextBoxZip.Text & "', phone='" & MaskedTextBoxPhone.Text & "', fax='" & MaskedTextBoxFax.Text & "', email='" & TextBoxEmail.Text & "'" & _
"WHERE accountNumber='" & TextBoxAccount.Text & "';", dbConn)
Catch ex As Exception
MessageBox.Show("A DATABASE ERROR HAS OCCURED" & vbCrLf & vbCrLf & ex.Message & vbCrLf & _
vbCrLf + "Please report this to the IT/Systems Helpdesk at Ext 131.")
End Try
MessageBox.Show("Customer account SUCCESSFULLY updated!")
Call lockForm()
End If
Catch ex As Exception
MessageBox.Show("A DATABASE ERROR HAS OCCURED" & vbCrLf & vbCrLf & ex.Message & vbCrLf & _
vbCrLf + "Please report this to the IT/Systems Helpdesk at Ext 131.")
End Try
Call lockForm()
dbConn.Close()
Use MySQLCommand instead of MySQLDataAdapter. You are defeating the purpose of using ADONet because still your code is vulnerable with sql injection. Make it parameterized. Below is a modified code from your code. It uses Using-End Using for proper handling of object disposal.
Dim ConnectionString As String ="Server=" & FormLogin.ComboBoxServerIP.SelectedItem & ";Port=3306;Uid=trojan;Password=horse;Database=accounting"
Dim iQuery As String = "UPDATE customer " & _
"SET accountNumber = #accountNumber, nameLAST = #nameLAST, nameFIRST = #nameFIRST, " & _
" nameSALUTATION = #nameSALUTATION, nameCOMPANY = #nameCOMPANY, addressSTREET = #addressSTREET, " & _
" addressSTREET1 = #addressSTREET1, addressCITY = #addressCITY, addressSTATE = #addressSTATE, " & _
" addressZIPCODE = #addressZIPCODE, phone = #phone, fax = #fax, email = #email " & _
"WHERE accountNumber = #accountNumber"
Using dbConn As New MySqlConnection(ConnectionString)
Using dbComm As New MySQLCommand()
With dbComm
.Connection = dbConn
.CommandType = CommandType.Text
.CommandText = iQuery
.Parameters.AddWithValue("#accountNumber", TextBoxAccount.Text )
.Parameters.AddWithValue("#nameLAST", TextBoxLastName.Text)
.Parameters.AddWithValue("#nameFIRST", TextBoxFirstName.Text)
.Parameters.AddWithValue("#nameSALUTATION", ComboBoxSalutation.SelectedItem)
.Parameters.AddWithValue("#nameCOMPANY", TextBoxCompanyName.Text)
.Parameters.AddWithValue("#addressSTREET", TextBoxAddress1.Text)
.Parameters.AddWithValue("#addressSTREET1", TextBoxAddress2.Text)
.Parameters.AddWithValue("#addressCITY", TextBoxCity.Text)
.Parameters.AddWithValue("#addressSTATE", ComboBoxState.SelectedItem)
.Parameters.AddWithValue("#addressZIPCODE", MaskedTextBoxZip.Text)
.Parameters.AddWithValue("#phone", MaskedTextBoxPhone.Text)
.Parameters.AddWithValue("#fax", MaskedTextBoxFax.Text)
.Parameters.AddWithValue("#email", TextBoxEmail.Text)
End With
Try
dbConn.Open
dbComm.ExecuteNonQuery()
MessageBox.Show("Customer account SUCCESSFULLY updated!")
Call lockForm()
Catch( ex as MySQLException)
MessageBox.Show("A DATABASE ERROR HAS OCCURED" & vbCrLf & vbCrLf & ex.Message & vbCrLf & _
vbCrLf + "Please report this to the IT/Systems Helpdesk at Ext 131.")
Finally
dbConn.Close()
End Try
End Using
End Using
In this case, I would use ExecuteNonQuery as you can't use a MySQLDataAdapter the way you are trying to use it. Also please use paramters as what you are doing opens you up to SQL injection attacks. And finally you don't need to update accountNumber because you are using that to find the row which you want to update!