<p>注意到您打破了2016年的变化:</p>
<blockquote>
<p>Under database compatibility level 130, implicit conversions from
datetime to datetime2 data types show improved accuracy by accounting
for the fractional milliseconds, resulting in different converted
values. Use explicit casting to datetime2 datatype whenever a mixed
comparison scenario between datetime and datetime2 datatypes exists.
For more information, refer to this <a href="http://support.microsoft.com/help/4010261" rel="nofollow noreferrer">Microsoft Support Article</a>.</p>
</blockquote>
<p><a href="https://docs.microsoft.com/en-us/sql/database-engine/breaking-changes-to-database-engine-features-in-sql-server-2016?view=sql-server-2017" rel="nofollow noreferrer">Breaking Changes in SQL Server 2016</a></p>
<p>问题是您的表仍然使用旧的<code>datetime</code>数据类型。这是一种很奇怪的类型。它没有ms分辨率。它的分辨率实际上是1/300秒。所以实际的存储值并不总是看起来的那样。存储是不精确的,就像浮点数一样。在</p>
<p>新的better <code>datetime2</code>具有更高的精度,并且始终存储十进制小数秒。无论如何,SQL 2016改变了<code>datetime</code>转换为<code>datetime2</code>的方式,其副作用是使涉及隐式转换的比较有时中断。在</p>
<p>要解决此问题,请将表上的数据类型更改为datetime2(3),以获得1ms的精度。或者强制参数为datetime,而不是datetime2。我不知道pyodbc是否允许这样做,但是您可以很容易地在查询中强制转换:</p>
<pre><code>cur.execute("SELECT * FROM dbo.Data WHERE datetime >= cast(? as datetime)", lastDatetime)
</code></pre>
<p>现在,不是将表列转换为<code>datetime2</code>,而是将参数值转换为<code>datetime</code>,比较工作如预期。在</p>
<p>或者将数据库兼容性级别降低到120。在</p>