pyodbc: ORACLE SQL 带有包含日期范围的 WHERE 子句的语句
pyodbc: ORACLE SQL Statement with WHERE Clause that incorporates date range
我正在使用 pyodbc 从数据库中提取数据 table。现在,我想将查询限制为仅包含最近 24 小时内添加的记录。有关添加记录时间的信息包含在 DATE_ADDED
柱子 。
这就是我正在尝试的:
pyodbc.pooling = False
conn_str = (
r'DRIVER={Oracle in OraClient12Home1};'
.....
.....
.....)
conn = pyodbc.connect(conn_str)
curs = conn.cursor()
date_today = datetime.datetime.today()
date_yesterday = date_today - datetime.timedelta(days=1)
sql = f"SELECT PROD_ID, ID, COUNT, DATE_ADDED FROM LZE.APODAT WHERE DATE_ADDED < {date_today} AND DATE_ADDED > {date_yesterday}"
my_df = pd.DataFrame(pd.read_sql(sql, conn))
我收到的错误信息是:
UnicodeDecodeError: 'utf-16-le' codec can't decode bytes in position
218-219: illegal encoding
我确定它与 DATE_ADDED
列的不同 formatting/data 类型有关,但我不确定如何处理这个问题。在数据库中它看起来如下:2019-04-24 10:21:05 AM
如有任何帮助,我们将不胜感激。
你说你想要最后 24 小时...
您可以在 where 子句中说 DATE_ADDED >= SYSDATE() - 1.0
来获取它。 SYSDATE()
让您感受当下。 oracle 中的日期表现得像浮点数,其中 1.0 是 24 小时。因此,从现在减去 1.0 得到昨天相同的时间。
如果您想要从昨天午夜开始的所有内容,您可以truncate日期。使用
DATE_ADDED >= TRUNC(SYSDATE() - 1.0)
考虑参数化(在应用层使用 SQL 时的行业标准),因为 Python 的 datetime
对象可能会转换为 Oracle 的 date
类型。
是的,您可以使用 params 参数在 Pandas 和 read_sql()
中进行参数化(不需要 pd.DataFrame()
包装器) .另外,您不需要 F-strings,因此此版本可以在任何 Python 版本中使用。
sql = """SELECT PROD_ID, ID, COUNT, DATE_ADDED
FROM LZE.APODAT
WHERE DATE_ADDED < ? AND DATE_ADDED > ?
"""
my_df = pd.read_sql(sql, conn, params=[date_today, date_yesterday])
否则转换为字符串(去除十进制微秒)并使用 Oracle 的 TO_DATE()
:
sql = """SELECT PROD_ID, ID, COUNT, DATE_ADDED
FROM LZE.APODAT
WHERE DATE_ADDED < TO_DATE(?, 'YYYY-MM-DD HH:MI:SS')
AND DATE_ADDED > TO_DATE(?, 'YYYY-MM-DD HH:MI:SS')?
"""
my_df = pd.read_sql(sql, conn, params=[date_today.strftime("%Y-%m-%d %H:%M:%S"),
date_yesterday.strftime("%Y-%m-%d %H:%M:%S")]
)
我正在使用 pyodbc 从数据库中提取数据 table。现在,我想将查询限制为仅包含最近 24 小时内添加的记录。有关添加记录时间的信息包含在 DATE_ADDED
柱子 。
这就是我正在尝试的:
pyodbc.pooling = False
conn_str = (
r'DRIVER={Oracle in OraClient12Home1};'
.....
.....
.....)
conn = pyodbc.connect(conn_str)
curs = conn.cursor()
date_today = datetime.datetime.today()
date_yesterday = date_today - datetime.timedelta(days=1)
sql = f"SELECT PROD_ID, ID, COUNT, DATE_ADDED FROM LZE.APODAT WHERE DATE_ADDED < {date_today} AND DATE_ADDED > {date_yesterday}"
my_df = pd.DataFrame(pd.read_sql(sql, conn))
我收到的错误信息是:
UnicodeDecodeError: 'utf-16-le' codec can't decode bytes in position 218-219: illegal encoding
我确定它与 DATE_ADDED
列的不同 formatting/data 类型有关,但我不确定如何处理这个问题。在数据库中它看起来如下:2019-04-24 10:21:05 AM
如有任何帮助,我们将不胜感激。
你说你想要最后 24 小时...
您可以在 where 子句中说 DATE_ADDED >= SYSDATE() - 1.0
来获取它。 SYSDATE()
让您感受当下。 oracle 中的日期表现得像浮点数,其中 1.0 是 24 小时。因此,从现在减去 1.0 得到昨天相同的时间。
如果您想要从昨天午夜开始的所有内容,您可以truncate日期。使用
DATE_ADDED >= TRUNC(SYSDATE() - 1.0)
考虑参数化(在应用层使用 SQL 时的行业标准),因为 Python 的 datetime
对象可能会转换为 Oracle 的 date
类型。
是的,您可以使用 params 参数在 Pandas 和 read_sql()
中进行参数化(不需要 pd.DataFrame()
包装器) .另外,您不需要 F-strings,因此此版本可以在任何 Python 版本中使用。
sql = """SELECT PROD_ID, ID, COUNT, DATE_ADDED
FROM LZE.APODAT
WHERE DATE_ADDED < ? AND DATE_ADDED > ?
"""
my_df = pd.read_sql(sql, conn, params=[date_today, date_yesterday])
否则转换为字符串(去除十进制微秒)并使用 Oracle 的 TO_DATE()
:
sql = """SELECT PROD_ID, ID, COUNT, DATE_ADDED
FROM LZE.APODAT
WHERE DATE_ADDED < TO_DATE(?, 'YYYY-MM-DD HH:MI:SS')
AND DATE_ADDED > TO_DATE(?, 'YYYY-MM-DD HH:MI:SS')?
"""
my_df = pd.read_sql(sql, conn, params=[date_today.strftime("%Y-%m-%d %H:%M:%S"),
date_yesterday.strftime("%Y-%m-%d %H:%M:%S")]
)