SQL concatenation inside VBA string - sql

I'm using VBA excel 2003,SQL 2005 to make a sql query call and inside my sql statement I'm using '+' operator to concatenate two strings.
dim query as string
query = "Select distinct ', '+emailaddress1 "
query = query & "from contact "
would this work inside vba? My query returns too many records in excel but not in SQL?
Please just focus on this 2 lines of code and not worry about the rest of my sql call, I'm just wondering whether or not this specific string would work?

Your code will return a column where each row would be an email address with a comma in front of it. If that is what you want, then yes, it will work.
If, on contrary, you want a single string where all email addresses would be listed, separated with commas, that'd be
query = "declare #foo varchar(max);"
query = query & "select distinct #foo = isnull(#foo,'') + emailaddress1 + ', ' from contact;"
query = query & "select left(#foo, len(#foo)-2);"

Related

MS Access multi field search with empty fields

I have a problem very similar to this one, but I just can't seem to solve it!
In MS Access (2003), I want to search a table based on entries in a number of fields, some of which may be empty.
I have:
text fields
date fields
integer fields, and
a memo field (but we can probably not bother searching this one if it is difficult).
They map onto a table exactly.
I am trying to create a query that will return matching rows when data is entered into one or more of these fields, but some fields can be left blank. How the heck do I do this?
A query like the one on the linked question works for text fields, but what do I do about the number fields, date fields (and possibly even the memo field)?
To give a clear example, the following code block works for TextField1, but not NumberField1:
PARAMETERS [Forms]![SearchForm]![FilterTextField1] Text ( 255 ), [Forms]![SearchForm]![FilterNumberField1] Text ( 255 );
SELECT Table1.[TextField1], Table1.[NumberField1], Table1.[TextField2], Table1.[TextField3], Table1.[DateField1], Table1.[DateField2], Table1.[DateField3]
FROM Table1
WHERE (Len([Forms]![SearchForm]![FilterTextField1] & '')=0 OR Table1.[TextField1] Like '*' & [Forms]![SearchForm]![FilterTextField1] & '*') AND (Len([Forms]![SearchForm]![FilterNumberField1] & '')=0 OR Table1.[NumberField1] Like '*' & [Forms]![SearchForm]![FilterNumberField1] & '*');
I do hope you can help. I'm sure I'm missing something really obvious, but for some reason my brain feels like it is leaking out of my ears at the moment.
Thank you!
If you need it, this is the basic design of the relevant entities:
Table1
SomePrimaryKeyWeDontCareAboutRightNow
TextField1
TextField2
TextField3
NumberField1
DateField1
DateField2
DateField3
MemoField1
SearchForm
FilterTextField1
FilterTextField2
FilterTextField3
FilterNumberField1
FilterDateField1
FilterDateField2
FilterDateField3
FilterMemoField1
You can check fo null values or cast to string
You could certainly spend a great deal of time crafting a huge and very hard to debug SQL query for this, or just jump into VBA and write some code to construct just the SQL you need.
VBA is there just for these kinds of scenario, where something is either impossible or becoming too complex to do otherwise.
With VBA, you can use an initial SELECT query that collect all the data, and then construct a WHERE clause based on the content of your search form to filter it.
For instance, I have a form like this, that allows the user to enter any criteria to filter a list of prices:
Some code to implement this could look like:
' Call this whenever the use click the Apply button '
Private Sub btApply_Click()
' Construct the filter '
Dim filter As String
If Not IsBlank(cbSupplierID) Then
If Not IsBlank(filter) Then filter = filter & " AND "
filter = filter & "(SupplierID=" & cbSupplierID & ")"
End If
If Not IsBlank(txtPartNumber) Then
If Not IsBlank(filter) Then filter = filter & " AND "
filter = filter & "(PartNumber LIKE '*" & txtPartNumber & "*')"
End If
If Not ckShowLocked Then
If Not IsBlank(filter) Then filter = filter & " AND "
filter = filter & "(NOT PriceLocked)"
End If
' ... code snipped, you get the jest ... '
' Now re-construct the SQL query '
Dim sql As String
sql = "SELECT * FROM Price"
If Not IsBlank(filter) Then
sql = sql & " WHERE " & filter
End If
SubForm.Form.RecordSource = sql
End Sub
It may seem like a lot of code, but each block only does one thing, and it's a lot easier to debug and maintain than cramming everything into a query.

Using a VBA array in a SQL statement

I am trying to write some code that uses SQL to delete rows from several tables.
A user would type type numbers into a textbox that are separated by a comma which is used in the WHERE clause of a SQL DELETE statement.
I have managed to split the string into a variant array and now I want to insert it into my SQL statement.
How do I insert the variable into the SQL statement and have it run through every element of the array?
EDIT: A bit more digging has taught me about For Each Next statements. This is probably what im looking for.
I suggest you build your query in VBA, then your list of numbers can be an IN statement:
sSQL = "DELETE FROM table WHERE ID In (" & MyList & ")"
Where MyList = "1,2,3,4" or such like.
As you can see, you do not need an array and a textbox would be more suitable than a combobox. If you wish to allow your users to select by say, a name, then a listbox is useful. You can iterate through the selected items in the listbox and build a string from IDs to be used in the Delete statement. ( MS Access 2007 - Cycling through values in a list box to grab id's for a SQL statement )
You can then execute the sql against an instance of a database. For example:
Dim db As Database
Set db = CurrentDB
db.Execute sSQL, dbFailOnError
MsgBox "You deleted " & db.RecordsAffected & " records."
A generic approach
WHERE
','+Array+',' like '%,'+col+',%'
It will consider all the numbers available in your Array
You could make it simple and elaborate a string, something like
stringBuilder sb = StringBuilder("DELETE FROM YOURTABLE WHERE ");
foreach(string st in stringArray){
sb.append("YOURFIELD='" + st + "'");
//If it is not the last element, add an "OR"
if (st != stringArray[stringArray.length -1]) sb.append(" OR ");
}
//Now, you have a string like
//DELETE FROM YOURTABLE WHERE YOURFIELD='hello' OR YOURFIELD='YES'
//... do something with the command
This method will fail if you want to run SQL query on two (or multiple) columns using array values from two different arrays. .e.g
where col1=array1(i) and col2=array2(i)

How do I save the result of an SQL COUNT query with VBA in Access 2007?

I'm trying to count the number of records in a table that meet a certain criteria. My preference is to use SQL, not Dcount, as I want to get better at SQL. Here's my current code below:
Dim countString As String
Dim count
countString = "SELECT COUNT(*) FROM `Engagement Letters` WHERE 'Client ID' = " & Me.cboSelectClient
count = CurrentDb.OpenRecordset(countString).Fields(0).Value
Yeah I know, I've used spaces in my tables and field names - I will change that. Though I think I should still be able to run this query as is, so I will leave it as is for now.
When I run the above, I get runtime error 3464 - data type mismatch in criteria expression. I've had the below dcount function work fine:
count = DCount("[Engagement Letter ID]", "Engagement Letters", "[Client ID] = " & Me.cboSelectClient)
And also the below COUNT query without the WHERE works fine:
"SELECT COUNT(*) FROM `Engagement Letters`"
My knowledge of SQL is very minimal, and my knowledge of more advanced VBA is also quite minimal, so I'm not sure where I'm going wrong. Can anyone help me with this?
Try building your string like this.
countString = "SELECT COUNT(*) FROM [Engagement Letters]" & vbCrLf & _
"WHERE [Client ID] = " & Me.cboSelectClient
Debug.Print countString
Use square brackets around object (table and field) names which include spaces or any characters other than letters, digits, and the underscore character.
For the table name, you used `Engagement Letters`, and the backticks appear to work the same as square brackets. Perhaps they always work equally well, but I don't know for sure because I use the brackets exclusively. And brackets instead of backticks might help you avoid this mistake ...
WHERE 'Client ID' = " & Me.cboSelectClient
... that was asking the db engine to compare the literal string, "Client ID", to the numerical value (?) you pulled from cboSelectClient.
I used vbCrLf between the 2 parts of the SELECT statement because I find that convenient when examining the completed string (via Debug.Print).

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("'", "''"))

Matching text string on first letter in SQL query

SAMPLE CODE:
Dim sql As String = "SELECT * FROM " + tblName + " WHERE needsTranslation = 'True' AND dataText LIKE " & "'" & alpha & "%" & "'" & " ORDER BY dataText;"
da = New SqlDataAdapter(sql, strConnection)
OP:
I would like to create a SQL query that returns all records when the first letter of a string matches my variable. I am coding this in an ASP.net code behind page in vb.net.
SELECT * FROM " + tblName + " WHERE textData = ' & alpha & "
In this exmample textData is a string of text and alpha is a single letter a through z or A through Z.
I don't need the criteria to be case sensitive, but I do need only the first letter of textData to match alpha.
I have tested the LIKE comparator and it does not return all records that begin with alpha.
What is the best way to do this? Any and all help will be appreciated.
thanks again,
The LIKE operator is what you'd want to use, but you have to use the % wildcard character like so:
SELECT * FROM MyTable WHERE textData LIKE 'a%'
SQL has sub-string operator SUBSTR() or SUBSTRING()
select * from tableName where substr( textData ) in ( 'A', 'B', 'C', ... );
I couldn't add to the comments on one of the other posts, but I'll strongly second the need to use a parameterized query for these reasons (you can include usage of the like operator with the wildcard % like the other answer correctly summarized to answer your question):
It will protect you from making mistakes with single quotes, especially if the user enters a search string that includes them
(they will cause your query to fail).
It protects you from SQL injection exploits. Example, a user were able to input the value of the variable "alpha" in the above
example they could enter something like:
'; DELETE FROM ;
If the user you were using had excessive database rights, they could
wreak all kinds of havoc (or they could potentially get access to
data they shouldn't have access to).