Data type mismatch on SQL Query in VBA - sql

I am trying to do an SQL query in VBA to retun a specific case number. Whenever I execute the query, it returns an error of "Data Type Mismatch in Criteria Expression". I am passing the query an integer to use to query an autonumber primary key.
Dim c As ADODB.Connection
Dim r As ADODB.Recordset
Dim strSQL As String, strManager As String
Set c = New ADODB.Connection
c.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Commit Tracker.accdb; Persist Security Info=False;"
strSQL = "SELECT * FROM CommitTrk WHERE CASE_ID_NBR = '" & CInt(frmCommitViewer.lstCases.Value) & "'"
Set r = c.Execute(strSQL)
Of course the debug hilights the execute command. Any help would be appreciated. Am I passing the wrong datatype to match the autonumber? If so, what datatype should I be using? Thanks!

if CASE_ID_NBR has numeric type, you should use it without quotes:
strSQL = "SELECT * FROM CommitTrk WHERE CASE_ID_NBR = " & CInt(frmCommitViewer.lstCases.Value)
you may also want to read this: Global Variables in SQL statement

Related

VBA SQL pulled data coming back as empty

I'm pulling into Excel VBA from a SQL ADODB Connection and it seems that some fields are coming back as empty that have values in SQL. I'm very green in VBA (just diving back into a legacy application to try and migrate everything to SQL Database storage instead of CSVs)
Here's an example of the value return (just a " where we should have "Sample Data | QRSTE/ S179399")
The code to pull:
Sub GetDFInfoByDf(recordID As String, connectionString as String)
Dim connectionString As String
connectionString = connectionString
Dim command As String
command = "Select * FROM data_table WHERE id = '" & recordID & "'"
Dim conn As ADODB.Connection
Dim rs As ADODB.Recordset
Set conn = New ADODB.Connection
Set rs = New ADODB.Recordset
conn.Open connectionString
rs.CursorLocation = adUseClient
rs.CursorType = adOpenStatic
rs.LockType = adLockBatchOptimistic
Set rs = conn.Execute(command)
Dim rsMatrix As Variant
rsMatrix = rs.GetRows(1)
If IsNull(rs) Then
'rs is null
MsgBox "Pulled recordset is null"
Else
Call FillObjValuesFromRecordSet(rs)
End If
I see that we have a somewhat special character in there (|)
In terms of any SQL Encoding configurations: It's most likely UTF-8. I would think that I have to convert that to ANSI either in VBA or on the SQL side, but have been running in circles to try and figure that out.
Note that this field is NVARCHAR in SQL
Any ideas on how to handle this? Documentation is very sparse on the subject, from what I've seen.
Thanks!
Things I've Tried:
Adding Session Mode=ANSI; to the connection string
Expected Outcome:
-SQL stores the varchar "Sample Data | QRSTE/ S179399" (no quotes in the field)
-I'm expecting my Select to return that exact varchar/string value instead of the return in the image (")
Solution:
My SQL table columns with varchar(max) or nvarchar(max) were not able to translate back.
My initial table had larger-than-needed sizes, so altering those columns to varchar(8000) and nvarchar(4000) fixed the issue!
Thanks

Retrieving "Number" From Sql VB.NET System.Data.OleDb.OleDbException: 'Data type mismatch in criteria expression.'

If I want to retrieve a value that is saved as a number in an access database.
Im using the following:
Dim sql As String = "SELECT ArithmeticScore FROM " & tablename & " WHERE DateAscending = '" & todaysdate & "'"
Using connection As New OleDbConnection(getconn)
Using command As New OleDbCommand(sql, connection)
connection.Open()
scorevalue = CDec(command.ExecuteScalar()) 'Data type mismatch in criteria expression.
connection.Close()
End Using
End Using
MsgBox(scorevalue)
getconn = connection string as a string
scorevalue = Nothing as decimal
The field ArithmeticScore is set to Number in the table.
The exact value in the cell right now is 50, but the program should allow for any decimal value.
The error im getting is "Data type mismatch in criteria expression".
The criteria expression mentioned in the error message does not refer to the ArithmeticScore output. It's talking about the WHERE clause. Whatever you have for todaysdate does not match what the database is expecting for the DateAscending column.
Since OleDb is a generic provider, we don't know exactly what kind of database you're talking to, but most databases have a way to get the current date value in SQL: getdate(), current_timestamp, etc. Using that mechanism will likely solve the conflict, and there's no need to use string concatenation for this in the first place.
Dim sql As String = "SELECT ArithmeticScore FROM " & tablename & " WHERE DateAscending = Date()"
The other way you can fix this is with proper parameterized queries, which you should doing anyway. It's NEVER okay to use string concatenation to substitute data into an SQL query, and if you find yourself needing to think about how to format a date or number string for use in an SQL command, you're almost always doing something very wrong.

How to write a query that uses a number as parameter and number type field?

I need to start a query to retrieve data from Access database using VBA which I want to use a variable number as a parameter. Is it possible?
like the:
field name: NMT field type (number)
table name: Orders
and the code is like the following:
Dim Con As New ADODB.Connection
Dim RS As New ADODB.Recordset
Dim X as Integer
X = me.textbox1.value
Con.Open "Provider= Microsoft.ACE.OLEDB.12.0;Data Source=" & U.Database01 & "\DB.accdb;Persist Security Info=False"
Rs.Open "select * from Orders where nmt = '" + X + "'", Con, adOpenDynamic, adLockPessimistic
Whenever I run this query, I get a run-time error '13' type mismatch.
Any suggestions ?
Multiple Issues
Type-mismatch in WHERE clause:
Your query (i.e. the WHERE clause) tries to compare a Number-column from database with a String-value (e.g. WHERE numberField = '123'). This will result in a runtime error Type mismatch (Error 13). See also similar question.
Unsafe to use + to concatenate Strings
When building the query you tried to concatenate the query-template with the number-parameter by a plus-sign. This works only when operating on numbers. See related question
Solution
remove single-quotes: you should compare the Number-column NMT with a number literal (e.g. WHERE nmt = 123)
use & to concatenate strings. This will also convert numbers to strings. Besides I explicitly used CStr function below.
Dim Con As New ADODB.Connection
Dim RS As New ADODB.Recordset
Dim strSQL As String
Dim nmtNumber as Integer ' you named it x before
nmtNumber = me.textbox1.value
strSQL = "SELECT * FROM Orders WHERE nmt = " & CStr(nmtNumber) ' removed single-quotes and used ampersand to concatenate with converted string
Con.Open "Provider= Microsoft.ACE.OLEDB.12.0;Data Source=" & U.Database01 & "\DB.accdb;Persist Security Info=False"
RS.Open strSQL, Con, adOpenDynamic, adLockPessimistic
Further improvement
I already extracted the SQL string (building) into a separate variable strSQL above.
Better would be to use predefined/prepared and parameterized queries:
QueryDef (DAO) where you can set the parameters (type-safe). See this question.
Command (ADODB) where you can set parameters (type-safe). See this question.
See also
What is ‘Run-time error ‘13’: Type mismatch’? And How Do You Fix It?
VBA Type Mismatch Error

How to retain the AutoNumber of a Primary Key when executing a query in MS Access?

I am trying to do something like the following in a query:
Dim rs As RecordSet
Dim NewPrimaryKey as Long
Set rs = Currentdb.OpenRecordset("SELECT * FROM MyTable WHERE MyPrimaryKey Is Null;")
With rs
.AddNew
NewPrimaryKey = !MyPrimaryKey
!DateValue = Now()
...
.Update
End With
Any pointers on how to do t his using a query that I can execute in MS Access 2003 using the JET engine would be greatly appreciated.
You can use two SQL statements to accomplish what I think you want. First an INSERT. Then "SELECT ##Identity" to get the last added autonumber value. Use an object variable for the database connection with both SQL statements.
Dim db As DAO.Database
Dim NewPrimaryKey As Long
Dim strInsert As String
strInsert = "INSERT INTO MyTable ([DateValue])" & vbCrLf & _
"VALUES (Now());"
Set db = CurrentDb
db.Execute strInsert, dbFailOnError
NewPrimaryKey = db.OpenRecordset("SELECT ##Identity")(0)
Debug.Print NewPrimaryKey
Set db = Nothing
I enclosed the field name DateValue in square brackets because it is a reserved word.
Edit: If you insert multiple records with one SQL statement, SELECT ##Identity will still give you the last autonumber. It's the last autonumber for inserts performed through that connection instance. And you don't get a sequence of the autonumbers used; only the last one.
strInsert = "INSERT INTO MyTable3 ([some_text])" & vbCrLf & _
"SELECT TOP 3 foo_text FROM tblFoo" & vbCrLf & _
"WHERE foo_text Is Not Null ORDER BY foo_text;"

How to return the value in one field based on lookup value in another field

This is basic stuff, but I'm somewhat unfamiliar with VBA and the Word/Access object models.
I have a two column database of about 117000 records. The columns are 'surname' and 'count'. I want a user to be able to type SMITH in a textbox and hit submit. I then want to run something like
SELECT table.count FROM table WHERE surname = string
and return the value of table.count in a string.
It feels like this should be five or six lines of code (which I have but won't post) but I'm obviously missing something!
Cheers
First of all, be careful naming the column 'count' -- this is a keyword in SQL and might cause problems. Similarly, don't call the table 'table'.
Here is some sample code which shows one way of doing it:
' This example uses Microsoft ActiveX Data Objects 2.8,
' which you have to check in Tools | References
' Create the connection. This connection may be reused for other queries.
' Use connectionstrings.com to get the syntax to connect to your database:
Dim conn As New ADODB.Connection
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\tmp\Database1.accdb"
Dim cmd As New ADODB.Command
Set cmd.ActiveConnection = conn
' Replace anything which might change in the following SQL string with ?
cmd.CommandText = "select ct from tbl where surname = ?"
' Create one parameter for every ?
Dim param As ADODB.Parameter
Set param = cmd.CreateParameter("surname", adBSTR, adParamInput, , TextBox1.Text)
cmd.Parameters.Append param
Dim rs As ADODB.Recordset
Set rs = cmd.Execute
MsgBox rs("ct")
rs.Close
conn.Close
It is possible to use InsertDatabase:
Sub GetData()
ActiveDocument.Bookmarks("InsertHere").Select
Selection.Range.InsertDatabase Format:=0, Style:=0, LinkToSource:=False, _
Connection:="TABLE Members", SQLStatement:= _
"SELECT [Count] FROM [Members]" _
& " WHERE Surname='" _
& ActiveDocument.FormFields("Text1").Result & "'", _
DataSource:="C:\docs\ltd.mdb", From:=-1, To:= _
-1, IncludeFields:=True
End Sub
This is an edited macro recorded using the database toolbar.
EDITED Warning: this code, as shown, is subject to a SQL Injection attack.