I'm trying to query my database based on the current user and the current date. I currently am getting no results from my query and I think the problem is with my formatting of the current date in vb.net. The query as is
query = "SELECT movie_name from movie2 Where movie_id=(SELECT movie_id from rental where client_username='" & currentUser & "' AND start_date<='" & Format(Now, "yyyy-MM-dd") & "' AND return_date>='" & Format(Now, "yyyy-MM-dd") & "')"
I know the rest of the query works (except calling the currentUser) as I have tested it on the mySql server. I have called currentUser before, which is saved through a variable in a module, without any hassle so I feel the problem has to be with my dates.
I don't know how to format the current date so mySql will receive it properly?
I have also tried the code
query = "SELECT movie_name from movie2 Where movie_id=(SELECT movie_id from rental where client_username='" & currentUser & "' AND start_date<='" & DateTime.Now.ToString("yyyy-MM-dd") & "' AND return_date>='" & DateTime.Now.ToString("yyyy-MM-dd") & "')"
with no success. Any help would be greatly appreciated!
Thanks, Alan.
The problem is the usual bad practice to use string concatenation when building sql command.
And the remedy is always the same. A parameterized query.
query = "SELECT movie_name from movie2 Where movie_id=" & _
"(SELECT movie_id from rental where client_username=#name" &_
" AND start_date<=#date AND return_date>=#date"
Using cmd = new MySqlCommand(query, connection)
cmd.Parameters.Add("#name", MySqlDbType.VarChar).Value = currentUser
cmd.Parameters.Add("#date", MySqlDbType.DateTime).Value = DateTime.Now
Using reader = cmd.ExecuteReader()
.... now read your data ....
End Using
End Using
With string concatenation you are vulnerable to Sql Injection and when forcing the conversion of decimals or date to a string you are an easy victim of wrong conversions. Parameters avoid all of that
EDIT: With an MySqlDataAdapter
query = "SELECT movie_name from movie2 Where movie_id=" & _
"(SELECT movie_id from rental where client_username=#name" &_
" AND start_date<=#date AND return_date>=#date"
Using cmd = new MySqlCommand(query, connection)
cmd.Parameters.Add("#name", MySqlDbType.VarChar).Value = currentUser
cmd.Parameters.Add("#date", MySqlDbType.DateTime).Value = DateTime.Now
Using adapter = new MySqlDataAdapter(cmd)
Dim dt = new DataTable()
adapter.Fill(dt)
End Using
End Using
Related
(1) Table DB-Fiddle
CREATE TABLE logistics (
id int primary key,
Product VARCHAR(255),
insert_timestamp Date
);
INSERT INTO logistics
(id, product, insert_timestamp
)
VALUES
("1", "Product_A", "2020-02-24 18:15:48"),
("2", "Product_B", "2020-02-24 20:30:17"),
("3", "Product_C", "2020-02-24 23:54:58"),
("4", "Product_D", "2020-02-25 08:09:30"),
("5", "Product_E", "2020-02-25 10:17:15");
(2) VBA
Value in Cell B1 = 2020-02-24
Sub Get_Data()
Dim conn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim dateVar As Date
Set conn = New ADODB.Connection
conn.ConnectionString = "DRIVER={MySQL ODBC 5.1 Driver}; SERVER=localhost; DATABASE=bi; UID=username; PWD=password; OPTION=3"
conn.Open
strSQL = " SELECT " & _
" cID " & _
" FROM logistics " & _
" WHERE DATE(insert_timestamp) BETWEEN """ & Format(Sheet1.Range("B1").Value, "YYYY-MM-DD") & "00:00:00" & """ " & _
" AND """ & Format(Sheet1.Range("B1").Value, "YYYY-MM-DD") & "23:59:59" & """ " & _
" GROUP BY 1 "
Set rs = New ADODB.Recordset
rs.Open strSQL, conn, adOpenStatic
Sheet1.Range("A1").CopyFromRecordset rs
rs.Close
conn.Close
End Sub
I want to run a query within the VBA that uses the date in Cell B1 within the BETWEEN statement in the WHERE clause.
When I run this query outside of the VBA it works perfectly:
SELECT
Product
FROM logistics
WHERE DATE(insert_timestamp) BETWEEN "2020-02-24 00:00:00" AND "2020-02-24 23:59:59";
Once, I run it in the VBA it does not give me an error but it also does not give me any result.
I assume the issue is caused by my combination of the sql and the VBA in the strSQL.
How do I have to change the VBA to make it work?
Instead of formatting values like dates or strings into the SQL command, it is much better to use ADODB.Parameter - in that case the driver will do all the work for you. You don't have to take care about quotes around a string, formatting a date so that the database understands it correctly (which is highly depending on database, regional settings and so on). Plus it is a protection against SQL injection. Plus, the query optimizer can do it's job much better because it gets the same SQL command every time and remembers the execution plan.
Drawback: code get's slightly more complicated because you have to involve a ADODB.command object.
In your SQL statement, you put a simple ? at the place where you want to have a parameter. You just have to take care that the numbers and the position of ? and parameters matches.
Dim Conn As New ADODB.Connection, cmd As New ADODB.Command, param As ADODB.Parameter, rs As ADODB.Recordset
Conn.Open "<your connection string>"
Set cmd.ActiveConnection = Conn
cmd.CommandText = "SELECT cID FROM logistics WHERE DATE(insert_timestamp) BETWEEN ? AND ? GROUP BY 1"
Set param = cmd.CreateParameter(, adDate, adParamInput, , Date)
cmd.Parameters.Append param
Set param = cmd.CreateParameter(, adDate, adParamInput, , Date + 1)
cmd.Parameters.Append param
Set rs = cmd.Execute
Debug.Print rs.Fields(0).Name, rs(0).Value
P.S. Was a little lazy for the date handling, if you have data exactly at midnight, you would get too much data.
you are missing a space between the date and the time...
Open your VBE and debug print the formula to see the result (maker sure you have the immediate window [view menu / Immediate window).
Sub test()
Debug.Print Format(Sheet1.Range("B1").Value, "YYYY-MM-DD") & "23:59:59"
End Sub
result
2020-03-1123:59:59
Just can add the space after the DD as follow
Format(Sheet1.Range("B1").Value, "YYYY-MM-DD ") & "23:59:59"
I know you've accepted an answer and it's a perfectly good one. I'm just leaving this here as an alternative method which you might find useful in other cases too:
Dim date_to_use As String
date_to_use = Format(Sheet1.Range("B1").Value, "YYYY-MM-DD")
strSQl = " SELECT " & _
" cID " & _
" FROM logistics " & _
" WHERE DATE(insert_timestamp) BETWEEN '[date to use] 00:00:00'" & _
" AND '[date to use] 23:59:59'" & _
" GROUP BY 1 "
strSQl = Replace(strSQl, "[date to use]", date_to_use)
Storing the contents of B1 in this way before using it also allows you to apply other changes to it - just in case you wanted to clean it up further or reduce the chances of SQL injection being used..
I have created a database within Microsoft access and with it a form.
I have a button attached to the form and when it's clicked I want to insert a new record into the table customerHeader.
There are four fields within that table one being an autonumber. In my SQL statement, I don't include the orderNumber since it is an autofield.
When I try to click the button and the on click event is executed, I get an error saying that Microsoft Access cannot append the records in the append query.
Any ideas, I have looked everywhere and I have not been able to find the solution.
Private Sub addOrder_Click()
Dim mySql As String
Dim rowNum As Integer
Dim recCount As Long
Dim orderNumber As Long
Dim myBool As Boolean
Dim todayDate As Date
todayDate = CDate(Date)
myBool = False
MsgBox todayDate
rowNum = Form.CurrentRecord
rowNum = CInt(rowNum - 1)
'DoCmd.GoToRecord , , acNewRec
mySql = "INSERT INTO orderHeader (orderDate,custNumber,printed) VALUES (" & todayDate & "," & rowNum & "," & myBool & ")"
DoCmd.RunSQL mySql
Me!orderNum.Requery
You don't have to much around - just use the ISO sequence for the format of the string expression for the date value:
mySql = "INSERT INTO orderHeader (orderDate,custNumber,printed) VALUES (#" & Format(todayDate, "yyyy\/mm\/dd") & "#," & rowNum & "," & myBool & ")"
However, it it's today, simply use:
mySql = "INSERT INTO orderHeader (orderDate,custNumber,printed) VALUES (Date()," & rowNum & "," & myBool & ")"
So here is my code below.
qry = "SELECT * FROM `tblsubjects` WHERE `GRADELEVEL` = " & lblgrade.Text & " AND `SUBJECTNAME` <> (SELECT `SUBJECTNAME` FROM `tblschedule` WHERE `SECTIONNAME` = '" & lblsect.Text & "')"
it came from may vb application. I think the error came from the query. t I'm making a scheduling system. On that query, i was trying to load the subjects that has not been scheduled on that gradelevel and section on to combo box. but that error comes out when i try to add more schedule on this section.
enter image description here
Here is my whole code on this function:
Private Sub subjectload()
con = New MySqlConnection
con.ConnectionString = "server=localhost;user id=root;password='';database=kccbeslis"
If DataGridView.Rows.Count > 0 Then
Try
con.Open()
qry = "SELECT * FROM `tblsubjects` WHERE `GRADELEVEL` = " & lblgrade.Text & " AND `SUBJECTNAME` <> (SELECT `SUBJECTNAME` FROM `tblschedule` WHERE `SECTIONNAME` = '" & lblsect.Text & "')"
cmd = New MySqlCommand(qry, con)
rdr = cmd.ExecuteReader
While rdr.Read
Dim subname = rdr.GetString("SUBJECTNAME")
cbsubject.Items.Add(subname)
End While
con.Close()
Catch ex As Exception
MessageBox.Show(ErrorToString)
End Try
Else
Try
con.Open()
qry = "SELECT * FROM `tblsubjects` WHERE `GRADELEVEL` = " & lblgrade.Text & ""
cmd = New MySqlCommand(qry, con)
rdr = cmd.ExecuteReader
While rdr.Read
Dim subname = rdr.GetString("SUBJECTNAME")
cbsubject.Items.Add(subname)
End While
con.Close()
Catch ex As Exception
MessageBox.Show(ErrorToString)
End Try
End If
End Sub
help me pls!
Subquery SELECTSUBJECTNAMEFROMtblscheduleWHERESECTIONNAME= '" & lblsect.Text & "' results more than 1 records. You are using <> instead of not in, use Not In clause and try.
It appears your sub select (SELECT subjectname FROM tblscheduler where..) has multiple schedules with the same 'sectionname' you are providing, therefore is returning more than 1 row.
Are you sure your sectionname column is unique per tblschedule entry? Try a count and group by to see if you have multiple records;
SELECT COUNT(*) FROM tblschedule GROUP BY sectionname;
You could try replacing <> with NOT IN if you require multiple rows.
Yes, that's cause your subquery returning more than 1 record and <> operator expects scalar value and list of values. You should rather use NOT IN operator like
AND `SUBJECTNAME` NOT IN (SELECT `SUBJECTNAME` FROM `tblschedule` WHERE `SECTIONNAME` = '" & lblsect.Text & "')
BTW, do you know your posted code is very much vulnerable to SQL Injection. You should consider using parameterized queries to avoid the same.
Use NOT IN instead of <>
qry = "SELECT * FROM tblsubjects WHERE GRADELEVEL = " & lblgrade.Text & " AND SUBJECTNAME NOT IN (SELECT SUBJECTNAME FROM tblschedule WHERE SECTIONNAME = '" & lblsect.Text & "')"
Hello I am using VB6 and mysql and I am facing a problem in searching through dates its not fetching records
Here is my code
Dim GetDateNow As Date
Dim GetDateTen As String
Dim SetDateTen As Date
GetDateNow = Format$(Now, "yyyy-mm-dd")
GetDateTen = Now - 15
SetDateTen = Format$(GetDateTen, "yyyy-mm-dd")
Dim rs As New Recordset
SQL = "SELECT * FROM CreditPayLog WHERE payment_user='" & Label5.Caption & "' AND payment_date BETWEEN '" & Format(SetDateTen, "yyyy-MM-dd") & "' AND '" & Format(GetDateNow, "yyyy-MM-dd") & "'"
Also i have used debug.print function to see the query all looks good but its not fetching data here is the query
SELECT * FROM CreditPayLog WHERE payment_user='1222150322' AND payment_date BETWEEN '2016-04-06' AND '2016-04-21'
payment_date is DATETIME column in mysql
Your sql is creating a text/string value for date... you need to cast as a date. Not sure how in mySQL but in MSSql you would use Convert(datetime, 'yourDateAsString', 103)
I am trying to use a single SQL command to do two selects I want to select related data and insert it in another table from another database, but it isn't working, I am new to this, can someone help me? Thanks in advance.
Try
If CreateAccessDatabase("C:\Users\Utilizador.Utilizador-PC\Documents\Visual Studio 2013\Projects\WindowsApplication1\WindowsApplication1\Doc_Vendas_Cab.mdb") = True Then
MsgBox("Database Created")
Else
MsgBox("Database Creation Failed")
End If
Dim Sql As String = "Select strCodSeccao,strAbrevTpDoc,strCodExercicio,intNumero " & _
"From Mov_Venda_Cab where dtmdata between #d1 and #d2; Union" & _
"Select Mov_Venda_Lin.Strcodartigo" & _
"from Mov_Venda_Lin,Mov_Venda_Cab where Mov_Venda_Cab.intnumero=Mov_Venda_Lin.intnumero;"
Dim data1, data2 As DateTime
data1 = DateTime.Parse(txtData1.Text)
data2 = DateTime.Parse(txtData2.Text)
data2 = data2.AddMinutes(0)
data2 = data2.AddHours(0)
data2 = data2.AddSeconds(0)
data1 = data1.AddMinutes(0)
data1 = data1.AddHours(0)
data1 = data1.AddSeconds(0)
Dim x As Integer = 0
Dim temp1, temp2, temp3, temp4, temp5 As String
Using con = New SqlConnection("Data Source=" & txtserv.Text & ";" & "Initial Catalog=" & txtBD.Text & ";" & "User ID=" & txtuser.Text & ";" & "Password=" & txtPass.Text & "")
Using cmd = New SqlCommand(Sql, con)
con.Open()
cmd.Parameters.AddWithValue("#d1", data1)
cmd.Parameters.AddWithValue("#d2", data2)
Using reader = cmd.ExecuteReader()
While reader.Read()
Dim strCodSeccao = reader("strCodSeccao").ToString()
temp1 = reader.Item(x)
temp2 = reader.Item(x + 1)
temp3 = reader.Item(x + 2)
temp4 = reader.Item(x + 3)
temp5 = reader.Item(x + 4)
Dim Con2 As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Users\Utilizador.Utilizador-PC\Documents\Visual Studio 2013\Projects\WindowsApplication1\WindowsApplication1\Doc_Vendas_Cab.mdb;Persist Security Info=True")
Con2.Open()
Dim Ole2 As String = "Insert into Mov_Venda_Cab values('" & temp1 & "','" & temp2 & "','" & temp3 & "','" & temp4 & "','" & temp5 & "');"
Dim OledbCom2 As New OleDb.OleDbCommand(Ole2, Con2)
Try
OledbCom2.ExecuteNonQuery()
Catch Ex As Exception
MsgBox(Ex)
End Try
Con2.Close()
End While
End Using
End Using
End Using
Catch Ex As Exception
MsgBox(Ex)
End Try
Your INSERT statement encloses all the values in single quotes. This will only work if the corresponding columns are all text columns (varchar, nvarchar etc.). Use command parameters instead:
Dim Ole2 As String = "Insert into Mov_Venda_Cab values(#p1, #p2, #p3, #p4, #p5);"
Dim OledbCom2 As New OleDb.OleDbCommand(Ole2, Con2)
OledbCom2.Parameters.AddWithValue("#p1", temp1)
OledbCom2.Parameters.AddWithValue("#p2", temp2)
OledbCom2.Parameters.AddWithValue("#p3", temp3)
OledbCom2.Parameters.AddWithValue("#p4", temp4)
OledbCom2.Parameters.AddWithValue("#p5", temp5)
This will work for any column type.
Also your SELECT statement lists only four columns, but you are accessing five columns in the reader.
SELECT strCodSeccao, strAbrevTpDoc, strCodExercicio, intNumero FROM ...
Other things in your code are strange as well. Your are defining two connections that are never used later.
You are adding zero hours, minutes and seconds to a date (this will not change the date). If you want the date part of the date without the time part, use the Date property instead, which returns the date component of the DateTime structure:
data1 = DateTime.Parse(txtData1.Text).Date
You are using a variable x for constant values.
You are opening and closing Con2 in the While-loop. Open it before the loop and close it after the loop. (You can do it with a Using-statement as for the other connection.)