[ruby-oci8-devel] Proposal for bind_param_array function prototype
Liming Lian
liming.lian at oracle.com
Mon Dec 17 01:55:59 EST 2007
Hi,
I have a workaround for the problem of execution count. Following is my
proposal.
We can add a function OCI8::Cursor#set_batch_size to set the iteration
count for statement execution. This function needs a parameter "size"
like following: set_batch_size(size). When users want to bind array,
they *must* call OCI8::Cursor#set_batch_size first. And they must also
make sure the size of the binding array is equal to the size declared at
set_batch_size. Otherwise, an error will be raised to prompt users
incoming array with incorrect size. Besides set_batch_size, like the
implementation of array DML in Perl DBD::ORACLE, we should also add
another function OCI8::Cursor#exec_array. Bind_param_array and
bind_param cannot be mixed in the same statement execution, and
bind_param_array *must* be used with OCI8::Cursor#exec_array; using
bind_param_array will have no effect for OCI8::Cursor#exec.
Users can call set_batch_size many times during Cursor process. But
every time at calling set_batch_size, if the new size isn't equal to the
old one, all the binds are clear from the Cursor. In that situation,
they have to re-bind all the parameter array.
Look at following usage scenarios for demonstration.
1) Correct usage
Cursor = conn.parse("INSERT INTO test_table VALUES(:name, :age)")
Cursor.set_batch_size(3)
Cursor.bind_param_array(1, ["test1", "test2", "test3"])
Cursor.bind_param_array(2, [20, 21, 22])
Cursor.exec_array
2) Correct usage
Cursor = conn.parse("INSERT INTO test_table VALUES(:name, :age)")
Cursor.set_batch_size(3)
Cursor.bind_param_array(1, nil, String)
Cursor.bind_param_array(2, nil, Fixnum)
Cursor[1] = ["test1", "test2", "test3"]
Cursor[2] = [20, 21, 22]
Cursor.exec_array
3) Correct usage
Cursor = conn.parse("INSERT INTO test_table VALUES(:name, :age)")
Cursor.set_batch_size(3)
Cursor.bind_param_array(1, ["test1", "test2", "test3"])
Cursor.bind_param_array(2, [20, 21, 22])
Cursor.set_batch_size(2)
Cursor.bind_param_array(1, ["test4", "test5"])
Cursor.bind_param_array(2, [23, 24])
Cursor.exec_array
4) Incorrect usage
Cursor = conn.parse("INSERT INTO test_table VALUES(:name, :age)")
Cursor.bind_param_array(1, ["test1", "test2"])
Cursor.bind_param_array(2, [20, 21])
Cursor.exec_array
== Error raised: should call set_batch_size first
5) Incorrect usage
Cursor = conn.parse("INSERT INTO test_table VALUES(:name, :age)")
Cursor.set_batch_size(3)
Cursor.bind_param_array(1, ["test1", "test2"])
Cursor.bind_param_array(2, [20, 21])
Cursor.exec_array
== Error raised: incorrect incoming bound array size
6) Incorrect usage
Cursor = conn.parse("INSERT INTO test_table VALUES(:name, :age)")
Cursor.set_batch_size(3)
Cursor.bind_param_array(1, ["test1", "test2"])
Cursor.bind_param_array(2, [20, 21])
Cursor.exec
== Error raised: should call exec_array to process array DML
7) Incorrect usage
Cursor = conn.parse("INSERT INTO test_table VALUES(:name, :age)")
Cursor.set_batch_size(3)
Cursor.bind_param_array(1, ["test1", "test2"])
Cursor.bind_param_array(2, [20, 21])
Cursor.set_batch_size(2)
Cursor.exec_array
== Error raised: OCIError: ORA-01008: not all variables bound
== Reason: didn't re-bind the array after calling set_batch_size with a
new batch size
With the new function set_batch_size, the function bind_param_array
doesn't need a parameter "max_array_size" any more. The parameter size
passed to set_batch_size will be used as max_array_size internally. So
the prototype of bind_param_array has been updated to:
bind_param_array(key, var_array, type = nil, max_item_length = nil)
Liming
> I haven't fully tested the above modifications but I can insert String
> arrays without any problem. The "Cursor[Key] = val" doesn't cause
> problem with bind_param, because the iteration count for a normal insert
> is always 1. In case of array insert, the iteration count changes with
> calling of "Cursor[Key] = val". Obviously it is unrealistic to make
> assumption as what I mentioned above. So I am thinking other ways to get
> the exact size of the array user has bound at the calling of cursor.exec.
>
> Hope I am clear. Any ideas?
>
> _______________________________________________
> ruby-oci8-devel mailing list
> ruby-oci8-devel at rubyforge.org
> http://rubyforge.org/mailman/listinfo/ruby-oci8-devel
>
More information about the ruby-oci8-devel
mailing list