Two combo values into sql string - vb.net

I am trying to combine two combobox selected values in a sql string with the following code :
opdragplaasnommer.CommandText = "SELECT plaasnommer FROM oesskattings
WHERE plaasnaam = '" & CmbPlaasnaam.Text & "'" And aliasnaam = " '" &
CmbAliasnaam.Text & "'"
However, I think I am messing up with my quotes and double quotes. I get the following error message :
Additional information: Conversion from string "SELECT plaasnommer
FROM oesskatt" to type 'Boolean' is not valid.

You really ought to learn how to use the String.Format method or string interpolation. It is far less error-prone than using the concatenation operator (&) over and over. You can see the issue with your code simply by looking at the colour. Anything in a literal String should be red and you can see some of yours that should be red but isn't. Presumably it should be something like this:
opdragplaasnommer.CommandText = "SELECT plaasnommer FROM oesskattings WHERE plaasnaam = '" & CmbPlaasnaam.Text & "' And aliasnaam = '" & CmbAliasnaam.Text & "'"
Using String.Format would look like this:
opdragplaasnommer.CommandText = String.Format("SELECT plaasnommer FROM oesskattings WHERE plaasnaam = '{0}' And aliasnaam = '{1}'", CmbPlaasnaam.Text, CmbAliasnaam.Text)
As you can see, far less easy to mess up. String interpolation would look like this:
opdragplaasnommer.CommandText = $"SELECT plaasnommer FROM oesskattings WHERE plaasnaam = '{CmbPlaasnaam.Text}' And aliasnaam = '{CmbAliasnaam.Text}'"
Given that this is SQL code, an even better idea would be to use parameters. I'm not going to go into detail about that because there's information all over the place but it's something that you really need to learn. Apart from your code being less error-prone, it will help avoid crashes due to formatting issues and, most importantly, protect you from SQL injection attacks.

You have messed up with your string;
opdragplaasnommer.CommandText = "SELECT plaasnommer FROM oesskattings WHERE plaasnaam = '" & CmbPlaasnaam.Text & "' And aliasnaam = '" & CmbAliasnaam.Text & "'"

In VB .NET string concatination is performed with & symbol. And new line requires underscore.
opdragplaasnommer.CommandText = "SELECT plaasnommer FROM oesskattings" & _
" WHERE plaasnaam = '" & CmbPlaasnaam.Text & "' And aliasnaam = '" & _
CmbAliasnaam.Text & "'"
But I would suggest to use String.Format function in this case.
opdragplaasnommer.CommandText = String.Format("SELECT plaasnommer FROM oesskattings WHERE plaasnaam = '{0}' and aliasnaam = '{1}'",
CmbPlaasnaam.Text,CmbAliasnaam.Text)
And again this just another way. But, to say the truth, I hate concatination for SQL queries. Better to declare SQL Parameters and assign value to them.

Related

visual basic like error

Private Sub txtmid_Change()
On Error Resume Next
Mmid = txtmid.Text
Adodc1.RecordSource = "select * from members where txtmid like '" & Mmid & "'"
Adodc1.Refresh
Mname = Adodc1.Recordset.Fields("Mname").Value
Expiryd = Adodc1.Recordset.Fields("Expiryd").Value
txtname.Text = Mname
txtedate(1).Text = Format(Expiryd, "dd / mm / yyyy")
End Sub
I am getting FROM clause error. Please help me to resolve this error. Thank you.
Try this:
First of all, remove On Error Resume Next, because it's dangerous (you should use a very error handler, instead).
Adodc1.RecordSource = "select * from members where Mmid = '" & Mmid & "'"
Note: anyway, for fields of TEXT type, you should use always Replace$() to 'double quote' to avoid mistake when string values contains a single quote. Example:
Dim sql As String
Dim sSearch As String
sSearch = "You are 'magic' developer"
sql = "SELECT * FROM Users WHERE Note = '" & Replace$(sSearch, "'", "''") & "'"
Otherwise, in this case, if you use (wrongly):
sql = "SELECT * FROM Users WHERE Note = '" & sSearch & "'"
You will get a error.

Adding SQL to VBA in Access

I have the following SQL code:
SELECT GrantInformation.GrantRefNumber, GrantInformation.GrantTitle, GrantInformation.StatusGeneral, GrantSummary.Summary
FROM GrantInformation LEFT JOIN GrantSummary ON GrantInformation.GrantRefNumber = GrantSummary.GrantRefNumber
WHERE (((GrantInformation.LeadJointFunder) = "Global Challenges Research Fund")) Or (((GrantInformation.Call) = "AMR large collab"))
GROUP BY GrantInformation.GrantRefNumber, GrantInformation.GrantTitle, GrantInformation.StatusGeneral, GrantSummary.Summary
HAVING (((GrantSummary.Summary) Like ""*" & strsearch & "*"")) OR (((GrantSummary.Summary) Like ""*" & strsearch & "*""));
Which I want to insert into the following VBA:
Private Sub Command12_Click()
strsearch = Me.Text13.Value
Task =
Me.RecordSource = Task
End Sub
After 'Task ='.
However it keeps on returning a compile error, expects end of statement and half the SQL is in red. I have tried adding ' & _' to the end of each line but it still will not compile.
Any suggestions where I am going wrong? Many thanks
You have to put the SQL into a string...
Dim sql As String
sql = "SELECT blah FROM blah;"
Note that this means you have to insert all of the values and double up quotes:
sql = "SELECT blah "
sql = sql & " FROM blah "
sql = sql & " WHERE blah = ""some value"" "
sql = sql & " AND blah = """ & someVariable & """;"
After that, you have to do something with it. For SELECTs, open a recordset:
Dim rs AS DAO.Recordset
Set rs = CurrentDb.OpenRecordset(sql)
Or, for action queries, execute them:
CurrentDb.Execute sql, dbFailOnError
Without knowing how you plan to use it, we can't give much more info than that.
This conversion tool would be quite helpful for automating the process: http://allenbrowne.com/ser-71.html
I suggest to use single quotes inside your SQL string to not mess up the double quotes forming the string.
In my opinion it's a lot better readable than doubled double quotes.
Simplified:
Dim S As String
S = "SELECT foo FROM bar " & _
"WHERE foo = 'Global Challenges Research Fund' " & _
"HAVING (Summary Like '*" & strsearch & "*')"
Note the spaces at the end of each line.
Obligatory reading: How to debug dynamic SQL in VBA
Edit
To simplify handling user entry, I use
' Make a string safe to use in Sql: a'string --> 'a''string'
Public Function Sqlify(ByVal S As String) As String
S = Replace(S, "'", "''")
S = "'" & S & "'"
Sqlify = S
End Function
then it's
"HAVING (Summary Like " & Sqlify("*" & strsearch & "*") & ")"

SQL Variable in Where Clause

Dim varCity As String
varCity = Me.txtDestinationCity
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE" & Me.txtDestinationCity & "= [TDestinationType].[tPreTravelDestinationCity]"
I am trying to select the states for the selected city. There is a drop down box with a list of cities. That box is titled txtDestinationCity.
It says I have an error in my FROM clause.
Thank you
You miss a space and some quotes. How about:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE '" & Me.txtDestinationCity & "' = [TDestinationType].[tPreTravelDestinationCity]"
Copy that next to your original to see the difference.
And for reasons SQL, PLEASE reverse the comparison. Always mention the column left and the value right:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE [TDestinationType].[tPreTravelDestinationCity] = '" & Me.txtDestinationCity & "'"
Since the quotes are annoying and easy to miss, i suggest defining a function like this:
Public Function q(ByVal s As String) As String
q = "'" & s & "'"
End Function
and then write the SQL string like that:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE [TDestinationType].[tPreTravelDestinationCity] = " & q(Me.txtDestinationCity)
This makes sure you ALWAYS get both quotes at the right places and not get confused by double-single-double quote sequences.
If you care about SQL-injection (yes, look that up), please use the minimum
Public Function escapeSQL(sql As String) As String
escapeSQL = Replace(sql, "'", "''")
End Function
and use it in all places where you concatenate user-input to SQL-clauses, like this:
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE [TDestinationType].[tPreTravelDestinationCity] = " & q(escapeSQL(Me.txtDestinationCity))
Lastly, breakt it for readability. I doubt your editor shows 200 characters wide:
Me.txtDestinationState.RowSource = _
"SELECT tPreTravelDestinationState " & _
"FROM [TDestinationType] " & _
"WHERE [TDestinationType].[tPreTravelDestinationCity] = " & q(escapeSQL(Me.txtDestinationCity))
Note the trailing spaces in each line! Without them, the concatenation will not work.
It can be easier to troubleshoot your query construction if you set it to a variable (e.g., strSQL) first. Then you can put a breakpoint and see it right before it executes.
You need a space after WHERE. Change WHERE" to WHERE<space>"
Me.txtDestinationState.RowSource = "SELECT tPreTravelDestinationState FROM [TDestinationType] WHERE " & Me.txtDestinationCity & "= [TDestinationType].[tPreTravelDestinationCity]"

Incorrect syntax near 's'. Unclosed quotation mark after the character string

I'm using a query to pull data from an SQL database, at times the last dropdown im using to get the record i'm looking for has a single quote, when it does I get the following error: Incorrect syntax near 's'. Unclosed quotation mark after the character string
This is the code I have:
Using objcommand As New SqlCommand("", G3SqlConnection)
Dim DS01 As String = DDLDS01.SelectedItem.Text
Dim State As String = DDLState.SelectedItem.Text
Dim Council As String = DDLCouncil.SelectedItem.Text
Dim Local As String = DDLLocal.SelectedItem.Text
Dim objParam As SqlParameter
Dim objDataReader As SqlDataReader
Dim strSelect As String = "SELECT * " & _
"FROM ConstitutionsDAT " & _
"WHERE DS01 = '" & DS01 & "' AND STATE = '" & State & "' AND COUNCIL = '" & Council & "' AND LOCAL = '" & Local & "' AND JURISDICTION = '" & DDLJurisdiction.SelectedItem.Text & "' "
strSelect.ToString.Replace("'", "''")
objcommand.CommandType = CommandType.Text
objcommand.CommandText = strSelect
Try
objDataReader = objcommand.ExecuteReader
DDLJurisdiction.Items.Add("")
While objDataReader.Read()
If Not IsDBNull(objDataReader("SUBUNIT")) Then
txtSubUnit.Text = (objDataReader("SUBUNIT"))
End If
If Not IsDBNull(objDataReader("DS02")) Then
lblDS02.Text = (objDataReader("DS02"))
End If
If Not IsDBNull(objDataReader("LEGISLATIVE_DISTRICT")) Then
txtALD.Text = (objDataReader("LEGISLATIVE_DISTRICT"))
End If
If Not IsDBNull(objDataReader("REGION")) Then
txtRegion.Text = (objDataReader("REGION"))
End If
If DDLState.SelectedItem.Text <> "OTHER" Then
If Not IsDBNull(objDataReader("UNIT_CODE")) Then
txtUnitCode.Text = (objDataReader("UNIT_CODE"))
End If
End If
End While
objDataReader.Close()
Catch objError As Exception
OutError.Text = "Error: " & objError.Message & objError.Source
Exit Sub
End Try
End Using
Not all records contain a single quote, only some, so i'd need something that would work if a single quote is present or not.
Thanks.
Your problem is this line here:
strSelect.ToString.Replace("'", "''")
This is changing your WHERE clause from something like
WHERE DS01 = 'asdf' AND ...
To:
WHERE DS01 = ''asdf'' AND ...
You need to do the replace on the individual values in the where clause, not on the whole select statement.
What you should really be doing is using a parameterized query instead.
Update: added same link as aquinas because it's a good link
Use parameterized queries, and only EVER use parameterized queries. See: How do I create a parameterized SQL query? Why Should I?

Query will not run with variables, will work when variable's definitions are pasted in

This is a Query in VBA (Access 2007)
I have 3 strings defined:
str_a = "db.col1 = 5"
str_b = " and db.col2 = 123"
str_c = " and db.col3 = 42"
Then I use these in the WHERE part of my Query:
"WHERE '" & str_a & "' '" & str_b & "' '" & str_c & "' ;"
This fails, but If I paste in the strings like this:
"WHERE db.col1 = 5 and db.col2 = 123 and db.col3 = 42;"
It works perfectly. I'm guessing the syntax is wrong when using multiple variables in a string.
Anyone have any hints?
"WHERE '" & str_a & "' '" & str_b & "' '" & str_c & "' ;"
will include single quotes within your completed WHERE clause. And the working version you showed us has none:
"WHERE db.col1 = 5 and db.col2 = 123 and db.col3 = 42;"
So, try constructing the WHERE clause with no single quotes:
"WHERE " & str_a & " " & str_b & " " & str_c & ";"
For debugging purposes, it's useful to view the final string after VBA has finished constructing it. If you're storing the string in a variable named strSQL, you can use:
Debug.Print strSQL
to display the finished string in the Immediate Window of the VB Editor. (You can get to the Immediate Window with the CTRL+g keyboard shortcut.)
Alternatively, you could display the finished string in a message box window:
MsgBox strSQL
You've got some extra single quotes in there.
Try this:
"WHERE " & str_a & str_b & str_c
Note: In general, you shouldn't build query strings by concatenating strings, because this leaves you vulnerable to SQL injection, and mishandles special characters. A better solution is to use prepared statements. But assuming you're operating in a very controlled environment the solution I gave should work.
Quick tip about troubleshooting SQL that is built dynamically: echo the SQL string resulting from all the concatenation and interpolation, instead of staring at your code.
WHERE 'db.col1 = 5' ' and db.col2 = 123' ' and db.col3 = 42';
Nine times out of ten, the problem becomes a lot more clear.
For VB6/VBA dynamic SQL, I always find it more readable to create an SQL template, and then use the Replace() function to add in the dynamic parts. Try this out:
Dim sql As String
Dim condition1 As String
Dim condition2 As String
Dim condition3 As String
sql = "SELECT db.col1, db.col2, db.col3 FROM db WHERE <condition1> AND <condition2> AND <condition3>;"
condition1 = "db.col1 = 5"
condition2 = "db.col2 = 123"
condition3 = "db.col3 = 'ABCXYZ'"
sql = Replace(sql, "<condition1>", condition1)
sql = Replace(sql, "<condition2>", condition2)
sql = Replace(sql, "<condition3>", condition3)
However, in this case, the values in the WHERE clause would change, not the fields themselves, so you could rewrite this as:
Dim sql As String
sql = "SELECT col1, col2, col3 FROM db "
sql = sql & "WHERE col1 = <condition1> AND col2 = <condition2> AND col3 = '<condition3>';"
sql = Replace(sql, "<condition1>", txtCol1.Text)
sql = Replace(sql, "<condition2>", txtCol2.Text)
sql = Replace(sql, "<condition3>", txtCol3.Text)
Some comments on constructing WHERE clauses in VBA.
Your example is by definition going to be incorrect, because you're putting single quotes where they aren't needed. This:
str_a = "db.col1 = 5"
str_b = " and db.col2 = 123"
str_c = " and db.col3 = 42"
"WHERE '" & str_a & "' '" & str_b & "' '" & str_c & "' ;"
...will produce this result:
WHERE 'db.col1 = 5' ' and db.col2 = 123' ' and db.col3 = 42' ;
This is obviously not going to work.
Take the single quotes out and it should work.
Now, that said, I'd never do it that way. I'd never put the AND in the substrings that are used to construct the WHERE clause, because what would I do if I have a value for the second string but not for the first?
When you have to concatenate a number of strings with a delimiter and some can be unassigned, one thing to do is to just concatenate them all and not worry if the string before the concatenation is unassigned of not:
str_a = "db.col1 = 5"
str_b = "db.col2 = 123"
str_c = "db.col3 = 42"
To concatenate that, you'd do:
If Len(str_a) > 0 Then
strWhere = strWhere & " AND " str_a
End If
If Len(str_b) > 0 Then
strWhere = strWhere & " AND " str_b
End If
If Len(str_c) > 0 Then
strWhere = strWhere & " AND " str_c
End If
When all three strings are assigned, that would give you:
" AND db.col1 = 5 AND db.col2 = 123 AND db.col3 = 42"
Just use Mid() to chop of the first 5 characters and it will always come out correct, regardless of which of the variables have values assigned:
strWhere = Mid(strWhere, 6)
If none of them are assigned, you'll get a zero-length string, which is what you want. If any one of them is assigned, you'll first get " AND ...", which is an erroneous leading operator, which you just chop out with the Mid() command. This works because you know that all the results before the Mid() will start with " AND " no matter what -- no needless tests for whether or not strWhere already has been assigned a value -- just stick the AND in there and chop it off at the end.
On another note, someone mentioned SQL injection. In regards to Access, there was a lengthy discussion of that which considers a lot of issues close to this thread:
Non-Web SQL Injection
I have my favorite "addANDclause" function, with the following parameters:
public addANDclause( _
m_originalQuery as string, _
m_newClause as string) _
as string
if m_originalQuery doe not contains the WHERE keyword then addANDClause() will return the original query with a " WHERE " added to it.
if m_orginalQuery already contains the WHERE keyword then addANDClause() will return the original query with a " AND " added to it.
So I can add as many "AND" clauses as possible. With your example, I would write the following to create my SQL query on the fly:
m_SQLquery = "SELECT db.* FROM db"
m_SQLquery = addANDClause(m_SQLQuery, "db.col1 = 5")
m_SQLQuery = addANDClause(m_SQLQuery, "db.col2 = 123")
m_SQLQuery = addANDClause(m_SQLQuery, "db.col3 = 42")
Of course, instead of these fixed values, such a function can pick up values available in bound or unbound form controls to build recordset filters on the fly. It is also possible to send parameters such as:
m_SQLQuery = addANDClause(m_SQLQuery, "db.text1 like 'abc*'")
While dynamic SQL can be more efficient for the engine, some of the comments here seem to endorse my view that dynamic SQL can be confusing to the human reader, especially when they didn't write the code (think of the person who will inherit your code).
I prefer static SQL in a PROCEDURE and make the call to the proc dynamic at runtime by choosing appropriate values; if you use SQL DDL (example below) to define the proc you can specify DEFAULT values (e.g. NULL) for the parameters so the caller can simply omit the ones that are not needed e.g. see if you can follow the logic in this proc:
CREATE PROCEDURE MyProc
(
arg_col1 INTEGER = NULL,
arg_col2 INTEGER = NULL,
arg_col3 INTEGER = NULL
)
AS
SELECT col1, col2, col3
FROM db
WHERE col1 = IIF(arg_col1 IS NULL, col1, arg_col1)
AND col2 = IIF(arg_col2 IS NULL, col2, arg_col2)
AND col3 = IIF(arg_col3 IS NULL, col3, arg_col3);
Sure, it may not yield the best execution plan but IMO you have to balance optimization against good design principles (and it runs really quick on my machine :)