VBA sql query problem - sql

Below query is resulting NO rows
lstResults.RowSource = "select EmpId from tblTesting where Empid ='" & Me.txtSearchEmpId.Value & "'"
Where below working fine :
lstResults.RowSource = "select * from tblTesting"
WHere is the fault here?
I check the value of '" & Me.txtSearchEmpId.Value & "'" using break point its having the value of "123" (numerical)
My empid is numerical value
Please help

If your EmpId is numerical, you probably want to remove the single-quotes:
lstResults.RowSource = "select EmpId from tblTesting where Empid = " & Me.txtSearchEmpId.Value
How does that work?

First, remove the single quotes from around your value, if it really is a number.
Second, cleanse your input. What if someone types 123 or true into your input field? You've then let them select all inputs. You might want to convert the value to an integer and then back to a string to make sure it is pure.
See xkcd #327:

Related

Passing a string variable in SQL query

I am trying to write a SQL query that takes in WHERE conditional value from a variable.
The variable is a string type and it is being extracted first from a different table using a different query through the use of recordsets. I think I got the quotations right in the query but it shows "Undefined function 'rsDB' in expression" error.
extPMBActID_SQL = "SELECT * FROM PMB;"
Set rsDB = CurrentDb.OpenRecordset(extPMBActID_SQL, dbOpenDynaset)
testID = Left(rsDB.Fields("ActivityID"), 2)
instRptGen_SQL = "SELECT AreaName FROM Area WHERE AreaID =" & "Left(rsDB.Fields('ActivityID'), 2)" & ";"
Set rsDB = CurrentDb.OpenRecordset(instRptGen_SQL, dbOpenDynaset)
I think whenever the query is ran, it is somehow not able to fetch rsDB.Fields("ActivityID") value. I am sure that testID variable does have the value.
Any ideas what I am missing here?
Remove the quotes from that second part:
instRptGen_SQL = "SELECT AreaName FROM Area WHERE AreaID =" & _
Left(rsDB.Fields("ActivityID").Value, 2)
You don't need the terminating ;, and if AreaID is not numeric you need single quotes around the value:
instRptGen_SQL = "SELECT AreaName FROM Area WHERE AreaID ='" & _
Left(rsDB.Fields("ActivityID").Value, 2) & "'"

Runtime error '3075' in VBA

I know there are plenty of posts with the same title, but I couldn't find anything similar to my problem.
I'm trying to update a record with SQL in VBA. In particular, my code goes to an excel file, extracts a value, asks the user for the ID of the record that needs to be updated, and then should procced to do the update. The thing is i tried running the same code without the user input, and works just fine, so the problem must be with the interpretation of the input. I checked that everything is a string but i don't know how to solve the problem.
Here is the code I am using:
Dim query2 as string
Dim myID as string
myID = InputBox("Insert ID:")
query2 = "UPDATE [Info test] " & "SET RESULT = " & var & "WHERE ID =" & myID
DoCmd.RunSQL (query2)
In this case, var is a string, and is the value i fetch from the excel file.
From various tests, i think the problem is with the last & myID, like there is an apostrophe before the value stored by myID, but i don't know what to do about it, or if this is really the problem.
Thanks to everybody who can help
Insert Debug.Print query2 before DoCmd, run the code and check output in immediate window. This SQl should work in query builder. I believe you need to enclose var in single quotes and add a space before WHERE
query2 = "UPDATE [Info test] SET RESULT = '" & Replace(var, "'", "''") & "' WHERE ID =" & myID
I added Replace in order to avoid errors if var contains single quote.
If var is a string, then you need to use single quotes and add space before WHERE like shown below
query2 = "UPDATE [Info test] " & "SET RESULT = '" & var & "' WHERE ID =" & myID

VB.NET 2010 & MS Access 2010 - Conversion from string "" to type 'Double' is not valid

I am new to VB.Net 2010. Here is my problem: I have a query that uses a combo box to fetch many items in tblKBA. All IDs in the MS Access database are integers. The combo box display member and value member is set to the asset and ID of tblProducts.
myQuery = "SELECT id, desc, solution FROM tblKBA WHERE tblKBA.product_id = '" + cmbProducts.SelectedValue + "'"
In addition to getting items from the KBA table, I want to fetch the department details from the department table, possibly done in the same query. I am trying to do it in two separate queries.
myQuery = "select telephone, desc, website from tblDepartments where tblDepartments.product_id = tblProducts.id and tblProducts.id = '" + cmbProducts.SelectedValue + "' "
All help will be appreciated!
Change the '+' to a '&' then the compiler would be happy.
try adding .toString to cmbproducts.selectedvalue or do "tblKBA.product_id.equals(" & cmbProducts.selectedValue.toString & ")"
1.) Don't use string concatenation to build your query. Use parameters.
2.) I am guessing that tblKBA.product_id is a double and not a string, so don't put quotes around it.
myQuery = "SELECT id, desc FROM tblKBA WHERE tblKBA.product_id = ?"
3 things. Test your value before building the select statement. Second, Use .SelectedItem.Value instead of .SelectedValue. Third, protect yourself from sql injection attack. Use parameters, or at the very least check for ' values.
If IsNumeric(cmbProducts.SelectedItem.Value) = False Then
'No valid value
Return
End If
myQuery = String.Format("SELECT id, desc FROM tblKBA WHERE tblKBA.product_id = {0}", cmbProducts.SelectedItem.Value.Replace("'", "''"))

String or binary data would be truncated. The statement has been terminated

I always got an error when adding a new data. the error says
String or binary data would be truncated. The statement has been terminated
As I've looked back on my backend or code. It looks like there's a conflict adding a TWO LABEL DATA in one column because I would like to join the (Year)-(StudentNumber)
Here's the code of my INSERT INTO Statement
INSERT INTO
[Student_Information] (StudentID, LastName, FirstName, MiddleName, Gender,
ContactNumber, Citizenship, Religion, Birthday, Address)
VALUES
( '" & lbl_cyear.Text - studid.Text & "','" + txt_lname.Text + "', '" + txt_fname.Text + "', '" + txt_mname.Text + "', '" + DDGender.Text + "', '" & txt_cnumber.Text & "', '" & txt_citizenship.Text & "' , '" + txt_religion.Text + "' , '" & txt_bday.Text & "', '" & txt_address.Text & "' )"
and here's the code how I generate the Year and the Student Number
Sub SNYear()
Dim test As Date
test = Convert.ToDateTime(Today)
lbl_cyear.Text = test.Year
End Sub
Sub SNGenerate()
'displaying Studentid
Dim SN As Integer ' Student Number
Dim SID As String 'Student ID Num as String
Dim rdr As SqlDataReader
cmd1.Connection = cn
cmd1.Connection.Open()
cmd1.CommandText = "Select Max (StudentID) as expr1 from [Student_Information]"
rdr = cmd1.ExecuteReader
If rdr.HasRows = True Then
rdr.Read()
End If
If rdr.Item(0).ToString = Nothing Then
SN = rdr.Item(0) + 1
SID = Format(SN, "0000")
ElseIf rdr.Item(0).ToString = 0 Then
SN = rdr.Item(0) + 1
SID = Format(SN, "0000")
Else
SN = rdr.Item(0) + 1
SID = Format(SN, "0000")
End If
studid.Text = SID
cmd1.Connection.Close()
End Sub
Can someone help me with the code? How to join 2 data in different label text and save it to one column in my table.
Woah! Never ever write sql queries like that. It's subject to dangerous SQL injection, and code like that is actually used as worst-case scenarios in SQL injection lectures everywhere!
That being said, the error message String or binary data would be truncated. The statement has been terminated. actually spells out what is wrong. You are trying to insert too much data into a field that has a specific dimension.
You are trying to insert the following expression into the StudentID field:
lbl_cyear.Text - studid.Text
I'm not even sure what you want to do there. Since Visual Basic is loosely typed by default, It will probably handle the lbl_cyear.Text as a number and try to subtract the studid.Text (as a number) from it. You probably mean something like this:
lbl_cyear.Text & "-" & studid.Text
It seems you are trying to use the StudentID column for two different types of information. Don't do that. Decide on one format for the student ids and dimension the column for it.
Is this a homework assignment?
Y#atornblad has some very valid points about re-structuring your code. However, the specific problem you are asking about is likely because you are trying to insert data into a column that is longer than the column can accept.
E.g. - you are trying to insert "Lorem Ipsum" into a column that has a maximum length of 5 characters.
Edit
You need to take another look at how your table is defined and make sure it is appropriate for the data you are storing. Also - make sure the data you are trying to store is in the correct format that the table was designed for. Don't assume it's in the format you want, actually step through the program in debug mode and look at what the variable is before it gets sent to the database.

Escaping ' in Access SQL

I'm trying to do a domain lookup in vba with something like this:
DLookup("island", "villages", "village = '" & txtVillage & "'")
This works fine until txtVillage is something like Dillon's Bay, when the apostrophe is taken to be a single quote, and I get a run-time error.
I've written a trivial function that escapes single quotes - it replaces "'" with "''". This seems to be something that comes up fairly often, but I can't find any reference to a built-in function that does the same. Have I missed something?
The "Replace" function should do the trick. Based on your code above:
DLookup("island", "villages", "village = '" & Replace(txtVillage, "'", "''") & "'")
It's worse than you think. Think about what would happen if someone entered a value like this, and you haven't escaped anything:
'); DROP TABLE [YourTable]
Not pretty.
The reason there's no built in function to simply escape an apostrophe is because the correct way to handle this is to use query parameters. For an Ole/Access style query you'd set this as your query string:
DLookup("island", "village", "village = ? ")
And then set the parameter separately. I don't know how you go about setting the parameter value from vba, though.
Though the shorthand domain functions such as DLookup are tempting, they have their disadvantages. The equivalent Jet SQL is something like
SELECT FIRST(island)
FROM villages
WHERE village = ?;
If you have more than one matching candidate it will pick the 'first' one, the definition of 'first' is implementation (SQL engine) dependent and undefined for the Jet/ACE engine IIRC. Do you know which one would be first? If you don’t then steer clear of DLookup :)
[For interest, the answer for Jet/ACE will either be the minimum value based on the clusterd index at the time the database file was last compacted or the first (valid time) inserted value if the database has never been compacted. Clustered index is in turn determined by the PRIAMRY KEY if persent otherwise a UNIQUE constraint or index defined on NOT NULL columns, otherwise the first (valid time) inserted row. What if there is more than one UNIQUE constraint or index defined on NOT NULL columns, which one would be used for clustering? I've no idea! I trust you get the idea that 'first' is not easy to determine, even when you know how!]
I've also seen advice from Microsoft to avoid using domain aggregate functions from an optimization point of view:
Information about query performance in an Access database
http://support.microsoft.com/kb/209126
"Avoid using domain aggregate functions, such as the DLookup function... the Jet database engine cannot optimize queries that use domain aggregate functions"
If you choose to re-write using a query you can then take advantage of the PARAMETERS syntax, or you may prefer the Jet 4.0/ACE PROCEDURE syntax e.g. something like
CREATE PROCEDURE GetUniqueIslandName
(
:village_name VARCHAR(60)
)
AS
SELECT V1.island_name
FROM Villages AS V1
WHERE V1.village_name = :village_name
AND EXISTS
(
SELECT V2.village_name
FROM Villages AS V2
WHERE V2.village_name = V1.village_name
GROUP
BY V2.village_name
HAVING COUNT(*) = 1
);
This way you can use the engine's own functionality -- or at least that of its data providers -- to escape all characters (not merely double- and single quotes) as necessary.
But then, it should be like this (with one more doublequote each):
sSQL = "SELECT * FROM tblTranslation WHERE fldEnglish=""" & myString & """;"
Or what I prefer:
Make a function to escape single quotes, because "escaping" with "[]" would not allow these characters in your string...
Public Function fncSQLStr(varStr As Variant) As String
If IsNull(varStr) Then
fncSQLStr = ""
Else
fncSQLStr = Replace(Trim(varStr), "'", "''")
End If
End Function
I use this function for all my SQL-queries, like SELECT, INSERT and UPDATE (and in the WHERE clause as well...)
strSQL = "INSERT INTO tbl" &
" (fld1, fld2)" & _
" VALUES ('" & fncSQLStr(str1) & "', '" & fncSQLStr(Me.tfFld2.Value) & "');"
or
strSQL = "UPDATE tbl" & _
" SET fld1='" & fncSQLStr(str1) & "', fld2='" & fncSQLStr(Me.tfFld2.Value) & "'" & _
" WHERE fld3='" & fncSQLStr(str3) & "';"
I believe access can use Chr$(34) and happily have single quotes/apostrophes inside.
eg
DLookup("island", "villages", "village = " & chr$(34) & nonEscapedString & chr$(34))
Though then you'd have to escape the chr$(34) (")
You can use the Replace function.
Dim escapedString as String
escapedString = Replace(nonescapedString, "'", "''")
Parametrized queries such as Joel Coehoorn suggested are the way to go, instead of doing concatenation in query string. First - avoids certain security risks, second - I am reasonably certain it takes escaping into engine's own hands and you don't have to worry about that.
By the way, here's my EscapeQuotes function
Public Function EscapeQuotes(s As String) As String
If s = "" Then
EscapeQuotes = ""
ElseIf Left(s, 1) = "'" Then
EscapeQuotes = "''" & EscapeQuotes(Mid(s, 2))
Else
EscapeQuotes = Left(s, 1) & EscapeQuotes(Mid(s, 2))
End If
End Function
For who having trouble with single quotation and Replace function, this line may save your day ^o^
Replace(result, "'", "''", , , vbBinaryCompare)
put brackets around the criteria that might have an apostrophe in it.
SOmething like:
DLookup("island", "villages", "village = '[" & txtVillage & "]'")
They might need to be outside the single quotes or just around txtVillage like:
DLookup("island", "villages", "village = '" & [txtVillage] & "'")
But if you find the right combination, it will take care of the apostrophe.
Keith B
My solution is much simpler. Originally, I used this SQL expression to create an ADO recordset:
Dim sSQL as String
sSQL="SELECT * FROM tblTranslation WHERE fldEnglish='" & myString & "';"
When myString had an apostrophe in it, like Int'l Electrics, my program would halt. Using double quotes solved the problem.
sSQL="SELECT * FROM tblTranslation WHERE fldEnglish="" & myString & "";"