| Message: 92907 |
 |
BY: Ronald Roy (rjroy) DATE: 2010-03-02 01:22 SUBJECT: char(1) causes 'negative string size' error I have a table processing_dates with a status column of char(1). I use a stored proc to get me the most recent processing_date. I can bind to all the out params of the stored proc, but when I get the value from the cursor it causes a "negative string size" ArgumentError to be raised. I actually hacked a solution by modifying bind_string_get within bind.c to convert all negative string lengths to 1. This works, but I don't think its a general solution.
Below is some slightly modified versions of the table, stored, proc, and the ruby code that failed.
------
CREATE TABLE "processing_dates"
( "processing_date_id" NUMBER NOT NULL ENABLE,
"processing_date" DATE DEFAULT SYSDATE NOT NULL ENABLE,
"status" CHAR(1 BYTE) DEFAULT '0' NOT NULL ENABLE);
PROCEDURE GetLastProcessingDate(
poProcessingDateID OUT processing_dates.processing_date_id%TYPE,
poProcessingDate OUT processing_dates.processing_date%TYPE,
poStatus OUT processing_dates.status%TYPE )
AS BEGIN
SELECT processing_date_id, processing_date, status
INTO poProcessingDateID, poProcessingDate, poStatus
FROM ( SELECT processing_date_id, processing_date, status
FROM processing_dates ORDER BY processing_date_id DESC)
WHERE rownum <= 1;
END GetLastProcessingDate;
---------
# @conn is the OCI8 to the database
cursor = @conn.parse('BEGIN GetLastProcessingDate( :id, :date, :status ); END;')
cursor.bind_param(':id', nil, Integer)
cursor.bind_param(':date', nil, Time)
cursor.bind_param(':status', '0', String, 1)
cursor.exec
@processing_date = cursor[':date']
@processing_date_id = cursor[':id']
# The next line raises an ArgumentException: negative string size
@status = cursor[':status']
-----
// The 100% hack I did was to add a 'sz' variable to the bind_string_get method.
// Below is the 100% hack from bind.c:
static VALUE bind_string_get(oci8_bind_t *obind, void *data, void *null_struct)
{
int sz;
oci8_vstr_t *vstr = (oci8_vstr_t *)data;
sz = vstr->size;
if (sz < 0) sz = 1;
return rb_external_str_new_with_enc(vstr->buf, sz, oci8_encoding);
}
-----
Please let me know if you need any more details.
| |