Problem using where with date in SQL Statement - sql

I am trying to execute an SQL statement in a VBA script. I have gotten the script to run, but it ignores the where with a date filter.
I have researched and tried every option I can find, but just cant seem to get it to work.
Set rs = conn.Execute("Select [adjustment_number], [status], [tax_adjusted],[amount], [gl_date],[creation_date],[apply_date],[comments],[type],[adjustment_type],[dbo].[Code_Combinations].[segment1], [dbo].[Code_Combinations].[segment10],[dbo].[Code_Combinations].[segment11],[dbo].[Code_Combinations].[segment12],[dbo].[Code_Combinations].[code_combination] FROM [dbo].[AR_ADJUSTMENTS_ALL] " & _
"left outer join [dbo].[Code_Combinations] on [dbo].[AR_ADJUSTMENTS_ALL].[CODE_COMBINATION_ID] = [dbo].[Code_Combinations].[CODE_COMBINATION_ID] where [gl_date] >= " & gldate & ";")

(Copying this from my comment above, into an answer, since this solved your problem)
SQL Server? Put single quotes around your date in the WHERE clause.
where [gl_date] >= '" & gldate & "';"
Assumes that gldate is a valid date, and [gl_date] is of a date datatype.

Related

Access VBA SQL query searching between dates

I have a some VBA code that takes in a date from and date to fields from two date picker values in textboxes.
However, when searching between the two dates I receive the 'Enter Parameter Value' prompt asking for input.
Dim SQLAllReject As String
Dim strDateFrom As String
Dim strDateTo As String
strDateFrom = Format(txtDate.Value, "mm/dd/yyyy")
strDateTo = Format(txtDateTo.Value, "mm/dd/yyyy")
When running directly in the Query Design wizard, searching between dates works fine:
WHERE (((XXXXXXXXXXXXXXXXXXXX.Date) Between #10/1/2021# And #10/27/2021#))
What is wrong here? How can I force Access/VBA to take the dates I've specified and search between them and NOT display the 'Enter Parameter Value' prompt?
When I debug the query and step through, it gives exactly the same dates as running it in Query Design view.
FYI if I use one date and the LIKE operator, this works fine.
SQLAllReject = "SELECT dbo_vw_busobj_file_rejections_load_access_temp5_copy.HashKey AS [ID], dbo_vw_busobj_file_rejections_load_access_temp5_copy.Reject_Date AS [Date], " & _
"FROM dbo_vw_busobj_file_rejections_load_access_temp5_copy " & _
"WHERE (((dbo_busobj_file_rejections_load_access_temp5_copy.Reject_Date) Between #" & strDateFrom & "# And #" & strDateTo & "#)) " & _
"ORDER BY dbo_vw_busobj_file_rejections_load_access_temp5_copy.Reject_Date DESC;"
Ok I somehow fixed it... the query string was trying to select from a view rather than the table and for some odd reason it was causing the parameter prompt.
I have changed dbo_vw_busobj_file_rejections_load_access_temp5_copy to dbo_busobj_file_rejections_load_access_temp5_copy table and managed to get it to work after doing some string to date conversion when selecting dates from the textboxes.

Why doesn't this WHERE clause return the right datums?

I'm trying to query a .mdb database, and this is part of the SQL in VB.Net:
sql = sql + "WHERE datdatum BETWEEN #" & "15-10-2018" & "# And #" & "31-10-2018" & "#"
The where clause is working the way you assume. At the moment I change the first date from 15-10-2018 to 01-10-2018, it shows all records from Jan-10 instead of Oct-01.
There are two problems here.
First, don't format the dates that way. Dates used for SQL should always use the ISO8601 format. For date-only values with no time component, there are some reasons to prefer the lesser-known unseparated variant of the standard format, but that's still ISO8601. So the date values should look like this:
sql = sql + "WHERE datdatum BETWEEN #" & "20181015" & "# And #" & "20181031" & "#"
or this:
sql = sql + "WHERE datdatum BETWEEN #" & "2018-10-15" & "# And #" & "2018-10-31" & "#"
Anything else is just begging for the kind of problem in your question, where the actual date read from the string varies based on the culture of the person/device making the interpretation.
This fix might seem to work on it's own, but we still need to do more work because of the 2nd issue:
DON'T USE STRING CONCATENATION TO PUT DATA INTO AN SQL QUERY!
You should always build the query more like this:
sql = sql + " WHERE datdatum BETWEEN ? And ?"
Concatenation is okay, as long as no data, such as a date value, is used. Then you populate the values like this (assuming you have an OleDbCommand object named cmd):
cmd.Parameters.Add("?", OleDbType.Date).Value = DateTime.Parse("2018-10-15")
cmd.Parameters.Add("?", OleDbType.Date).Value = DateTime.Parse("2018-10-31")
This completely avoids the formatting issue from the question, because you're working with .Net DateTime values. It can sometimes run faster (though it may not matter for Access). And it protects against SQL injection issues, both malicious and benign. IMO anything else is amateurish and borders on professional malpractice.

MS Access SQL query within VBA code

I need a second set of eyes on this SQL query embedded in the VBA code. I'm making an MS Access app that returns a dataset based on the to & from date criteria set by the user in the specific date picker boxes. The sql query that you see actually has been tested statically within MS Access query design view. I tested it with actual dates where you see the Me.from_filter and Me.to_filter. It worked perfectly! If you chose something like from 1/1/2015 to 5/1/2015 it returns columns of all the months you need. Perfect. Now when I embed it in the VBA code and assign it to a control variable, I get the "Run-time error '2342': A RunSQL action requires an argument consisting of an SQL statement." Can someone please eyeball this and tell me what might be wrong?
Option Compare Database
Option Explicit
Dim strSQL As String
Private Sub Command0_Click()
If IsNull(Me.from_filter) Or IsNull(Me.to_filter) Then
MsgBox "You have not entered a start date or end date"
Else
strSQL = "TRANSFORM Sum(dbo_ASSET_HISTORY.MARKET_VALUE) AS SumOfMARKET_VALUE " _
& "SELECT [dbo_FIRM]![NAME] AS [FIRM NAME], dbo_FUND.CUSIP, dbo_FUND.FUND_NAME, dbo_FUND.PRODUCT_NAME " _
& "FROM (dbo_ASSET_HISTORY INNER JOIN dbo_FIRM ON dbo_ASSET_HISTORY.FIRM_ID = dbo_FIRM.FIRM_ID) INNER JOIN dbo_FUND ON dbo_ASSET_HISTORY.FUND = dbo_FUND.FUND " _
& "WHERE (((dbo_FIRM.Name) Like 'Voya F*') And ((dbo_ASSET_HISTORY.PROCESS_DATE) >= #" & Me.from_filter & "# And (dbo_ASSET_HISTORY.PROCESS_DATE) <= #" & Me.to_filter & "#)) " _
& "GROUP BY [dbo_FIRM]![NAME], dbo_FUND.CUSIP, dbo_FUND.FUND_NAME, dbo_FUND.PRODUCT_NAME " _
& "PIVOT [dbo_ASSET_HISTORY]![ASSET_YEAR] & '-' & [dbo_ASSET_HISTORY]![ASSET_MONTH];"
DoCmd.RunSQL (strSQL)
End If
End Sub
RunSQL is for running action queries like update, insert, select into, delete, etc as per Microsoft definition https://msdn.microsoft.com/en-us/library/office/ff194626.aspx , you should probably use OpenQuery or similar to run your query.

Microsoft Query in Excel VBA - how to pass date filters

I am really hoping someone here could help me with the issue I have spent hours trying to fix with no result.
I am trying to establish a data connection with a csv file using MS query in Excel VBA. I need to filter the data out from the csv file into the spreadsheet by applying a date filter on a certain column. When the date is fixed (i.e. hardcoded in VBA), the connection works absolutely fine. However, I would like the date to be a user input and that's where I am facing problems. Basically, I am not sure how to pass a date variable to the connection.
When the macro works fine, the SQL statement looks like this:
.CommandText = "SELECT * FROM " & csvName & " WHERE SECTYPE='GS' AND LAST TRADED DATE={ts '2016-01-29 00:00:00'}"
When I try to pass the date via variable sValnDate, I get 'SQL syntax error':
.CommandText = "SELECT * FROM " & csvName & " WHERE SECTYPE='GS' AND LAST TRADED DATE={ts " & sValnDate & "}"
I have tried several configurations of the variable. I have tried to pass it as a date, a string exactly as in the correct command, a date formatted as required in the correct command, keeping and removing the curly brackets with each format of the variable etc, but nothing worked.
I have just presented here 1 statement to keep things simple. However, if you need to see the entire block (not more than 15-20 lines), please let me know.
Thanks in advance
PS: just looked at the preview. Somehow `` around LAST TRADED DATE have been removed here.
Assuming that sValnDate is a string that looks like 2016-01-29 00:00:00 then you are simply missing the ticks (aka single quotes or Chr(39)).
.CommandText = "SELECT * FROM " & csvName & _
" WHERE [SECTYPE]='GS' AND [LAST TRADED DATE]={ts '" & sValnDate & "'}"
If sValnDate is an actual date then format it like,
.CommandText = "SELECT * FROM " & csvName & _
" WHERE [SECTYPE]='GS' AND [LAST TRADED DATE]={ts '" & _
Format(sValnDate, "yyyy-mm-dd hh:mm:ss" & "'}"

SQL Filter doesn't work with past year

I got a very strange problem.
When I filter my data in the current year everything is working fine:
But If I try to go back a year, suddenly I get a blank report...
Going to the next year isn't a problem, like you can see here:
My code is:
These 2 values come through as a 'date' in a private sub
datumvan = DateTimePickerVan.Value.ToLocalTime
datumtot = DateTimePickerTot.Value.ToLocalTime
Dim culture As New CultureInfo("pt-BR")
sqlstr = "SELECT * FROM [Geschiedenis$] WHERE Aangemeld BETWEEN '" & datumvan.ToString("d", culture) & "' AND '" & datumtot.ToString("d", culture) & "'"
See also how the sql looks like if it goes to the debugging:
So to conclude: everything is working fine unless I go to the previous year.
If I place: NOT BETWEEN, everything is reversed, and I see all the data.
I tried to replace BETWEEN with >= and <= as well, but the same thing occurred.
Any ideas?
Aangemeld is obviously a date, as it should be. So you must compare Aangemeld with dates. In order to do so,
first convert the dates to strings in VB. Make this a specific date format, rather than relying on some region settings. E.g. datumvan.ToString("dd/MM/yyyy")
then convert the string to date in SQL. Again don't rely on database settings, but name the format you are using.
How to convert a string to a date in SQL depends on the DBMS you are using. Here are some examples:
MySQL:
" ... WHERE Aangemeld BETWEEN STR_TO_DATE('" & datumvan.ToString("dd/MM/yyyy") & "','%d/%m/%Y') AND ... "
SQL_Server:
" ... WHERE Aangemeld BETWEEN CONVERT(datetime,'" & datumvan.ToString("dd/MM/yyyy") & "',103) AND ... "
Oracle:
" ... WHERE Aangemeld BETWEEN TO_DATE('" & datumvan.ToString("dd/MM/yyyy") & "','dd/mm/yyyy') AND ... "
Many DBMS (such as MySQL, SQL-Server, and PostgreSQL) also accept a string in ISO format as as date literal.
" ... WHERE Aangemeld BETWEEN '" & datumvan.ToString("yyyyMMdd") & "' AND ... "
In Oracle such a literal must be preceded by DATE:
" ... WHERE Aangemeld BETWEEN DATE'" & datumvan.ToString("yyyyMMdd") & "' AND ... "
One more thing: I don't know if this is the case in other DBMS, too, but I know that Oracle treats a date without time as a date at midnight, as it only knows datetime data type. So a between clause would exclude the last day. Which is why in Oracle you would compare TRUNC(Aangemeld) instead of Aangemeld.