我试图查询Microsoft SQL数据库,以获取在上一个循环中返回的日期时间之后的所有记录。我使用“>;”运算符,但我看到的结果是“>;=”(大于或等于)。在
Python(3.6.5 Win10)脚本:
import pyodbc # version 4.0.24
import time
import datetime
import json
con = pyodbc.connect("DRIVER={ODBC Driver 17 for SQL Server};SERVER=localhost;DATABASE=mydb;UID=myuid;PWD=mypwd")
cur = con.cursor()
i = 0
lastDatetime = datetime.datetime.strptime('01Jan1970', '%d%b%Y')
while i < 60:
print("{0}: SELECT * FROM dbo.Data WHERE datetime > '{1}'".format(str(i), lastDatetime))
cur.execute("SELECT * FROM dbo.Data WHERE datetime > ?", lastDatetime)
rows = cur.fetchall()
for k, v in enumerate(rows):
jsonMsg = json.dumps({
"transaction_id": v[1],
"plu": v[2].strip(),
"qty": int(v[3]),
"dateTime": str(v[4])
}, separators=(',', ':'))
print(str(jsonMsg))
lastDatetime = v[6]
print("lastDatetime set to: {0}".format(lastDatetime))
i = i + 1
time.sleep(5)
产生:
^{pr2}$我在SQL Server Management Studio中运行查询,得到预期结果:
SELECT * FROM dbo.Data WHERE datetime > '2018-08-01 10:48:47.653'
不返回记录。在
为了得到预期的结果,我在python脚本中缺少了什么或者应该做些什么修改?在
谢谢。在
编辑: 将“”添加到datatime前后的sql字符串的打印中。对结果没什么影响。在
我把最后一次加上1毫秒,并把“>;”改为“>;=”,就解决了这个问题。由于毫秒是当前MS-SQL中最小的时间增量,因此该方法不应丢失任何数据。在
我怀疑这与Python处理浮点数有关,但不能肯定的是,将1毫秒的浮点数加到秒数部分并没有完全增加它。在
修订代码:
注意到您打破了2016年的变化:
Breaking Changes in SQL Server 2016
问题是您的表仍然使用旧的
datetime
数据类型。这是一种很奇怪的类型。它没有ms分辨率。它的分辨率实际上是1/300秒。所以实际的存储值并不总是看起来的那样。存储是不精确的,就像浮点数一样。在新的better
datetime2
具有更高的精度,并且始终存储十进制小数秒。无论如何,SQL 2016改变了datetime
转换为datetime2
的方式,其副作用是使涉及隐式转换的比较有时中断。在要解决此问题,请将表上的数据类型更改为datetime2(3),以获得1ms的精度。或者强制参数为datetime,而不是datetime2。我不知道pyodbc是否允许这样做,但是您可以很容易地在查询中强制转换:
现在,不是将表列转换为
datetime2
,而是将参数值转换为datetime
,比较工作如预期。在或者将数据库兼容性级别降低到120。在
相关问题 更多 >
编程相关推荐