简体   繁体   中英

Update the timestamp to current timestamp in DB2 using Python ibm_db package

I am trying to set the lastupdated timestamp in db2 to current timestamp everytime the section of my script runs

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")

on running this script I get the error

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

I have tried multiple resolutions like passing the datetime as a string as well but no luck with solving the issue this is the timestamp format used in db2 '2020-02-21 13:37:37'

If someone can please provide a way to resolve this that would be really helpful

Your update stmt is wrong. Change:

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

to:

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

or:

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

The error message you get is puzzling, but is due to the fact that you are trying to evaluate a Boolean from a string:

db2 "values 'testing' and current_timestamp = current_timestamp"

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

compare with

db2 "values true and current_timestamp = current_timestamp"

1 
--
 1

even if that succeded you would get an error trying to assign a timestamp column a boolean value.

I guess older versions of Db2 would have objected during prepare, but nowadays type checking is much more relaxed, which leads to very counter intuitive error messages from time to time

That said, you may want to look into doing:

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

Your code would then be reduced to:

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")

As a side node, I find it a bit cumbersome to explicitly bind parameters and usually just do:

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

If the purpose is just to update the timestamp whenever the row is changed, concider a trigger:

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

If you change your update statement to:

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

the trigger will do that for you:

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.

Dependent on your version of Db2, you may also look into declaring the column as:

FOR EACH ROW ON UPDATE AS ROW CHANGE TIMESTAMP

You probably want GENERATED ALWAYS, but I don't think you can alter the column to that, so you will have to do a bit more work to get that in place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM