【问题标题】:Update the timestamp to current timestamp in DB2 using Python ibm_db package使用 Python ibm_db 包将时间戳更新为 DB2 中的当前时间戳
【发布时间】:2020-04-11 18:47:58
【问题描述】:

每次我的脚本部分运行时,我都会尝试将 db2 中的 lastupdated 时间戳设置为当前时间戳

datetimes = datetime.now()
datetime1 = datetimes.strftime("%Y-%m-%d  %H:%M:%S")
datetime2 = datetime.strptime(datetime1,'%Y-%m-%d  %H:%M:%S')
print(type(datetime2))
print(datetime2)
sql = "update salesorder set LASTUPDATEUSER = 'Testing' and LASTUPDATEDATETIME = ? where code ='0888' "
prepared = ibm_db.prepare(conn, sql)
returnCode = ibm_db.bind_param(prepared,1,datetime2, ibm_db.SQL_PARAM_INPUT,ibm_db.SQL_CHAR)

if returnCode == False:
    print("unable to bind")
#ibm_db.execute(upstmt)
#param = param1
returnCode = ibm_db.execute(prepared)

if returnCode == False:
    print("unable to execut")

运行此脚本时出现错误

Traceback (most recent call last):
  File "new.py", line 27, in <module>
    returnCode = ibm_db.execute(prepared)
 SQLCODE=-420atement Execute Failed: [IBM][CLI Driver][DB2/LINUXX8664] SQL0420N  Invalid character found in a character string argument of the function "BOOLEAN".  SQLSTATE=22018

我尝试了多种解决方案,例如将日期时间作为字符串传递,但没有解决问题,这是 db2 '2020-02-21 13:37:37' 中使用的时间戳格式

如果有人可以请提供一种解决此问题的方法,这将非常有帮助

【问题讨论】:

  • 请编辑您的问题以提供这些事实(不要使用 cmets,它们会丢失)。 (1) SALESORDER 表上是否有任何触发器 (2) describe table SALESORDER 的输出是什么(查看列数据类型和可空性) (3) 是什么阻止您更新为 CURRENT TIMESTAMP 值(或适当时与 GMT 偏移) 即为什么你需要传递一个值,只是让数据库从特殊寄存器中计算出时间戳。

标签: python db2


【解决方案1】:

您的更新 stmt 错误。变化:

update salesorder 
    set LASTUPDATEUSER = 'Testing' and LASTUPDATEDATETIME = ? 
where code ='0888'

到:

update salesorder 
    set LASTUPDATEUSER = 'Testing'
      , LASTUPDATEDATETIME = ? 
where code ='0888'

或:

update salesorder 
    set (LASTUPDATEUSER, LASTUPDATEDATETIME) = ('Testing', ?) 
where code ='0888'

您收到的错误消息令人费解,但这是由于您尝试从字符串中评估布尔值:

db2 "values 'testing' and current_timestamp = current_timestamp"

1 
--
SQL0420N  Invalid character found in a character string argument of the 
function "BOOLEAN".  SQLSTATE=22018

比较

db2 "values true and current_timestamp = current_timestamp"

1 
--
 1

即使成功,您在尝试为时间戳列分配布尔值时也会出错。

我猜旧版本的 Db2 在准备期间会反对,但现在类型检查要宽松得多,这会不时导致非常反直觉的错误消息

也就是说,您可能想研究一下:

update salesorder 
    set (LASTUPDATEUSER, LASTUPDATEDATETIME) = ('Testing', current_timestamp) 
where code ='0888'

然后您的代码将简化为:

sql = """update salesorder 
        set (LASTUPDATEUSER, LASTUPDATEDATETIME) = ('Testing', current_timestamp) 
    where code ='0888'"""
prepared = ibm_db.prepare(conn, sql)
returnCode = ibm_db.execute(prepared)

if returnCode == False:
    print("unable to execut")

作为一个侧节点,我觉得显式绑定参数有点麻烦,通常只是这样做:

ibm_db.execute(prepared, (param1, ...))

如果目的只是在行更改时更新时间戳,请考虑触发器:

create trigger trg1 
no cascade before update on salesorder 
referencing new as n 
for each row 
    set n.LASTUPDATEDATETIME = current_timestamp

如果您将更新语句更改为:

update salesorder 
    set LASTUPDATEUSER = 'Testing' 
where code ='0888'

触发器会为你做到这一点:

db2 "select * from salesorder"

LASTUPDATEUSER       LASTUPDATEDATETIME         CODE 
-------------------- -------------------------- -----
Testing              2020-04-11-11.51.22.055602 0888 

  1 record(s) selected.

./aa.py

db2 "select * from salesorder"

LASTUPDATEUSER       LASTUPDATEDATETIME         CODE 
-------------------- -------------------------- -----
Testing              2020-04-11-11.58.50.222753 0888 

  1 record(s) selected.

根据您的 Db2 版本,您还可以考虑将列声明为:

FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP

您可能希望始终生成,但我认为您无法将列更改为该列,因此您必须做更多的工作才能将其落实到位。

【讨论】:

  • 非常感谢,这是一个非常清晰明了的解释并解决了问题
猜你喜欢
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-26
  • 2017-07-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多