I have a table that have a column storing date in varchar(10) format, like '20190101'. I have a variable in SSIS is defined as DateTime format. now I want to make the value match in SSIS OLE DB data flow source, in the format as SELECT * FROM table where date = CONVERT(varchar(10), ?, 112).
Looks like the conversion didn't work correctly; no qualified data pops out in the data flow.
So what's wrong with this query (the result looks fine when putting it into SSMS), and how to debug it (it's not possible to debug it using the query like SELECT CAST(? AS varchar(10) FROM table in data source).
(PS: the last thing I want to do is to define another string variable to work around).
The reason is because of implicit conversion by SSIS data source when deciding the type of parameter according to the opposite side of operator. Try this test:
Make a valid SSIS data source connection to a table that contains a date(time) column; make a dateTime variable.
Switch the data source to SQL command and type the below queries, one by one:
SELECT 1 FROM table WHERE ? > 1
SELECT 1 FROM table WHERE ? > '1'
SELECT 1 FROM table WHERE ? > date_col
Execute the data flow.
In SSMS, quote the recent sessions:
select top 50 t.text, s.* from sys.dm_exec_query_stats s
CROSS APPLY sys.dm_exec_sql_text(sql_handle) t
where t.text LIKE <filter your session>
order by last_execution_time desc
You may find how the parameter is interpreted:
(#P1 int)SELECT 1 FROM table WHERE ? > 1
(#P1 varchar(8))SELECT 1 FROM table WHERE ? > '1'
(#P1 datetime)SELECT 1 FROM table WHERE ? > date_col
In other words, the SQL command will interpret the type of incoming parameter regardless of what type it original was.
So in my problem, the dateTime parameter was first implicitly converted into varchar with an unknown format than we are attempting to convert it into a specified date type:
SELECT * FROM table where date = CONVERT(varchar(10), 'Jan 01 2019 12:00:00', 112)
Related
I've been using the following format to insert into my mysql database previously, and would like to keep it uniform.
INSERT INTO OPENQUERY (ENET, 'SELECT * FROM ActiveDirectory.Computers') -- MYSQL database
SELECT c.[CommonName],
c.[DistinguishedName],
c.[SAMAccountName],
c.[DNSHostName],
c.[Location],
c.[Division],
c.[Department],
c.[ManagedBy],
c.[MachineRole],
CAST(CAST(c.[LastLogon] as timestamp) as datetime) AS LastLogon,
c.[OperatingSystem],
c.[OperatingSystemVersion],
c.[ServicePack],
c.[OU],
c.[CreatedOn],
c.[ChangedOn],
CASE WHEN c.[UserAccountControl] & 2 = 0 THEN 1 ELSE 0 END AS [Enabled] -- Check to see if disabled. Disabled = bitwise of 2; 4098 = 4096 + 2 = Trust Account + Disabled
FROM [IT_ActiveDirectory].[dbo].[ADComputerTable] c -- MSSQL database
My problem comes when inserting the fields that are datetimes in MSSQL (c.LastLogon, c.CreatedOn, c.ChangedOn) into mysql fields that are also datetimes. I have tried almost every combination of CAST() and CONVERT() I can think of, but I may have missed something. I have also tried changing mysql's field type to timestamp.
It returns: Conversion failed when converting date and/or time from character string.
It seems strange to me that MSSQL won't just send the data to MYSQL and let it do the conversion. Instead it looks like it is trying to convert and match the datatypes and data before it sends it to MYSQL.
If I can't insert it this way, I am open to another format, like if its possible to do the insert inside of the OPENQUERY() SELECT. Any suggestions? I'm dead in the water at the moment.
I would try to convert to ISO-8601 format string:
INSERT INTO OPENQUERY (ENET, 'SELECT * FROM ActiveDirectory.Computers')
SELECT
...,
CONVERT(VARCHAR, LastLogon, 126) AS LastLogon
FROM [IT_ActiveDirectory].[dbo].[ADComputerTable];
Also I don't like SELECT * in OPENQUERY. If columns are matched by position it is error-prone. Consider expanding start to columns.
In one of my MYSQL databases, I have done the following query :
SELECT * FROM mytable WHERE date_column < 1971-01-01 AND date_column IS NOT NULL;
This returns about 3000 items where the date is shown as NULL in the mysql command line prompt, and in the IntelliJ IDEA mysql database editor.
The column has a DATE type.
The database is a copy of a prod database environment that has been running for a couple years.
How can a record end up in that state ? What is that state ? How can I fix it properly ?
PS: The < 1971/01/01 clause was just to filter the correct dates out of the query. If I just query on the IS NOT NULL clause, I still get these weird dates of course.
I am surprised this works. First, date constants should be surrounded by single quotes:
SELECT *
FROM mytable
WHERE date_column < '1971-01-01' AND date_column IS NOT NULL;
Second, this cannot return a NULL value for date_column. This suggests one of two things:
date_col is actually another type, such as varchar and you are seeing 'NULL' the string, not NULL the value.
another column is NULL.
I'm using Access 2010 and have a table like the following called Table1 (the table is imported from Excel and the date column was formatted as date there):
date xy
---------------------------------
19.10.2016 14:10:51 jljh
19.10.2016 13:13:28 kgkhg
19.10.2016 12:53:15 asd
I've already accepted that I can't do normal SQL things in Access. But why does the following simple-as-hell query ends in the error data type mismatch in criteria expression?
SELECT DateValue(DATE) as dt, COUNT(CSID)
FROM Table1
GROUP BY DateValue(DATE)
First, you can do "normal SQL things" in Access.
Then, DateValue doesn't accept dot as the date separator, thus:
SELECT DateValue(Replace([DATE], ".", "/")) as dt, COUNT(*)
FROM Table1
GROUP BY DateValue(Replace([DATE], ".", "/"))
You -- that is me -- say that the table was imported from Excel. So go back to Excel, do the date truncation there, re-import it again, and your -- that is my -- query will run as if it were "normal" SQL. Nothing more intuitive than this shit.
EDIT: Meanwhile I also figured out what the problem was: there were unfilled values in the date column. So DateValue cannot know how to handle them and must throw an exception. However, what's still a bit annoying is that this error did not occur without the group by statement. So it's only 50% the blame of Access this time, the other part is on me :-)
Is there a way to trim off the timestamp in a DB2 date function?
Have DB2 select statement where I'mm selecting a date form the databease and saving it to a variable. I then use that variable as a parameter for another db2 select by adding 30days to it but I don't think it agrees with the timestamp that it is adding to the end.
Select business_date From DB2INST1.BusDate Where key = 0
There is no timestamp in the database for this date but its adding '12:00:00AM' to the end
it saves this select into a variable and I use it in another select here
where expirdate > (DATE(#BusDate) + 30 DAYS)
I get this error:
{"ERROR [428F5] [IBM][DB2/AIX64] SQL0245N The invocation of routine \"DATE\" is ambiguous. The argument in position \"1\" does not have a best fit."} System.Exception {IBM.Data.DB2.DB2Exception}
Select business date as a varchar/string
Select varchar_format(business_date,'YYYY-MM-DD')
then do this to use it later, convert it to a date then use a date function to add 30days to it:
(DATE(to_date(#BusDate, 'YYYY-MM-DD') + 30 DAYS))
Try
where expirdate > DATE(#BusDate + 30 DAYS)
Is the first SELECT statement and the second SELECT Statement part of same stored procedure? Are you storing the resulting date in any .Net variable? If you are storing it in a .Net DateTime variable, my suggestion is to do the date addition operation in .Net code itself. And then remove the time part from the variable before passing to the database.
Take a look at this too: Datetime field overflow with IBM Data Server Client v9.7fp5
If both the SELECT statements were part of a stored procedure and there is no .Net DateTime variable invloved, then it is a different story.
We have a legacy database (SQLServer 2008) with thousands of rows in it. Each record has a logdate field which is a date but stored as a varchar in the format 21/04/2010 16:40:12.
We only need to return the rows where the logdate is in the future, and order them by date. We could pull back all the rows and filter on the server but this seems wrong and won't scale.
Is there a way of doing the filtering and ordering in Entity Framework 4.
This is what we thought might work but it's failed.
from c in db.changes
where [DateTime]c.logdate > DateTime.Today()
orderby [DateTime]c.logdate
select c;
Any help is appreciated.
You can't parse a string into a date on the DB server with any built-in L2E function.
You can:
map a DB function yourself,
write SQL and execute it with ObjectContext.ExecuteStoreQuery, or
fix the metadata.
I'd pick the latter, if it were me.
I'm not sure you can do it through pure LINQ unless you create your own LINQ functions. If you can execute an ad-hoc query and have EF4 translate it back into objects, like you can on the DataContext.Translate LINQ2SQL method, you can convert it like this:
CONVERT(datetime, logdate, 103)
And thus your query would be:
SELECT
*
FROM
changes
WHERE
CONVERT(datetime, logdate, 103) > GETDATE()
ORDER BY
CONVERT(datetime, logdate, 103)
Alternatively, if you can add to the schema (I assume you can't modify the varchar column to store it as a datetime natively), you could add a computed column like so:
ALTER TABLE
changes
ADD
logdateDatetime AS CONVERT(datetime, logdate, 103) PERSISTED
And then query the logdateDatetime column instead of logdate.
The order in a varchar field will be considerably different than the order in date field. Fix your structure to correctly store dates or add an additional date field that is populated through a trigger. Likely you have bad dates in there as well since there are no controls on a varchar field to diallow dates from being put in. You will need to fix these as well.