Hi,

Hoping someone can help me here as I'm really stuck with this. I have a large amount of code which reads some XML and inserts data from the XML into a database. One particular insert fails:

insert into document (book,category,country,expiry,id,last_update,mnem,name,odec,route,source,tdate,ttimestamp,ttype,version) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)

and the parameters are:

SD, HR, UK, 2017-07-08 14:10:00, XXXXXXXXXXX, 1183290197812, XX, xxxxx, N, 534453, xxxxxxxxxx, 2007-07-01, 1183269593843, xxxxxx, 1.2.6

the error is:

DBD::Oracle::st execute failed: ORA-01843: not a valid month (DBD ERROR: error possibly near <*> indicator at char 146 in 'insert into document (book,category,country,expiry,id,last_update,mnem,name,odec,route,source,tdate,ttimestamp,ttype,version) values(:p1,:p2,:p3,:<*>p4,:p5,:p6,:p7,:p8,:p9,:p10,:p11,:p12,:p13,:p14,:p15)') at /usr/lib/perl5/site_perl/5.8.8/DBIx/Log4perl/st.pm line 38.

There is nothing obviously wrong with p4 and 2017-07-08 14:10:00 as the session was previously altered to set the nls_timestamp_format to 'yyyy-mm-dd hh24:mi:ss. I have even verified that by looking at NLS_SESSION_PARAMETERS just before the execute call.

After much head scratching I discovered the problem P4 has utf8 set on it and downgrading it makes the code work i.e. when utf8::is_utf8 returns 1 on the timestamp scalar it fails and if I do a utf8::downgrade(scalar) on it before calling execute it works.

When I examine a DBD:Oracle (v 1.19 BTW) trace file the only difference I can see between the one that fails:

       bind :p4 <== "2017-07-08 14:10:00" (type 0)
       rebinding :p4 (is-utf8, ftype 1, csid 0, csform 0, inout 0)
       bind :p4 <== "2017-07-08 14:10:00" (size 19/20/0, ptype 4, otype 1)
bind :p4 <== '2017-07-08 14:10:00' (size 19/19, otype 1, indp 0, at_exec 1)
OCIBindByName(8ef1a50,8ed3a8c,8dfdad8,":p4",3,8ece658,19,1,8ed3aa4,0,8ed3
a9c,0,0,2)=SUCCESS
OCIBindDynamic(8ef1460,8dfdad8,8ed3a68,cfece0,8ed3a68,cfefc0)=SUCCESS
rebinding :p4 with UTF8 value so setting csform=SQLCS_IMPLICIT OCIAttrSet(8ef1460,OCI_HTYPE_BIND,bfc3a76b,0,32,8dfdad8)=SUCCESS
        OCIAttrGet(8ef1460,OCI_HTYPE_BIND,8ed3a78,0,31,8dfdad8)=SUCCESS
bind :p4 <== "2017-07-08 14:10:00" (in, is-utf8, csid 873->0->873, ftype 1, csform 0->2, maxlen 19, maxdata_size 0)
        OCIAttrSet(8ef1460,OCI_HTYPE_BIND,bfc3a768,0,31,8dfdad8)=SUCCESS

and the successful one:

       bind :p4 <== '2017-07-08 14:10:00' (type 0)
       rebinding :p4 (not-utf8, ftype 1, csid 0, csform 0, inout 0)
       bind :p4 <== '2017-07-08 14:10:00' (size 19/20/0, ptype 4, otype 1)
bind :p4 <== '2017-07-08 14:10:00' (size 19/19, otype 1, indp 0, at_exec 1)
OCIBindByName(9330bc8,9315214,923ed10,":p4",3,926b1e0,19,1,931522c,0,9315
224,0,0,2)=SUCCESS
OCIBindDynamic(93305d8,923ed10,93151f0,1c4ce0,93151f0,1c4fc0)=SUCCESS
OCIAttrGet(93305d8,OCI_HTYPE_BIND,9315200,0,31,923ed10)=SUCCESS
bind :p4 <== '2017-07-08 14:10:00' (in, not-utf8, csid 873->0->873, ftype 1, csform 0->0, maxlen 19, maxdata_size 0)

is the us-utf8 versus not-utf8.

I have tried reducing the problem to a small script but just setting the UTF8 flag on any timestamp does not make it fail so I'm unsure where to go now. Any ideas?

Martin
--
Martin J. Evans
Easysoft Limited
http://www.easysoft.com

Reply via email to