linq query convert text to date to compare with another date vb.net - sql

I have a database field, Field260, that stores date representations as text. For instance a value for 3/29/2018 would be stored as a string "03/29/2018"
Dim Db = New DataClasses1DataContext
Return From cf In Db.FileDatas
Where cf.Field260 <= System.DateTime.Today
Returns error
System.Data.SqlClient.SqlException: 'Explicit conversion from data type text to datetime is not allowed.'
When I tried to Parse the date
Where DateTime.Parse(cf.Field260) <= System.DateTime.Today
I receive
System.NotSupportedException: 'Method 'System.DateTime Parse(System.String)' has no supported translation to SQL.'
I'm stumped.

I encountered a similar issue - have an app that I used to have a DatePicker for a field, and my database field defined as DateTime, but the users absolutely wanted to copy/paste whatever garbage they wanted into the field. Problem is, I'm allowing them to search for records by that "Date" field.
As a workaround, I do some basic validations on the garbage they enter to attempt to only allow dates (IsDate function captures most errors, but still allows them to enter years like 208 instead of 2018, so I also check that Year(DateValue(txtDate.Text))>2000, which works for me because it's an application-received date, so should never be older than this year). Then I store it as varchar in the database.
When searching for the records, you have two options - either grab all records, then perform a date conversion on the list returned to pare down the results, or hope and pray that your faulty LINQ WHERE clause will get everything you want.

Figured it out cuz I'm a genius.
Return From cf In Db.FileDatas
Where cf.Field260.ToString() <= System.DateTime.Today.ToString("MM/dd/yyyy")
Somehow comparing string to string works, who knew!

Related

Calendar Date String Conversion in Fill Method with specific query

I am using this query to generate a DataTable to display information for users to select from. The fill method I am using gives teh ff error.
Conversion failed when converting date and/or time from character
string
SELECT Time_Slot.TimeSlot, Proposed_Date.Date
FROM Time_Slot CROSS JOIN
Proposed_Date
WHERE (Time_Slot.TimeSlot_ID NOT IN
(SELECT Event_Time_ID
FROM Event_Booking
WHERE (Booking_Date = #Booking_Date)))
DTAvailableBookingsTableAdapter.FillAvailableBookings(DSEventBooking.DTAvailableBookings, MonthCalendar1.SelectionRange.Start.ToShortDateString)
Any help in resolving the error would be welcome
Many people make their own lives difficult when it comes to dates. VB.NET has a dedicated data type for dates so, if you are working with dates, use it. Don't convert anything that is not text to text, unless it is specifically for display/serialisation purposes, where only text is supported.
Presumably your Booking_Date is the appropriate data type for dates in your database, e.g. Date/Time in Access or date in SQL Server. In that case, the #Booking_Date parameter is expecting a value of that type, not text. In that case, why are you converting a value of the correct type to a value of the incorrect type here:
MonthCalendar1.SelectionRange.Start.ToShortDateString
The Start property is the correct type and you spoil it by converting it to a String. Don't. Just pass the DateTime value that you already have because that is what's expected.
MonthCalendar1.SelectionRange.Start
Coming from a MonthCalendar, it should already have the time portion zeroed so there's no need to do that yourself but, in cases where you did need to, you can get the Date property of a DateTime value to get another DateTime value with the same date and the time zeroed.
MonthCalendar1.SelectionRange.Start.Date
Note that DateTime is a .NET type and VB has a Date type that is simply an alias for that, i.e. a Date and a DateTime are the same thing. If this is confusing, it shouldn't be. Int32 is a .NET type too and Integer is a VB data type that maps to it. Do you use Integer all the time without any confusion? If so then you should use Date all the time without confusion too.

Test for zero datetime in SSIS Conditional Split

A value coming back from a DB2 query passes a zero date as 0001-01-01 00:00:00.000000 and I am having a problem testing for this value in a Conditional Split condition. I tried a few different things but either they stay red or cause an error when run. I even tried testing for the date being less than the SQL start date. Neither of these work.
(DT_Date)DRIVER_TERMDATE < (DT_DATE)"1753-1-1"
DRIVER_TERMDATE != "0001-01-01 00:00:00.000000"
The minimum date for the DT_DATE data type is 1899-12-30, which is after that date and trying to convert it to this data type will cause an error. If you're importing the DRIVER_TERMDATE as text, trying adding a condition for this string, for example
DRIVER_TERMDATE == "0001-01-01 00:00:00.000000"
However it looks like you already tried checking to see if DRIVER_TERMDATE is not equal to this value, so see if trailing zeros are being removed during from the text during execution by right-clicking the output from the DB2 source, selecting Enable Data Viewer, and examining the data when the package runs. Once you've confirmed the exact string that's being sent in, you can add a condition for this.

"Input value not long enough for date format" When updating with TableAdapter

My queries are managed by a DataAdapter, so I have little to no control over it's generation.The problem query goes this way:
UPDATE MYSCHEMA.MYTABLE
SET MYDATETIME = :myDateTime
WHERE (MYKEY = :myKey)
The data access layer is automatically generated. I can't change how it works...
The type of MYDATETIMEin the database side is Timestamp.
The type of the parameter myDateTime of the DataAdapter query and the field from the dataset is DateTime.
Not sure if it should matter. Also, it seems that on the Oracle side, the hour is 24 hour but the hour managed by the app has a 12 hour base. But Why would it matter? When calling the update method, I pass Date.Now. How more legit could it be?? But it still is rejected with:
ORA-01840: Input value not long enough for date format
Any ideas?
As per comment chat, it seems that a string conversion is occurring because the parameter database type is set to varchar
Set the ProviderType of the parameter to be something more relevant to the type Oracle is expecting - it'll either be Date, DateTime, Timestamp, OracleDateTime or some variation on this theme (the names change according to whether you use .net oracle client or oracle's one) , hopefully...

Date Range Query not returning all records - SQL

I have a SQL db that I need to filter results based on the month that inventory items were completed in order to do the billing.
The field I'm working with is called CompletionDate. Here is the code I'm using.
input name='criteria' type='hidden' value="WHERE CompletionDate BETWEEN '8-1-2013' AND '8-31-2013'"
I get some of the records returned but not all. I suspect that the problem lies in the format of the CompletionDate field. It is currently a varchar(10). I am storing the data in this field in the format MM-DD-YYYY.
After some searching I understand that since the field is in a varchar datatype that the above mentioned code is not going to work the way I want it to. I've tried this to no avail.
input name='criteria' type='hidden' value="WHERE to_date(CompletionDate, 'mm-dd-yyyy') BETWEEN to_date('8-1-2013', 'mm-dd-yyyy') AND to_date('8-31-2013', 'mm-dd-yyyy')"
Can anyone help guide me to the solution?
Because the field is of type varchar, you are not searching for a date range but actually a text range. You really should store dates in a date type field, because then you can easily and efficiently do date range queries.
Your workaround using to_date should in theory work, although it is rather inefficient as the database has to try to convert the text from each row into a real date in order to be able to do the comparison. As to why it actually does not work is still unclear. What database are you using? Is the format string correct or should it be in uppercase ('MM-DD-YYYY')?
If you are stubborn in storing dates as text in the database, using a format that can be lexically sorted, e.g. YYYY-MM-DD including leading zeroes (2013-08-01), can seemingly make the range queries work. But there really are several good reasons why databases have dedicated date datatypes!
A better way is like this:
where CompletionDate >= the start of your date range
and CompletionDate < the day after the end of your date range.
Reason number 1 is that it will take the time element into account, if applicable.
Reason number 2 is that using functions in the where clause slows down production.
By the way, if CompletionDate is a char or varchar datatype in your db, you have serious problems.

SQL Server - simple select and conversion between int and string

I have a simple select statement like this:
SELECT [dok__Dokument].[dok_Id],
[dok__Dokument].[dok_WartUsNetto],
[dok__Dokument].[dok_WartUsBrutto],
[dok__Dokument].[dok_WartTwNetto],
[dok__Dokument].[dok_WartTwBrutto],
[dok__Dokument].[dok_WartNetto],
[dok__Dokument].[dok_WartVat],
[dok__Dokument].[dok_WartBrutto],
[dok__Dokument].[dok_KwWartosc]
FROM [dok__Dokument]
WHERE [dok_NrPelnyOryg] = 2753
AND [dok_PlatnikId] = 174
AND [dok_OdbiorcaId] = 174
AND [dok_PlatnikAdreshId] = 625
AND [dok_OdbiorcaAdreshId] = 624
Column dok_NrPelnyOryg is of type varchar(30), and not null.
The table contained both integer and string values in this column and this select statement was fired millions of times.
However recently this started crashing with message:
Conversion failed when converting the varchar value 'garbi czerwiec B' to data type int.
Little explanation: the table contains multiple "document" records and the mentioned column contains document original number (which comes from multiple different sources).
I know I can fix this by adding '' around the the number, but I'm rather looking for an explanation why this used to work and while not changing anything now it crashes.
It's possible that a plan change (due to changed statistics, recompile etc) led to this data being evaluated earlier (full scan for example), or that this particular data was not in the table previously (maybe before this started happening, there wasn't bad data in there). If it is supposed to be a number, then make it a numeric column. If it needs to allow strings as well, then stop treating it like a number. If you properly parameterize your statements and always pass a varchar you shouldn't need to worry about whether the value is enclosed in single quotes.
All those equality comparison operations are subject to the Data Type Precedence rules of SQL Server:
When an operator combines two
expressions of different data types,
the rules for data type precedence
specify that the data type with the
lower precedence is converted to the
data type with the higher precedence.
Since character types have lower precedence than int types, the query is basically the same as:
SELECT ...
FROM [dok__Dokument]
WHERE cast([dok_NrPelnyOryg] as int) = 2753
...
This has two effects:
it makes all indexes on columns involved in the WHERE clause useless
it can cause conversion errors.
You're not the first to have this problem, in fact several CSS cases I faced had me eventually write an article about this: On SQL Server boolean operator short-circuit.
The correct solution to your problem is that if the field value is numeric then the column type should be numeric. since you say that the data come from a 3rd party application you cannot change, the best solution is to abandon the vendor of this application and pick one that knows what is doing. Short of that, you need to search for character types on character columns:
SELECT ...
FROM [dok__Dokument]
WHERE [dok_NrPelnyOryg] = '2753'
...
In .Net managed ADO.Net parlance this means you use a SqlCommand like follows:
SqlCommand cmd = new SqlCommand (#" SELECT ...
FROM [dok__Dokument]
WHERE [dok_NrPelnyOryg] = #nrPelnyOryg
... ");
cmd.Parameters.Add("#nrPelnyOryg", SqlDbType.Varchar).Value = "2754";
...
Just make sure you don't fall into he easy trap of passing in a NVARCHAR parameter (Unicode) for comparing with a VARCHAR column, since the same data type precendence rules quoted before will coerce the comparison to occur on the NVARCHAR type, thus rendering indexes, again, useless. the easiest way to fall for this trap is to use the dredded AddWithValue and pass in a string value.
Your query stopped working because someone inserted the text string in to the field you are querying using INT. Up until that time it was possible to implicitly convert the data but now that's no longer the case.
I'd go check your data and, more importantly, the model; as Aaron said do you need to allow strings in that field? If not, change the data type to prevent this happening in the future.