Native Query date formats between different database engines - sql-server

I am creating a native query for Hibernate using the following code
final Query countQuery = entityManager.createNativeQuery( countSql );
if ( countCriteria.getStartDate() != null ) {
final String startDate = countCriteria.getStartDate().toString();
countQuery.setParameter( START_DATE_PARAMETER, startDate );
}
Where startDate on my class is an org.joda.time.DateTime and toString() returns "2019-05-13".
These query parameters work fine in production, which is running against MS Sql Server. (ick!)
Now, the unit test is running against HSQLDB. I'm providing the same values and it throws:
javax.persistence.PersistenceException: org.hibernate.exception.DataException: data exception: invalid datetime format
When it attempts to run the query.
Since the parameter is formatted exactly the same, I'm assuming that the problem is the format of the date string for HSQLDB.
So, now what? How do I move forward with this? I've checked the setParameter format that takes TEMPORAL or whatever, but that won't work for JODA time.
I've already talked to my tech lead about not using native queries, but using hibernate queries, but it has fallen on deaf ears. Do I have another option so I don't have to battle my tech lead to write unit tests for our DAOs?

Well, I'm embarrassed to admit how long it took me to figure this one out.
I simply converted the LocalDate to a java date, then used that to set a TemporalType parameter.
Date date = localDate.toDate();
countQuery.setParameter(parmName, date, TemporalType.DATE);
This seems to be working fine.

Related

Convert FileTime to DateTime in Azure Logic App

I'm pretty new to Logic App so still learning my way around custom expressions. One thing I cannot seem to figure out is how to convert a FileTime value to a DateTime value.
FileTime value example: 133197984000000000
I don't have a desired output format as long as Logic App can understand that this is a DateTime value and can be able to run before/after date logic.
To achieve your requirement, I have converted the Windows file Time to Unix File Time then converted to File time by add them as seconds to a default date 1970-01-01T00:00:00Z. Here is the Official documentation that I followed. Below is the expression that worked for me.
addSeconds('1970-01-01T00:00:00Z', div(sub(133197984000000000,116444736000000000),10000000))
Results:
This isn't likely to float your boat but the Advanced Data Operations connector can do it for you.
The unfortunate piece of the puzzle is that (at this stage) it doesn't just work as is but be rest assured that this functionality is coming.
Meaning, you need to do some trickery if you want to use it to do what you want.
By this I mean, if you use the Xml to Json operation, you can use the built in functions that come with the conversion to do it for you.
This is an example of what I mean ...
You can see that I have constructed some XML that is then passed into the Data parameter. That XML contains your Windows file time value.
I have then setup the Map Object to then take that value and use the built in ado function FromWindowsFileTime to convert it to a date time value.
The Primary Loop at Element is the XPath query that will make the selection to return the relevant values to loop over.
The result is this ...
Disclaimer: I should point out, this is due to drop in preview sometime in the middle of Jan 2023.
They have another operation in development that will allow you to do this a lot easier but for now, this is your easier and cheapest option.
This kind of thing is also available in the Transform and Expert operations but that's the next tier level of pricing.

Dynamic Date using Analysis Services in Report builder

Looking for help on this one. I'm working on a report in Report Builder that uses data from the Analysis Services cube and it is giving me a lot of problems when it come to any date/time data. I am trying to build a dynamic report that will allow the report to update depending on when it is viewed. I do this by setting parameters (#FromDateDate and #ToDateDate). Unfortunately MDX seems to hate dates which makes no sense to me.
My goal is to get data over a span of three months with the #ToDateDate being Today() and the #FromDateDate being 3 months in the past which I am able to achieve with this function (=DateAdd(DateInterval.Day,-90,Today()) ). However those don't go well with MDX.
My query looks like this:
SELECT
NON EMPTY
{[Measures].[Work Item Count]} ON COLUMNS
,NON EMPTY
{
[Date].[Year - Month - Date Hierarchy].[Date].ALLMEMBERS*
[Work Item].[System_State].[System_State].ALLMEMBERS*
[Work Item].[Microsoft_VSTS_Common_Severity].[Microsoft_VSTS_Common_Severity].ALLMEMBERS
}
DIMENSION PROPERTIES
MEMBER_CAPTION
,MEMBER_UNIQUE_NAME
ON ROWS
FROM
(
SELECT
StrToMember
(#FromDateDate
,CONSTRAINED
)
:
StrToMember
(#ToDateDate
,CONSTRAINED
) ON COLUMNS
FROM
(
SELECT
{[Work Item].[System_WorkItemType].&[Bug]} ON COLUMNS
FROM
(
SELECT
{
[Team Project].[Team Project Hierarchy].&[{6F43CBFD-2E98-4CA7-B428-0B732603517A}]
} ON COLUMNS
FROM [Work Item]
)
)
)
WHERE
(
[Team Project].[Team Project Hierarchy].&[{6F43CBFD-2E98-4CA7-B428-0B732603517A}]
,[Work Item].[System_WorkItemType].&[Bug]
)
CELL PROPERTIES
VALUE
,BACK_COLOR
,FORE_COLOR
,FORMATTED_VALUE
,FORMAT_STRING
,FONT_NAME
,FONT_SIZE
,FONT_FLAGS;
I was able to figure out how to essentially inject he appropriate format by adjusting my Parameter Values in the Dataset Properties to this -
="[Date].[Date].&["+format(Parameters!FromDateDate.Value,"yyyy-MM-ddThh:mm:ss")+"]"
My two parameters have default values of :
=DateAdd(DateInterval.Day,-90,Today()) and =Today()
When I run my report I get the following error:
The restrictions imposed by the CONSTRAINED flag in the STRTOMEMBER function were violated.
Now if I remove CONSTRAINED from the STRTOMEMBER function I get another error. I have also tried removing the entire STRTOMEMBER function and just using the parameters which I can get to work in Management Studio but not in Report builder. Please Help! I have attempted so many different ways and still no success. Let me know what additional information is needed.
Another thing -
If I remove the T in the date format of the Parameter Value in the Dataset Property to look like this:
="[Date].[Year - Month - Date Hierarchy].[Date].&["+format(Parameters!FromDateYearMonthDateHierarchy.Value,"yyyy-MM-dd hh:mm:ss")+"]"
I get the below error:
The '2017-06-08 12:00:00' string cannot be converted to the date type.
So here is the solution if anyone is interested. I've seen a ton of forum posts online with no one having a concrete answer so I can see this is a common problem - the workaround at this link is valid and does work:
Using Dynamic MDX in Reporting Services
My issue was the format of my "injected" date. When running the query generated by my #ToDateDate and #FromDateDate parameters...
(note: after changes I made my parameters are now
#FromDateYearMonthDateHierarchy and '#ToDateYearMonthDateHierarcy`
which you will notice in my Parameter Value function)
My Parameter Values appeared in the following format:
[Date].[Year - Month - Date Hierarchy].[Date].&[2010-12-31T00:00:00]
In order to fix the issue for me my "injection statement" had to look like this:
"[Date].[Year - Month - Date Hierarchy].[Date].&[" & Format(CDate(Parameters!FromDateYearMonthDateHierarchy.Value),"yyyy-MM-dd") & "T00:00:00]"
With the actual date formatting of "yyyy-MM-dd") & "T00:00:00]" so in the end the hours minutes and second was what was giving me the headache. The injection works perfectly but just need to pay attention to the Formatting of the date and time. I genuinely hope this helps someone!

ADO Recordset Type for Date

Warning: Classic ASP Ahead. :)
I'm working on a legacy Classic ASP application and I'm running into an oddity with an ADODB.Recordset object.
I have a SQL2012 database table containing a particular field. Let's call it AnnoyingField. Its datatype in SQL is 'date'.
The ASP opens an ADODB.Recordset with a SELECT on the table to collect the fields, then does some looping to do its work:
For each Field in rs.Fields
typeid = rs(Field.Name).Type
'do stuff based on type
For some reason, the Type for AnnoyingField is coming back as 202 (nvarchar) rather than one of the expected types for date (133 or even 7). This is causing some issues further in the code.
I tested with another field of 'datetime' type and the Recordset code returned the expected Type for a datetime field.. 135.
Anyone have an idea why the 'date' fields are returning as an nvarchar?
Changing the database fields from date to datetime in this case might not be possible, even though it might be the logical path to take to get expected data.
Date fields are newer than your version of ADODB. So it doesn't understand what it's getting.
You may be able to cheer it up by using
select convert(datetime, AnnoyingField) from CrazyFuturisticTable
You may also get the correct result if you upgrade your ADODB version to 2.8 and/or connect using the SQL Native Client. Obviously, I haven't tried this, because I live in 2014.
If you keep it a little simpler, cut ADO out of the picture and use isdate and "convert date" and vartype.
For each Field in rs.Fields
Field=rs(Field.Name)
if isdate(Field) then Field=cdate(Field) ' just in case
typeid = VarType(Field)
'do stuff based on type
Vartype
http://www.w3schools.com/vbscript/func_vartype.asp
ADO .type can report more "types"
http://www.w3schools.com/ado/prop_para_type.asp
But I think what vartype can offer should help people in 95% of cases.
Word of warning with cdate, depending on what the server locale is set too or your Session.LCID (in your code) is set will determine what format the date will be formatted to. Shouldn't be a problem for most people but obviously test to see if you get the expected result.
I am using Classic ASP / VBScript and have found that for SQL2012 using SQL Native driver ("Provider=SQLNCLI11"), and the ADO module provided by Windows (presumably Vista or newer [mine is Windows Servr2012 R2 - the version [MyDbConn.version] shows as 6.3) this now works again.
I had been looking for / expecting the Field.Type to be adDate [7], but am actually getting adDBDate [133]

Dateformat mismatch in sql server and C# code

I have a problem.
I have an application in C# with SQL SERVER 2005 as backend.
The problem is in fetching the correct record based on the date.
The frontend code is
if (string.IsNullOrEmpty(txtFromDate.Text))
SelectCmd.Parameters[0].Value = DBNull.Value;
else
SelectCmd.Parameters[0].Value = txtFromDate.Text;
Now if I run usp_NewGetUserDetail '03/04/2010' in the query analyser, I am able to get the correct record.
So I am preety confident that my SP is correct(I have tested with many variations).
But if the same value is passed from front end code(SelectCmd.Parameters[0].Value = "03/04/2010";), I am getting some unexpected record. By that I mean , the records which are not in the date range.
I guess that there is some mismatch in date format of backend and frontend.
Kindly let me know if I missed out some information that I need to provide for solving this
Please help.
Dealing with dates on SQL Server is a tricky business, since most formats are language- and locale-dependent. As Adam already mention - you should try to avoid dealing with dates as strings - it does get messy, and using DateTime (both in .NET and in T-SQL) is much safer and easier.
But if you must use strings, then be aware of these points: a date like 02/05/2010 will be interpreted as Feb 5, 2010 in some places, or as May 2, 2010 in others. So whatever you're doing - you'll always run into someone who has a different setting and gets different results.
The way to do here is to use the ISO-8601 format which is independent of all locale and language settings and just always works.
So for your dates, always use the YYYYMMDD format - first of all, it always works, and second of all, with that format, you get a "natural" sort behavior - sorted by Year, then Month, then Day.
There's no need to pass the date as a string, nor should you. Set the value of the parameters to a DateTime object that represents the date you want, not the string representation of it.
Try something like this:
DateTime fromDate;
if (DateTime.TryParse(txtFromDate.Text, out fromDate))
{
SelectCmd.Parameters[0].Value = fromDate
}
else
{
SelectCmd.Parameters[0].Value = DBNull.Value;
}

Executing stored procedures with date parameters: Command Object vs Connection Object

When supplying dates to a stored procedure via a parameter I'm a little confused over which format to use for the dates. My original VBA syntax used the ADO Connection object to execute the stored procedure:
Set SentDetailRS = Me.ADOConnectionToIntegrity.Execute("dbo.s_SelectAggregatedSentDetailList '" & fCSQLDate(EffectiveDate) & "'", , adCmdText)
This works fine for me using the date syntax yyyy-mm-dd but when another user executes the code they recieve the error: 13 'Type Mismatch'.
After some experimentation I found that supplying the date in the format dd/mm/yyyy fixes this error for the user but now gives me the error!
Executing the stored procedure using a command object with parameters works regardless of the format of the date (I assume ADO is taking care of the formatting behind the scenes). I thought that using the format yyyy-mm-dd would work universally with SQL Server?
I'm also perplexed as to why this problem appears to be user specific? I noticed that my default language on SQL Server is 'English' whereas the other user's default language is 'British English', could that cause the problem?
I'm using ADO 2.8 with Access 2003 and SQL Server 2000, SQL Server login is via Windows integrated security.
Be careful, and do not believe that ADO is taking care of the problem. Universal SQL date format is 'YYYYMMDD', while both SQL and ACCESS are influenced by the regional settings of the machine in the way they display dates and convert them in character strings.
Do not forget that Date separator is # in Access, while it is ' in SQL
My best advice will be to systematically convert your Access #MM-DD-YYYY# (or similar) into 'YYYYMMDD' before sending the instruction to your server. You could build a small function such as:
Public function SQLdateFormat(x_date) as string
SQLDateFormat = _
trim(str(datePart("yyyy",x_date))) & _
right(str(datePart("m",date)),2) & _
right(str(datePart("d",date)),2)
''be carefull, you might get something like '2008 9 3'
SQLDateFormat = replace(functionSQLDateFormat," ","0")
'' you will have the expected '20080903'
End function
If you do not programmatically build your INSERT/UPDATE string before sending it to the server, I will then advise you to turn the regional settings of all the machines to the regional settings of the machine hosting SQL. You might also have to check if there is a specific date format on your SQL server (I am not sure). Personnaly, I solved this kind of localisation problems (it also happens when coma is used as a decimal separator in French) or SQL specific characters problems (when quotes or double quotes are in a string) by retreating the SQL instructions before sending them to the server.
I would guess that fCSQLDate function is culture-specific - i.e. it will parse the date based on the user's locale settings. That's why you see the problem.
Anyway, using queries with concatenated strings is always a bad idea (injection attacks). You are better off if you use parameters.
Access uses # as date field delimiter. The format should be #mm/dd/yyyy# probably the #mm-dd-yyyy# will also work fine.
Sorry I don't know mysql, but with oracle I would always explicity state the format that I was expecting the format to be in, eg: 'DD-MM-YYYY', to avoid (regional) date format problems
Why not use the format
dd mmm yyyy
There is only one way it can be interpreted.
You can use the Date() function to return a universal date based on the machine date and time settings. The region settings on the machine will determine how it it formatted on the client end. If you leave the field as strictle a DateTime field then the cleint region settings can format the date.
Going into the server, using the Date() function should aslo work (returning a universal date value).
Also, use a command object and parameters in your query when you pass them to avoid SQL injection attacks on string fields.

Resources