我一直在使用cx_oracle遇到一些奇怪的行为。我有一个程序包,使用merge语句更新表。该过程采用8个值数组,所有NUMBER个都有一个VARCHAR2和一个TIMESTAMP要更新。发送的时间戳被硬编码为datetime.datetime(2017, 10, 9, 13, 20, 10)
所以当我在我的开发人员数据库和生产中从我的Windows机器运行脚本时,预期的时间戳值应为2017-10-09 13:20:10:000000
,输入的时间戳是正确的。但是当我从我的linux主机(centos)运行它时,时间戳只能在开发数据库和生产数据库上正确输入,时间戳为2017-10-09 13:20:10:005400
,其中ms / us是随机的并且每次运行都会改变。
最初我认为这是一个客户端配置问题,但是因为它在一个数据库上从同一个客户端工作而在另一个数据库上工作,并且从其他Windows客户端工作两者都有点混乱,NLS两个客户端上的设置都是相同的。
Python代码
import cx_Oracle
import datetime
import numpy as np
id_list = ['XXXX', 'XXXX', 'XXXX', 'XXX', 'XXXX']
time_list = [datetime.datetime(2017, 10, 9, 13, 20, 10),
datetime.datetime(2017, 10, 9, 13, 20, 21),
datetime.datetime(2017, 10, 9, 13, 11, 17),
datetime.datetime(2017, 10, 9, 13, 10, 1),
datetime.datetime(2017, 10, 9, 12, 7, 10),
]
bid_list = [32.09, 0, 0, 0, 0]
ask_list = [33.789, 0, 0, 0, 0]
t_list = [0, 0, 0, 0, 0]
f_m = [20, 0, 0, 0, 0]
rfv_list = [256, 45, 9, 0, 0]
fv = [10, 134, 46.0, 0, 0]
db = cx_Oracle.connect('/@wallet_user')
cursor = db.cursor()
string_arr = lambda cur, array: cur.arrayvar(cx_Oracle.STRING, array)
time_arr = lambda cur, array: cur.arrayvar(cx_Oracle.TIMESTAMP, array)
number_arr = lambda cur, array: cur.arrayvar(cx_Oracle.NUMBER, array)
p_id = string_arr(cursor, id_list)
p_time = time_arr(cursor, time_list)
p_bid = number_arr(cursor, bid_list)
p_ask = number_arr(cursor, ask_list)
p_t = number_arr(cursor, t_list)
p_futures = number_arr(cursor, f_m)
p_rfv = number_arr(cursor, rfv_list)
p_fv = number_arr(cursor, fv)
cursor.callproc('PKG_TEST.prc_load_test_values', [p_id, p_time, p_bid, p_ask, p_t, p_futures, p_rfv, p_fv])
db.commit()
cursor.close()
db.close()
PL / sql程序
PROCEDURE prc_load_load_test_values ( p_id IN aa_iepnfv_id,
p_tof IN aa_tof,
p_r_bid IN aa_iepnfv_r_bid,
p_r_ask IN aa_iepnfv_r_ask,
p_r_t IN aa_iepnfv_r_t,
p_r_fm IN aa_iepnfv_r_fm,
p_r_fv IN aa_iepnfv_r_fv,
p_fv IN aa_iepnfv_fv
)
IS
l_error_count PLS_INTEGER;
BEGIN
DBMS_UTILITY.EXEC_DDL_STATEMENT('TRUNCATE TABLE tablename');
FORALL i IN p_id.FIRST .. p_id.LAST SAVE EXCEPTIONS
INSERT INTO IRE_ETF_PRICING_NET_FAIR_VALUE
(
id,
tof,
r_bid,
r_ask,
r_t,
r_fm,
r_fv,
fv
)
VALUES
(
p_id(i),
p_tof(i),
p_r_bid(i),
p_r_ask(i),
p_r_t(i),
p_r_fm(i),
p_r_fv(i),
p_fv(i)
);
DBMS_OUTPUT.PUT_LINE('Rows inserted '||SQL%ROWCOUNT);
EXCEPTION
WHEN array_dml_exception THEN
l_error_count := SQL%BULK_EXCEPTIONS.COUNT;
FOR i IN 1 .. l_error_count LOOP
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_STACK);
DBMS_OUTPUT.PUT_LINE(CHR(10));
DBMS_OUTPUT.PUT_LINE('Error bulk load at index '|| SQL%BULK_EXCEPTIONS(i).ERROR_INDEX||' for error message '||
SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
DBMS_OUTPUT.PUT_LINE(CHR(10));
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END LOOP;
END prc_load_load_test_values;