Good evening,
I've been working at this all day today to no avail. I'm using the code below to take user input in a textbox and search through the database (as the user types) and present the results in a ListView control. It works as-is, but I know it's insecure because it's not parametized. I know how to add the parameter to the MySQLCommand object but can't figure out how to add it to the query. Any help would be greatly appreciated, thanks.
HERE'S MY CODE:
Private Sub TextBoxSearch_TextChanged(sender As Object, e As System.EventArgs) Handles TextBoxSearch.TextChanged
Dim dbConn As New MySqlConnection(String.Format("Server={0};Port={1};Uid={2};Password={3};Database=accounting", FormLogin.ComboBoxServerIP.SelectedItem, My.Settings.DB_Port, My.Settings.DB_UserID, My.Settings.DB_Password))
Dim dbQuery As String = ""
Dim dbCmd As New MySqlCommand
Dim dbReader As MySqlDataReader
Dim a, b, c, d, f, g
Try
dbQuery = "SELECT * FROM cc_master INNER JOIN customer ON customer.accountNumber = cc_master.customer_accountNumber " & _
"WHERE nameCOMPANY OR accountNumber LIKE '%" & TextBoxSearch.Text & "%' " & _
"ORDER BY nameCOMPANY ASC"
dbConn.Open()
dbCmd = New MySqlCommand(dbQuery, dbConn)
dbReader = dbCmd.ExecuteReader()
ListViewRecords.Items.Clear()
Do While dbReader.Read()
a = (dbReader.Item("ccID").ToString())
b = (dbReader.Item("accountNumber").ToString())
c = (dbReader.Item("nameCOMPANY").ToString())
d = DecryptCard(dbReader.Item("ccNumber").ToString())
f = (dbReader.Item("ccExpireMonth").ToString())
g = (dbReader.Item("ccExpireYear").ToString())
Dim item As ListViewItem = ListViewRecords.Items.Add(a)
item.SubItems.Add(b)
item.SubItems.Add(c)
item.SubItems.Add(d)
item.SubItems.Add(f)
item.SubItems.Add(g)
Loop
dbReader.Close()
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
dbConn.Close()
dbCmd.Dispose()
End Sub
I'm assuming your issue is the wildcards not working correctly. This does not work as the parameter cannot be enclosed in quotes.
dbQuery = "SELECT * FROM cc_master INNER JOIN customer ON customer.accountNumber = cc_master.customer_accountNumber " & _
"WHERE nameCOMPANY OR accountNumber LIKE '%?ParameterName%' " & _
"ORDER BY nameCOMPANY ASC"
To fix, you can concat the wildcards into your parameter first and then insert it into your query.
Dim parameter = "%" & TextBoxSearch.Text & "%"
dbQuery = "SELECT * FROM cc_master INNER JOIN customer ON customer.accountNumber = cc_master.customer_accountNumber " & _
"WHERE nameCOMPANY OR accountNumber LIKE ?ParameterName " & _
"ORDER BY nameCOMPANY ASC"
Did you mean something like:
dbQuery = "SELECT * FROM cc_master INNER JOIN customer " & _
"ON customer.accountNumber = cc_master.customer_accountNumber " & _
"WHERE nameCOMPANY OR accountNumber LIKE '%' + ? + '%' " & _
"ORDER BY nameCOMPANY ASC"
dbConn.Open()
dbCmd.Connection = dbConn
dbCmd.CommandType = CommandType.Text
dbCmd.CommandText = dbQuery
dbCmd.Parameters.AddWithValue("?", TextBoxSearch.Text)
dbReader = dbCmd.ExecuteReader()
However, I think you would probably be better with a stored procedure and pass parameters to that http://www.mysqltutorial.org/stored-procedures-parameters.aspx
Related
Below is my code. Can anyone help?
SQL1 runs well but SQL2 Gives me a run time error 3075 (missing operator) in query expression '*StockNo'.
Private Sub DataUpdate()
Dim SQL1 As String
Dim SQL2 As String
SQL1 = "UPDATE tblChemicalStock " & _
"INNER JOIN tblChemicalStock1 " & _
"ON(tblChemicalStock.ChemicalName = tblChemicalStock1.ChemicalName) " & _
"SET tblChemicalStock.Stock1 = tblChemicalStock1.Stock1, " & _
"tblChemicalStock.Stock2 = tblChemicalStock1.Stock2, " & _
"tblChemicalStock.TotalStock = tblChemicalStock1.TotalStock;"
DoCmd.RunSQL SQL1
SQL2 = "INSERT INTO tblChemicalStock ([StockNo],[ChemicalName],[Stock1],
[Stock2],[TotalStock],[CategoryCode])" & _
"SELECT *StockNo,ChemicalName,Stock1,Stock2,TotalStock,CategoryCode FROM tblChemicalStock1 t" & _
"WHERE NOT EXISTS(SELECT 1 FROM tblChemicalStock s" & _
"WHERE t.StockNo = s.StockNo);"
DoCmd.RunSQL SQL2
End Sub
I have 8 combo boxes in an Access database. Each combo box can either have a value or not have a value (2 options). In total, there can be 256 combinations (2^8). I am trying to create some code in VBA that loops through these combinations to determine which combination currently exists, with the ultimate goal of writing an SQL query within VBA based on that combination. So for example, let's say combo1 and combo2 both have selections, but not combo3 through combo8. If that is the combination I would like my SQL query to do a SELECT FROM query WHERE a column in db = combo1 and a column in db = combo2. Can anyone provide hints as to how I would structure my code?
Thanks!
Dim a as string, b as string
const myAND as string = "AND "
a = ""
a = "SELECT * FROM a table "
b = ""
if cbo1.value <> "" then
b = b & myAND & "AND field1 = '" & cbo1.value & "'"
end if
if cbo2.value <> "" then
b = b & myAND & "field2 = '" & cbo2.value & "'"
end if
etc for each cbo box
If b <> "" Then
' Lazy way
' a = a & "WHERE 1=1 " & b
' remove the first AND way
a = a & "WHERE 1=1 " & mid(b,len(myAND))
End if
' a now contains the SQL you need.
Dim where_condtion as String
Dim sqlquery as String
where_condtion = ""
IF combo1 <>"" then
where_condtion = where_condtion + "~fieldname~ = " & combo1
End IF
IF combo2 <>"" then
where_condtion = where_condtion + "AND ~fieldname~ = " & combo2
End IF
*
*
*
IF combo8 <>"" then
where_condtion = where_condtion + "AND ~fieldname~ =" & combo8
End IF
IF where_condtion <> "" then
sqlquery = "Select * from ~table name~ where" + where_condtion
ELSE
sqlquery = "Select * from ~table name~
End IF
sqlquery = Replace(sqlquery, "where AND ", "where ")
DoCmd.OpenQuery "sqlquery", acViewNormal, acEdit
OR
CurrentDb.OpenRecordset("sqlquery")
Am option would be a concatenated string
Code Example
Dim strSQL as String
'basic string
strSQL = "SELECT tbl.fieldA, tbl.fieldB FROM tbl "
Dim strSQLwhere as String
strSQLwhere = ""
'Combobox cmbbox1
If Not isNull(cmbbox1) And cmbbox1.ListIndex <> -1 then
strSQLwhere = strSQLwhere & "tbl.fieldToFilter1=" & cmbbox1
End if
'Combobox cmbbox2
If Not isNull(cmbbox2) And cmbbox2.ListIndex <> -1 then
iF NOT strSQLwhere = "" then
strSQLwhere = strSQLwhere & " AND "
end if
strSQLwhere = strSQLwhere & "tbl.fieldToFilter2=" & cmbbox2
End if
'And so on until cmbBox 8
'Combine all Strings
if not strSQLwhere = "" then
strSQL = strSQL & " WHERE (" & strSQLwhere & ")"
End if
'Add here further thing like ORDER BY, GROUP BY
'Show SQL sting if it is well fomratted, change string concatenation if not
debug.print strSQL
You could do the combobox if-then-(else) cases in a separate function if you are able to do that in VBA.
To give a brief summary of the objective of this macro, I am trying to get the sum of cash between certain dates based on a set of parameters. I keep getting an error in VBA when I try to run a SQL query with a date. I'm not sure what the issue is but I think it's related to how I have the date formatted. I have tried running it multiple ways but keep getting a syntax error, whether it be related to 'a', '#', or 'table'.
Here's the query I'm using. Any help would be greatly appreciated.
Sub GetCashBalance()
Dim cn As New ADODB.Connection
Dim rs As ADODB.Recordset
Dim SQL As String
Dim StartDate As String
Dim EndDate As String
StartDate = InputBox("Enter Start Date in mm/dd/yy format.")
EndDate = InputBox("Enter End Date in mm/dd/yy format.")
SQL = "Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Initial Catalog=master;Data Source=SERVER\ODS"
Set cn = New ADODB.Connection
Set rs = New ADODB.Recordset
cn.Open SQL
Set rs = cn.Execute("SELECT SUM(a.CASH)" & _
"FROM CUSTOMER_DATA.dbo.TRANSACTION_HISTORY a" & _
"LEFT JOIN CUSTOMER_DATA.dbo.DAILY_TRANSACTION b" & _
"ON a.T01_KEY = b.T01_KEY" & _
"WHERE PROC_DATE BETWEEN #StartDate# AND #EndDate#" & _
"AND a.CODE NOT IN ('22','23','M','2-L','36-R')" & _
"AND isnull(a.DESCRIPTION, '') NOT IN ('01','02','03','0DO1','0NF2');")
If Not rs.EOF Then
Sheets(7).Range("A40").CopyFromRecordset rs
rs.Close
Else
MsgBox "Error", vbCritical
End If
cn.Close
End Sub
Set rs = cn.Execute("SELECT SUM(a.CASH)" & _
"FROM CUSTOMER_DATA.dbo.TRANSACTION_HISTORY a" & _
"LEFT JOIN CUSTOMER_DATA.dbo.DAILY_TRANSACTION b" & _
"ON a.T01_KEY = b.T01_KEY" & _
"WHERE PROC_DATE BETWEEN '" & StartDate & "' AND '" & EndDate & _
"# AND a.CODE NOT IN ('22','23','M','2-L','36-R')" & _
"AND isnull(a.DESCRIPTION, '') NOT IN ('01','02','03','0DO1','0NF2');")
Take a look at below piece, that should be changed
BETWEEN '" & StartDate & "' AND '" & EndDate & _
"' AND ....
I think it is better to use ADODB.Command and Parameters instead of doing a concatenation in the sql query.
Hey guys I have to extract some values from my DB and put them on my textbox. There's a problem at :
TextBox1.Text = TextBox1.Text & DR.Item("id") & Space(3) & DR.Item("Nume") & Space(3) & DR.Item("COUNT(pontaj.prezente)")
Error in VB:
This is how my select looks like:
Dim dbCon = New MySqlConnection("Server = localhost;Database = users; Uid=root; Pwd = password ")
'SELECT users1.id,users1.Nume, COUNT(pontaj.prezente) FROM users1, pontaj WHERE users1.id = pontaj.id
Dim strQuery = "SELECT users1.id,users1.Nume, COUNT(pontaj.prezente)" & _
"FROM users1, pontaj "
Dim SQLCmd = New MySqlCommand(strQuery, dbCon)
' Pwd = password
' Open
dbCon.Open()
Dim DR = SQLCmd.ExecuteReader
TextBox1.Text = TextBox1.Text & DR.Item("id") & Space(3) & DR.Item("Nume") & Space(3) & DR.Item("COUNT(pontaj.prezente)") & vbCrlf
While DR.Read
End While
'Close
DR.Close()
dbCon.Close()
Well, the error is clear, you cannot access the fields of a DataReader before calling Read.
The call is required to position the reader on the first record returned by the query and then to advance on the subsequent records until you reach the end of the returned records.
Also the syntax for your query seems incorrect and the way you reference the third column of your query
Dim dbCon = New MySqlConnection(............)
Dim strQuery = "SELECT users1.id,users1.Nume, COUNT(pontaj.prezente) as countPrezente " & _
"FROM users1 INNER JOIN pontaj ON users1.id = pontaj.id " & _
"GROUP BY users1.id, users1.Nume"
Dim SQLCmd = New MySqlCommand(strQuery, dbCon)
dbCon.Open()
Dim DR = SQLCmd.ExecuteReader
' If Read returns true then you have one or more record to show'
While DR.Read()
TextBox1.Text = TextBox1.Text & _
DR.Item("id") & Space(3) & _
DR.Item("Nume") & Space(3) & _
DR.Item("countPrezente") & vbCrlf
End While
DR.Close
dbCon.Close
Looking at your previous question, the Foreign Key between users1 and pontaj is named id, so I have used an explicit join between the two tables to link the records from the two tables
I am a beginner with VBA. I managed to run mySQL query in VBA which works but I get the same number in all my excel column results. I am not sure what I should change in my code for distinct results to show. Can anybody help me out?
strSql = "SELECT COUNT(*), destination_id FROM `order` " & _
"JOIN user ON user.id = order.destination_id " & _
"WHERE payment_status = 'pay' " & _
"AND email NOT LIKE '%#thelts.com' " & _
"AND email NOT LIKE '%trend.com' " & _
"AND `is_dinstinct` IS NULL; "
rs.Open strSql, oConn, adOpenDynamic, adLockPessimistic
res = rs.GetRows
rs.Close
Range("A1", "B6") = res(0, 0)
Two things, it looks like you are missing a GROUP BY destination_id in your sql (although thst may be legal in mysql, im a sql server dude) but I believe your real problem is in the line...
Range("A1", "B6") = res(0, 0)
What you are saying here is put the result at position 0, 0 in each cell of the range.
You could try
Range("a1") = res(0, 0)
Range("b6") = res(0, 1)
CopyFromRecordsetis the method I (& #TimWilliams) use to write a result to a range - You may find it a little more helpful than loading into an array first
An example from the excel help:
For iCols = 0 to rs.Fields.Count - 1
ws.Cells(1, iCols + 1).Value = rs.Fields(iCols).Name
Next
ws.Range(ws.Cells(1, 1), ws.Cells(1, rs.Fields.Count)).Font.Bold = True
ws.Range("A2").CopyFromRecordset rs
placing this method in your code,
strSql = "SELECT COUNT(*), destination_id FROM `order` " & _
"JOIN user ON user.id = order.destination_id " & _
"WHERE payment_status = 'pay' " & _
"AND email NOT LIKE '%#thelts.com' " & _
"AND email NOT LIKE '%trend.com' " & _
"AND `is_dinstinct` IS NULL; "
rs.Open strSql, oConn, adOpenDynamic, adLockPessimistic
Range("A1").CopyFromRecordset rs