-
Notifications
You must be signed in to change notification settings - Fork 421
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
issue due to rounding of timestamps #1843
Comments
Hi @AlBundy33, thanks for reaching out, we will take a look at this issue soon. |
Hi @AlBundy33, Could you elaborate on what your expected behavior is? The program appears to be "working" properly when I run it. The assert will fail whenever it encounters a row where it doesn't need to update anything. |
If you get a timestamp (ts) from db and then query or update all records where the timestamp-column >= ts i would expect that also the row is updated where i got the timestamp from. In my first example the row with the timestamp was not updated even the timestamp >= ts because i got it first from database. Another example (not tested but makes it hopefully clear) This should now get all records including the row where we get the timestamp from in first place but depending on the used millis it seems that the original record is skipped. If you execute the posted test it should fail. |
Comparing a java Timestamp to a datetime column on sql server will not have accurate results. |
i know - but if i get the timestamp from the database on the first hand i would expect that is a usabe timestamp. if i do a so it seems that the driver rounds timestamps that are already coming from the database. |
This is an issue with how the database handles comparisons between datetime and datetime2 values. The driver sends timestamp parameters as datetime2, but the column is a datetime. (This worked great up until SQL Server 2016.) When the database converts the datetime to a datetime2 for comparison with the more precise datetime2 parameter, you can get unexpected results. For more details and workarounds, see these links: #680
Regards, |
So you don't think that this behavior is a bug? If I read a valie A from database and query all records with value A afterwards I would expect to get all the records including that one where I've got value A from in first place. With jTDS driver for example this issue doesn't exists. |
It may be unintuitive but yes this is the expected behavior. As you can see from the example TSQL in issue 680, even comparing the exact "same" datetime2 to datetime value within SSMS will result in an inequality. When you read value A the server will give the driver a time value which for example ends in .003 seconds. When you query the database against this same column we then pass back that value which ends in .003 seconds, however when the server makes the comparison it will compare the value we passed with the stored value of .00<1 third of a millisecond>. Which will result in an inequality since 0.003 != 0.0033333333... I suspect that jTDS still sends data as datetime instead of datetime2. However it would not make sense for us to do that since datetime2 is the more accurate datatype. If you run the repro app with the column type as datetime2(3) the comparison will work for all rows. |
Hello @AlBundy33, |
I'm not really sure about that. 😄 The problem is that the current behavior is totally unxpected when working with datetime. Setting compatibility mode to an older version may workaround the problem but if we forget to change the settings in existing and future customer database we have rhe same problem as mentioned above. Is there really no chance that you can handle this on driver side? |
There probably are ways to handle it driver side, and you are free to make a feature request, however this is simultaneously
So it would take a long time and likely a rather unexpectedly smooth semester to get this in. |
Problem is also described in #1520 |
#1687 resolves this by allowing users to specify the datatype to use for date/timestamp parameters. @AlBundy33, please let us know if this fix (included in 12.2+) works for you. Closing issue, but can reopen if needed. |
thank you - seems to work 👍 |
Driver version
10.2.0
SQL Server version
Microsoft SQL Server 2019 (RTM-CU15) (KB5008996) - 15.0.4198.2 (X64)
Jan 12 2022 22:30:08
Copyright (C) 2019 Microsoft Corporation
Developer Edition (64-bit) on Linux (Ubuntu 20.04.3 LTS)
Client Operating System
Windows 10 but also affects Ubuntu
JAVA/JVM version
OpenJDK 11 but also affects Oracle Java 8
Description
We've recently tried to switch from jTDS to mssql-jdbc-driver which seems to work pretty good in most cases.
But there seems to be an issue due to the rounding of timestamps in mssql-jdbc because if we write a tiemstamp with System.currentTimeMillis() in the database, read the value from the database and try to update all records with timestamp >= the previous read tiemstamp this doesn't work for some values.
Test-case
I hope this test-case will describe the problem better :-)
-> This test-case is similar to some logic in our application that currently fails in our integration tests.
I've used com.microsoft.sqlserver.jdbc.preparedStatement.SetObjectTest as base - not sure if this is the right place.
I don't know if step 3 or 4 is the problem but this test always fails with my local database with very low values of i.
The expected behavior would be that I could search with the original values from database.
The text was updated successfully, but these errors were encountered: