• Bug#1032142: marked as done (unblock: libdbd-oracle-perl/1.83-1) (6/11)

    From Debian Bug Tracking System@21:1/5 to All on Tue Feb 28 22:20:01 2023
    [continued from previous message]

    -stick to one style within your program.
    -
    -## **prepare\_cached**
    -
    - $sth = $dbh->prepare_cached($statement, \%attr);
    -
    -Implemented by DBI, no driver-specific impact. This method is most useful
    -if the same query is used over and over as it will cut down round trips to the server.
    -
    -## **do**
    -
    - $rv = $dbh->do($statement);
    - $rv = $dbh->do($statement, \%attr);
    - $rv = $dbh->do($statement, \%attr, @bind_values);
    -
    -Prepare and execute a single statement. Returns the number of rows affected if the
    -query was successful, returns undef if an error occurred, and returns -1 if the
    -number of rows is unknown or not available. Note that this method will return **0E0** instead
    -of 0 for 'no rows were affected', in order to always return a true value if no error occurred.
    -
    -## **last\_insert\_id**
    -
    -Oracle does not implement auto\_increment of serial type columns it uses predefined
    -sequences where the id numbers are either selected before insert, at insert time with a trigger,
    - or as part of the query.
    -
    -Below is an example of you to use the latter with the SQL returning clause to get the ID number back
    -on insert with the bind\_param\_inout method.
    -.
    -
    - $dbh->do('CREATE SEQUENCE lii_seq START 1');
    - $dbh->do(q{CREATE TABLE lii (
    - foobar INTEGER NOT NULL UNIQUE,
    - baz VARCHAR)});
    - $SQL = "INSERT INTO lii (foobar,baz) VALUES (lii_seq.nextval,'XX') returning foobar into :p_new_id";";
    - $sth = $dbh->prepare($SQL);
    - my $p_new_id='-1';
    - $sth->bind_param_inout(":p_new_id",\$p_new_id,38);
    - $sth->execute();
    - $db->commit();
    -
    -## **commit**
    -
    - $rv = $dbh->commit;
    -
    -Issues a COMMIT to the server, indicating that the current transaction is finished and that
    -all changes made will be visible to other processes. If AutoCommit is enabled, then
    -a warning is given and no COMMIT is issued. Returns true on success, false on error.
    -
    -## **rollback**
    -
    - $rv = $dbh->rollback;
    -
    -Issues a ROLLBACK to the server, which discards any changes made in the current transaction. If AutoCommit
    -is enabled, then a warning is given and no ROLLBACK is issued. Returns true on success, and
    -false on error.
    -
    -## **begin\_work**
    -
    -This method turns on transactions until the next call to ["commit"](#commit) or ["rollback"](#rollback), if ["AutoCommit"](#autocommit) is
    -currently enabled. If it is not enabled, calling begin\_work will issue an error. Note that the
    -transaction will not actually begin until the first statement after begin\_work is called.
    -
    -## **disconnect**
    -
    - $rv = $dbh->disconnect;
    -
    -Disconnects from the Oracle database. Any uncommitted changes will be rolled back upon disconnection. It's
    -good policy to always explicitly call commit or rollback at some point before disconnecting, rather than
    -relying on the default rollback behavior.
    -
    -If the script exits before disconnect is called (or, more precisely, if the database handle is no longer
    -referenced by anything), then the database handle's DESTROY method will call the rollback() and disconnect()
    -methods automatically. It is best to explicitly disconnect rather than rely on this behavior.
    -
    -## **ping**
    -
    - $rv = $dbh->ping;
    -
    -This `ping` method is used to check the validity of a database handle. The value returned is
    -either 0, indicating that the connection is no longer valid, or 1, indicating the connection is valid.
    -This function does 1 round trip to the Oracle Server.
    -
    -## **get\_info()**
    -
    - $value = $dbh->get_info($info_type);
    -
    -DBD::Oracle supports `get_info()`, but (currently) only a few info types.
    -
    -## **table\_info()**
    -
    -DBD::Oracle supports attributes for `table_info()`.
    -
    -In Oracle, the concept of _user_ and _schema_ is (currently) the
    -same. Because database objects are owned by an user, the owner names
    -in the data dictionary views correspond to schema names.
    -Oracle does not support catalogues so TABLE\_CAT is ignored as
    -selection criterion.
    -
    -Search patterns are supported for TABLE\_SCHEM and TABLE\_NAME.
    -
    -TABLE\_TYPE may contain a comma-separated list of table types.
    -The following table types are supported:
    -
    - TABLE
    - VIEW
    - SYNONYM
    - SEQUENCE
    -
    -The result set is ordered by TABLE\_TYPE, TABLE\_SCHEM, TABLE\_NAME.
    -
    -The special enumerations of catalogues, schemas and table types are -supported. However, TABLE\_CAT is always NULL.
    -
    -An identifier is passed _as is_, i.e. as the user provides or
    -Oracle returns it.
    -`table_info()` performs a case-sensitive search. So, a selection
    -criterion should respect upper and lower case.
    -Normally, an identifier is case-insensitive. Oracle stores and
    -returns it in upper case. Sometimes, database objects are created
    -with quoted identifiers (for reserved words, mixed case, special
    -characters, ...). Such an identifier is case-sensitive (if not all
    -upper case). Oracle stores and returns it as given.
    -`table_info()` has no special quote handling, neither adds nor
    -removes quotes.
    -
    -## **primary\_key\_info()**
    -
    -Oracle does not support catalogues so TABLE\_CAT is ignored as
    -selection criterion.
    -The TABLE\_CAT field of a fetched row is always NULL (undef).
    -See ["table\_info()"](#table_info) for more detailed information.
    -
    -If the primary key constraint was created without an identifier,
    -PK\_NAME contains a system generated name with the form SYS\_Cn.
    -
    -The result set is ordered by TABLE\_SCHEM, TABLE\_NAME, KEY\_SEQ.
    -
    -An identifier is passed _as is_, i.e. as the user provides or
    -Oracle returns it.
    -See ["table\_info()"](#table_info) for more detailed information.
    -
    -## **foreign\_key\_info()**
    -
    -This method (currently) supports the extended behaviour of SQL/CLI, i.e. the -result set contains foreign keys that refer to primary **and** alternate keys. -The field UNIQUE\_OR\_PRIMARY distinguishes these keys.
    -
    -Oracle does not support catalogues, so `$pk_catalog` and `$fk_catalog` are -ignored as selection criteria (in the new style interface).
    -The UK\_TABLE\_CAT and FK\_TABLE\_CAT fields of a fetched row are always
    -NULL (undef).
    -See ["table\_info()"](#table_info) for more detailed information.
    -
    -If the primary or foreign key constraints were created without an identifier, -UK\_NAME or FK\_NAME contains a system generated name with the form SYS\_Cn.
    -
    -The UPDATE\_RULE field is always 3 ('NO ACTION'), because Oracle (currently) -does not support other actions.
    -
    -The DELETE\_RULE field may contain wrong values. This is a known Bug (#1271663)
    -in Oracle's data dictionary views. Currently (as of 8.1.7), 'RESTRICT' and -'SET DEFAULT' are not supported, 'CASCADE' is mapped correctly and all other -actions (incl. 'SET NULL') appear as 'NO ACTION'.
    -
    -The DEFERABILITY field is always NULL, because this columns is
    -not present in the ALL\_CONSTRAINTS view of older Oracle releases.
    -
    -The result set is ordered by UK\_TABLE\_SCHEM, UK\_TABLE\_NAME, FK\_TABLE\_SCHEM,
    -FK\_TABLE\_NAME, ORDINAL\_POSITION.
    -
    -An identifier is passed _as is_, i.e. as the user provides or
    -Oracle returns it.
    -See ["table\_info()"](#table_info) for more detailed information.
    -
    -## **column\_info()**
    -
    -Oracle does not support catalogues so TABLE\_CAT is ignored as
    -selection criterion.
    -The TABLE\_CAT field of a fetched row is always NULL (undef).
    -See ["table\_info()"](#table_info) for more detailed information.
    -
    -The CHAR\_OCTET\_LENGTH field is (currently) always NULL (undef).
    -
    -Don't rely on the values of the BUFFER\_LENGTH field!
    -Especially the length of FLOATs may be wrong.
    -
    -Datatype codes for non-standard types are subject to change.
    -
    -Attention! The DATA\_DEFAULT (COLUMN\_DEF) column is of type LONG so you
    -may have to set LongReadLen on the connection handle before calling -column\_info if you have a large default column. After DBD::Oracle 1.40 -LongReadLen is set automatically to 1Mb when calling column\_info and
    -reset aftwerwards.
    -
    -The result set is ordered by TABLE\_SCHEM, TABLE\_NAME, ORDINAL\_POSITION.
    -
    -An identifier is passed _as is_, i.e. as the user provides or
    -Oracle returns it.
    -See ["table\_info()"](#table_info) for more detailed information.
    -
    -It is possible with Oracle to make the names of the various DB objects (table,column,index etc)
    -case sensitive.
    -
    - alter table bloggind add ("Bla_BLA" NUMBER)
    -
    -So in the example the exact case "Bla\_BLA" must be used to get it info on the column. While this
    -
    - alter table bloggind add (Bla_BLA NUMBER)
    -
    -any case can be used to get info on the column.
    -
    -## **statistics\_info()**
    -
    -Oracle does not support catalogues so TABLE\_CAT is ignored as
    -selection criterion.
    -The TABLE\_CAT field of a fetched row is always NULL (undef).
    -See ["table\_info()"](#table_info) for more detailed information.
    -
    -The INDEX\_QUALIFIER field of a fetched row is always NULL (undef),
    -for the same reason as for TABLE\_CAT.
    -
    -If an index was created without an identifier
    -(e.g. in the course of a PK creation),
    -INDEX\_NAME contains a system generated name with the form SYS\_.
    -
    -COLUMN\_NAME may contain a system generated name
    -(e.g. for function-based indexes).
    -
    -For the TYPE column, a simple mapping is used:
    -
    - NORMAL btree
    - CLUSTER clustered
    - ... other
    -
    -The `$quick` parameter is currently ignored.
    -The method uses the dictionary with the gathered statistics,
    -thus cannot ensure that the values for CARDINALITY and PAGES are current.
    -
    -The result set is ordered by
    -NON\_UNIQUE, TYPE, INDEX\_QUALIFIER, INDEX\_NAME, ORDINAL\_POSITION.
    -
    -An identifier is passed _as is_, i.e. as the user provides or
    -Oracle returns it.
    -See ["table\_info()"](#table_info) for more detailed information.
    -
    -## **selectrow\_array**
    -
    - @row_ary = $dbh->selectrow_array($sql);
    - @row_ary = $dbh->selectrow_array($sql, \%attr);
    - @row_ary = $dbh->selectrow_array($sql, \%attr, @bind_values);
    -
    -Returns an array of row information after preparing and executing the provided SQL string. The rows are returned
    -by calling ["fetchrow\_array"](#fetchrow_array). The string can also be a statement handle generated by a previous prepare. Note that
    -only the first row of data is returned. If called in a scalar context, only the first column of the first row is
    -returned. Because this is not portable, it is not recommended that you use this method in that way.
    -
    -## **selectrow\_arrayref**
    -
    - $ary_ref = $dbh->selectrow_arrayref($statement);
    - $ary_ref = $dbh->selectrow_arrayref($statement, \%attr);
    - $ary_ref = $dbh->selectrow_arrayref($statement, \%attr, @bind_values);
    -
    -Exactly the same as ["selectrow\_array"](#selectrow_array), except that it returns a reference to an array, by internal use of
    -the ["fetchrow\_arrayref"](#fetchrow_arrayref) method.
    -
    -## **selectrow\_hashref**
    -
    - $hash_ref = $dbh->selectrow_hashref($sql);
    - $hash_ref = $dbh->selectrow_hashref($sql, \%attr);
    - $hash_ref = $dbh->selectrow_hashref($sql, \%attr, @bind_values);
    -
    -Exactly the same as ["selectrow\_array"](#selectrow_array), except that it returns a reference to an hash, by internal use of
    -the ["fetchrow\_hashref"](#fetchrow_hashref) method.
    -
    -## **clone**
    -
    - $other_dbh = $dbh->clone();
    -
    -Creates a copy of the database handle by connecting with the same parameters as the original
    -handle, then trying to merge the attributes. See the DBI documentation for complete usage.
    -
    -# DATABASE HANDLE ATTRIBUTES
    -
    -## **AutoCommit** (boolean)
    -
    -Supported by DBD::Oracle as proposed by DBI.The default of AutoCommit is on, but this may change
    -in the future, so it is highly recommended that you explicitly set it when -calling ["connect"](#connect).
    -
    -## **ReadOnly** (boolean)
    -
    - $dbh->{ReadOnly} = 1;
    -
    -Specifies if the current database connection should be in read-only mode or not.
    -
    -Please not that this method is not foolproof: there are still ways to update the
    -database. Consider this a safety net to catch applications that should not be -issuing commands such as INSERT, UPDATE, or DELETE.
    -
    -This method method requires DBI version 1.55 or better.
    -
    -## **Name** (string, read-only)
    -
    -Returns the name of the current database. This is the same as the DSN, without the
    -"dbi:Oracle:" part.
    -
    -## **Username** (string, read-only)
    -
    -Returns the name of the user connected to the database.
    -
    -## **Driver** (handle, read-only)
    -
    -Holds the handle of the parent driver. The only recommended use for this is to find the name
    -of the driver using:
    -
    - $dbh->{Driver}->{Name}
    -
    -## **RowCacheSize**
    -
    -DBD::Oracle supports both Server pre-fetch and Client side row caching. By default both
    -are turned on to give optimum performance. Most of the time one can just let DBD::Oracle
    -figure out the best optimization.
    -
    -### **Row Caching**
    -
    -Row caching occurs on the client side and the object of it is to cut down the number of round
    -trips made to the server when fetching rows. At each fetch a set number of rows will be retrieved
    -from the server and stored locally. Further calls the server are made only when the end of the
    -local buffer(cache) is reached.
    -
    -Rows up to the specified top level row
    -count `RowCacheSize` are fetched if it occupies no more than the specified memory usage limit.
    -The default value is 0, which means that memory size is not included in computing the number of rows to prefetch. If
    -the `RowCacheSize` value is set to a negative number then the positive value of RowCacheSize is used
    -to compute the number of rows to prefetch.
    -
    -By default `RowCacheSize` is automatically set. If you want to totally turn off prefetching set this to 1.
    -
    -For any SQL statement that contains a LOB, Long or Object Type Row Caching will be turned off. However server side
    -caching still works. If you are only selecting a LOB Locator then Row Caching will still work.
    -
    -### Row Prefetching
    -
    -Row prefetching occurs on the server side and uses the DBI database handle attribute `RowCacheSize` and or the
    -Prepare Attribute 'ora\_prefetch\_memory'. Tweaking these values may yield improved performance.
    -
    - $dbh->{RowCacheSize} = 100;
    - $sth=$dbh->prepare($SQL,{ora_exe_mode=>OCI_STMT_SCROLLABLE_READONLY,ora_prefetch_memory=>10000});
    -
    -In the above example 10 rows will be prefetched up to a maximum of 10000 bytes of data. The Oracle Call Interface Programmer's Guide,
    -suggests a good row cache value for a scrollable cursor is about 20% of expected size of the record set.
    -
    -The prefetch settings tell the DBD::Oracle to grab x rows (or x-bytes) when it needs to get new rows. This happens on the first
    -fetch that sets the current position to any value other than 0. In the above example if we do a OCI\_FETCH\_FIRST the first 10 rows are
    -loaded into the buffer and DBD::Oracle will not have to go back to the server for more rows. When record 11 is fetched DBD::Oracle
    -fetches and returns this row and the next 9 rows are loaded into the buffer. In this case if you fetch backwards from 10 to 1
    -no server round trips are made.
    -
    -With large record sets it is best not to attempt to go to the last record as this may take some time, A large buffer size might even slow down
    -the fetch. If you must get the number of rows in a large record set you might try using an few large OCI\_FETCH\_ABSOLUTEs and then an OCI\_FETCH\_LAST,
    -this might save some time. So if you had a record set of 10000 rows and you set the buffer to 5000 and did a OCI\_FETCH\_LAST one would fetch the first 5000 rows into the buffer then the next 5000 rows.
    -If one requires only the first few rows there is no need to set a large prefetch value.
    -
    -If the ora\_prefetch\_memory less than 1 or not present then memory size is not included in computing the
    -number of rows to prefetch otherwise the number of rows will be limited to memory size. Likewise if the RowCacheSize is less than 1 it
    -is not included in the computing of the prefetch rows.
    -
    -# ORACLE-SPECIFIC STATEMENT HANDLE METHODS
    -
    -## **ora\_stmt\_type**
    -
    -Returns the OCI Statement Type number for the SQL of a statement handle.
    -
    -## **ora\_stmt\_type\_name**
    -
    -Returns the OCI Statement Type name for the SQL of a statement handle.
    -
    -# DBI STATEMENT HANDLE OBJECT METHODS
    -
    -## **bind\_param**
    -
    - $rv = $sth->bind_param($param_num, $bind_value);
    - $rv = $sth->bind_param($param_num, $bind_value, $bind_type);
    - $rv = $sth->bind_param($param_num, $bind_value, \%attr);
    -
    -Allows the user to bind a value and/or a data type to a placeholder.
    -
    -The value of `$param_num` is a number if using the '?' or if using ":foo" style placeholders, the complete name
    -(e.g. ":foo") must be given.
    -The `$bind_value` argument is fairly self-explanatory. A value of `undef` will -bind a `NULL` to the placeholder. Using `undef` is useful when you want
    -to change just the type and will be overwriting the value later.
    -(Any value is actually usable, but `undef` is easy and efficient).
    -
    -The `\%attr` hash is used to indicate the data type of the placeholder.
    -The default value is "varchar". If you need something else, you must
    -use one of the values provided by DBI or by DBD::Oracle. To use a SQL value, -modify your "use DBI" statement at the top of your script as follows:
    -
    - use DBI qw(:sql_types);
    -
    -This will import some constants into your script. You can plug those
    -directly into the ["bind\_param"](#bind_param) call. Some common ones that you will
    -encounter are:
    -
    - SQL_INTEGER
    -
    -To use Oracle SQL data types, import the list of values like this:
    -
    - use DBD::Oracle qw(:ora_types);
    -
    -You can then set the data types by setting the value of the `ora_type`
    -key in the hash passed to ["bind\_param"](#bind_param).
    -The current list of Oracle data types exported is:
    -
    - ORA_VARCHAR2 ORA_STRING ORA_NUMBER ORA_LONG ORA_ROWID ORA_DATE ORA_RAW
    - ORA_LONGRAW ORA_CHAR ORA_CHARZ ORA_MLSLABEL ORA_XMLTYPE ORA_CLOB ORA_BLOB - ORA_RSET ORA_VARCHAR2_TABLE ORA_NUMBER_TABLE SQLT_INT SQLT_FLT ORA_OCI
    - SQLT_CHR SQLT_BIN
    -
    -Data types are "sticky," in that once a data type is set to a certain placeholder,
    -it will remain for that placeholder, unless it is explicitly set to something -else afterwards. If the statement has already been prepared, and you switch the
    -data type to something else, DBD::Oracle will re-prepare the statement for you before
    -doing the next execute.
    -
    -Examples:
    -
    - use DBI qw(:sql_types);
    - use DBD::Oracle qw(:ora_types);
    -
    - $SQL = "SELECT id FROM ptable WHERE size > ? AND title = ?";
    - $sth = $dbh->prepare($SQL);
    -
    - ## Both arguments below are bound to placeholders as "varchar"
    - $sth->execute(123, "Merk");
    -
    - ## Reset the datatype for the first placeholder to an integer
    - $sth->bind_param(1, undef, SQL_INTEGER);
    -
    - ## The "undef" bound above is not used, since we supply params to execute - $sth->execute(123, "Merk");
    -
    - ## Set the first placeholder's value and data type
    - $sth->bind_param(1, 234, { pg_type => ORA_NUMBER });
    -
    - ## Set the second placeholder's value and data type.
    - ## We don't send a third argument, so the default "varchar" is used
    - $sth->bind_param('$2', "Zool");
    -
    - ## We realize that the wrong data type was set above, so we change it:
    - $sth->bind_param('$1', 234, { pg_type => SQL_INTEGER });
    -
    - ## We also got the wrong value, so we change that as well.
    - ## Because the data type is sticky, we don't need to change it
    - $sth->bind_param(1, 567);
    -
    - ## This executes the statement with 567 (integer) and "Zool" (varchar)
    - $sth->execute();
    -
    -These attributes may be used in the `\%attr` parameter of the
    -["bind\_param" in DBI](https://metacpan.org/pod/DBI#bind_param) or ["bind\_param\_inout" in DBI](https://metacpan.org/pod/DBI#bind_param_inout) statement handle methods.
    -
    -- ora\_type
    -
    - Specify the placeholder's datatype using an Oracle datatype.
    - A fatal error is raised if `ora_type` and the DBI `TYPE` attribute
    - are used for the same placeholder.
    - Some of these types are not supported by the current version of
    - DBD::Oracle and will cause a fatal error if used.
    - Constants for the Oracle datatypes may be imported using
    -
    - use DBD::Oracle qw(:ora_types);
    -
    - Potentially useful values when DBD::Oracle was built using OCI 7 and later:
    -
    - ORA_VARCHAR2, ORA_STRING, ORA_LONG, ORA_RAW, ORA_LONGRAW,
    - ORA_CHAR, ORA_MLSLABEL, ORA_RSET
    -
    - Additional values when DBD::Oracle was built using OCI 8 and later:
    -
    - ORA_CLOB, ORA_BLOB, ORA_XMLTYPE, ORA_VARCHAR2_TABLE, ORA_NUMBER_TABLE -
    - Additional values when DBD::Oracle was built using OCI 9.2 and later:
    -
    - SQLT_CHR, SQLT_BIN
    -
    - See ["Binding Cursors"](#binding-cursors) for the correct way to use ORA\_RSET.
    -
    - See ["LOBS AND LONGS"](#lobs-and-longs) for how to use ORA\_CLOB and ORA\_BLOB.
    -
    - See ["SYS.DBMS\_SQL datatypes"](#sys-dbms_sql-datatypes) for ORA\_VARCHAR2\_TABLE, ORA\_NUMBER\_TABLE.
    -
    - See ["Data Interface for Persistent LOBs"](#data-interface-for-persistent-lobs) for the correct way to use SQLT\_CHR and SQLT\_BIN.
    -
    - See ["OTHER DATA TYPES"](#other-data-types) for more information.
    -
    - See also ["Placeholders and Bind Values" in DBI](https://metacpan.org/pod/DBI#Placeholders-and-Bind-Values).
    -
    -- ora\_csform
    -
    - Specify the OCI\_ATTR\_CHARSET\_FORM for the bind value. Valid values
    - are SQLCS\_IMPLICIT (1) and SQLCS\_NCHAR (2). Both those constants can
    - be imported from the DBD::Oracle module. Rarely needed.
    -
    -- ora\_csid
    -
    - Specify the _integer_ OCI\_ATTR\_CHARSET\_ID for the bind value.
    - Character set names can't be used currently.
    -
    -- ora\_maxdata\_size
    -
    - Specify the integer OCI\_ATTR\_MAXDATA\_SIZE for the bind value.
    - May be needed if a character set conversion from client to server
    - causes the data to use more space and so fail with a truncation error.
    -
    -- ora\_maxarray\_numentries
    -
    - Specify the maximum number of array entries to allocate. Used with
    - ORA\_VARCHAR2\_TABLE, ORA\_NUMBER\_TABLE. Define the maximum number of
    - array entries Oracle can pass back to you in OUT variable of type
    - TABLE OF ... .
    -
    -- ora\_internal\_type
    -
    - Specify internal data representation. Currently is supported only for
    - ORA\_NUMBER\_TABLE.
    -
    -### Optimizing Results
    -
    -#### Prepare Postponed Till Execute
    -
    -The DBD::Oracle module can avoid an explicit 'describe' operation
    -prior to the execution of the statement unless the application requests -information about the results (such as $sth->{NAME}). This reduces -communication with the server and increases performance (reducing the
    -number of PARSE\_CALLS inside the server).
    -
    -However, it also means that SQL errors are not detected until
    -`execute()` (or $sth->{NAME} etc) is called instead of when
    -`prepare()` is called. Note that if the describe is triggered by the
    -use of $sth->{NAME} or a similar attribute and the describe fails then
    -_an exception is thrown_ even if `RaiseError` is false!
    -
    -Set ["ora\_check\_sql"](#ora_check_sql) to 0 in prepare() to enable this behaviour.
    -
    -## **bind\_param\_inout**
    -
    - $rv = $sth->bind_param_inout($param_num, \$scalar, 0);
    -
    -DBD::Oracle fully supports bind\_param\_inout below are some uses for this method.
    -
    -### **Returning A Value from an INSERT**
    -
    -Oracle supports an extended SQL insert syntax which will return one
    -or more of the values inserted. This can be particularly useful for -single-pass insertion of values with re-used sequence values
    -(avoiding a separate "select seq.nextval from dual" step).
    -
    - $sth = $dbh->prepare(qq{
    - INSERT INTO foo (id, bar)
    - VALUES (foo_id_seq.nextval, :bar)
    - RETURNING id INTO :id
    - });
    - $sth->bind_param(":bar", 42);
    - $sth->bind_param_inout(":id", \my $new_id, 99);
    - $sth->execute;
    - print "The id of the new record is $new_id\n";
    -
    -If you have many columns to bind you can use code like this:
    -
    - @params = (... column values for record to be inserted ...);
    - $sth->bind_param($_, $params[$_-1]) for (1..@params);
    - $sth->bind_param_inout(@params+1, \my $new_id, 99);
    - $sth->execute;
    -
    -If you have many rows to insert you can take advantage of Oracle's built in execute array feature
    -with code like this:
    -
    - my @in_values=('1',2,'3','4',5,'6',7,'8',9,'10');
    - my @out_values;
    - my @status;
    - my $sth = $dbh->prepare(qq{
    - INSERT INTO foo (id, bar)
    - VALUES (foo_id_seq.nextval, ?)
    - RETURNING id INTO ?
    - });
    - $sth->bind_param_array(1,\@in_values);
    - $sth->bind_param_inout_array(2,\@out_values,0,{ora_type => ORA_VARCHAR2}); - $sth->execute_array({ArrayTupleStatus=>\@status}) or die "error inserting";
    - foreach my $id (@out_values){
    - print 'returned id='.$id.'\n';
    - }
    -
    -Which will return all the ids into @out\_values.
    -
    -- **Note:**
    -- This will only work for numbered (?) placeholders,
    -- The third parameter of bind\_param\_inout\_array, (0 in the example), "maxlen" is required by DBI but not used by DBD::Oracle
    -- The "ora\_type" attribute is not needed but only ORA\_VARCHAR2 will work.
    -
    -### Returning A Recordset
    -
    -DBD::Oracle does not currently support binding a PL/SQL table (aka array)
    -as an IN OUT parameter to any Perl data structure. You cannot therefore call -a PL/SQL function or procedure from DBI that uses a non-atomic datatype as -either a parameter, or a return value. However, if you are using Oracle 9.0.1 -or later, you can make use of table (or pipelined) functions.
    -
    -For example, assume you have the existing PL/SQL Package :
    -
    - CREATE OR REPLACE PACKAGE Array_Example AS
    - --
    - TYPE tRec IS RECORD (
    - Col1 NUMBER,
    - Col2 VARCHAR2 (10),
    - Col3 DATE) ;
    - --
    - TYPE taRec IS TABLE OF tRec INDEX BY BINARY_INTEGER ;
    - --
    - FUNCTION Array_Func RETURN taRec ;
    - --
    - END Array_Example ;
    -
    - CREATE OR REPLACE PACKAGE BODY Array_Example AS
    - --
    - FUNCTION Array_Func RETURN taRec AS
    - --
    - l_Ret taRec ;
    - --
    - BEGIN
    - FOR i IN 1 .. 5 LOOP
    - l_Ret (i).Col1 := i ;
    - l_Ret (i).Col2 := 'Row : ' || i ;
    - l_Ret (i).Col3 := TRUNC (SYSDATE) + i ;
    - END LOOP ;
    - RETURN l_Ret ;
    - END ;
    - --
    - END Array_Example ;
    - /
    -
    -Currently, there is no way to directly call the function -Array\_Example.Array\_Func from DBI. However, by making the following relatively
    -painless additions, its not only possible, but extremely efficient.
    -
    -First, you need to create database object types that correspond to the record -and table types in the package. From the above example, these would be :
    -
    - CREATE OR REPLACE TYPE tArray_Example__taRec
    - AS OBJECT (
    - Col1 NUMBER,
    - Col2 VARCHAR2 (10),
    - Col3 DATE
    - ) ;
    -
    - CREATE OR REPLACE TYPE taArray_Example__taRec
    - AS TABLE OF tArray_Example__taRec ;
    -
    -Now, assuming the existing function needs to remain unchanged (it is probably -being called from other PL/SQL code), we need to add a new function to the -package. Here's the new package specification and body :
    -
    - CREATE OR REPLACE PACKAGE Array_Example AS
    - --
    - TYPE tRec IS RECORD (
    - Col1 NUMBER,
    - Col2 VARCHAR2 (10),
    - Col3 DATE) ;
    - --
    - TYPE taRec IS TABLE OF tRec INDEX BY BINARY_INTEGER ;
    - --
    - FUNCTION Array_Func RETURN taRec ;
    - FUNCTION Array_Func_DBI RETURN taArray_Example__taRec PIPELINED ;
    - --
    - END Array_Example ;
    -
    - CREATE OR REPLACE PACKAGE BODY Array_Example AS
    - --
    - FUNCTION Array_Func RETURN taRec AS
    - l_Ret taRec ;
    - BEGIN
    - FOR i IN 1 .. 5 LOOP
    - l_Ret (i).Col1 := i ;
    - l_Ret (i).Col2 := 'Row : ' || i ;
    - l_Ret (i).Col3 := TRUNC (SYSDATE) + i ;
    - END LOOP ;
    - RETURN l_Ret ;
    - END ;
    -
    - FUNCTION Array_Func_DBI RETURN taArray_Example__taRec PIPELINED AS
    - l_Set taRec ;
    - BEGIN
    - l_Set := Array_Func ;
    - FOR i IN l_Set.FIRST .. l_Set.LAST LOOP
    - PIPE ROW (
    - tArray_Example__taRec (
    - l_Set (i).Col1,
    - l_Set (i).Col2,
    - l_Set (i).Col3
    - )
    - ) ;
    - END LOOP ;
    - RETURN ;
    - END ;
    - --
    - END Array_Example ;
    -
    -As you can see, the new function is very simple. Now, it is a simple matter -of calling the function as a straight-forward SELECT from your DBI code. From -the above example, the code would look something like this :
    -
    - my $sth = $dbh->prepare('SELECT * FROM TABLE(Array_Example.Array_Func_DBI)');
    - $sth->execute;
    - while ( my ($col1, $col2, $col3) = $sth->fetchrow_array {
    - ...
    - }
    -
    -### **SYS.DBMS\_SQL datatypes**
    -
    -DBD::Oracle has built-in support for **SYS.DBMS\_SQL.VARCHAR2\_TABLE**
    -and **SYS.DBMS\_SQL.NUMBER\_TABLE** datatypes. The simple example is here:
    -
    - my $statement='
    - DECLARE
    - tbl SYS.DBMS_SQL.VARCHAR2_TABLE;
    - BEGIN
    - tbl := :mytable;
    - :cc := tbl.count();
    - tbl(1) := \'def\';
    - tbl(2) := \'ijk\';
    - :mytable := tbl;
    - END;
    - ';
    -
    - my $sth=$dbh->prepare( $statement );
    -
    - my @arr=( "abc","efg","hij" );
    -
    - $sth->bind_param_inout(":mytable", \\@arr, 10, {
    - ora_type => ORA_VARCHAR2_TABLE,
    - ora_maxarray_numentries => 100
    - } ) ;
    - $sth->bind_param_inout(":cc", \$cc, 100 );
    - $sth->execute();
    - print "Result: cc=",$cc,"\n",
    - "\tarr=",Data::Dumper::Dumper(\@arr),"\n";
    -
    -- **Note:**
    -- Take careful note that we use '\\\\@arr' here because the 'bind\_param\_inout'
    - will only take a reference to a scalar.
    -
    -### **ORA\_VARCHAR2\_TABLE**
    -
    -SYS.DBMS\_SQL.VARCHAR2\_TABLE object is always bound to array reference.
    -( in bind\_param() and bind\_param\_inout() ). When you bind array, you need -to specify full buffer size for OUT data. So, there are two parameters: -_max\_len_ (specified as 3rd argument of bind\_param\_inout() ),
    -and _ora\_maxarray\_numentries_. They define maximum array entry length and -maximum rows, that can be passed to Oracle and back to you. In this
    -example we send array with 1 element with length=3, but allocate space for 100 -Oracle array entries with maximum length 10 of each. So, you can get no more -than 100 array entries with length <= 10.
    -
    -If you set _max\_len_ to zero, maximum array entry length is calculated
    -as maximum length of entry of array bound. If 0 < _max\_len_ < length( $some\_element ),
    -truncation occur.
    -
    -If you set _ora\_maxarray\_numentries_ to zero, current (at bind time) bound -array length is used as maximum. If 0 < _ora\_maxarray\_numentries_ < scalar(@array),
    -not all array entries are bound.
    -
    -### **ORA\_NUMBER\_TABLE**
    -
    -SYS.DBMS\_SQL.NUMBER\_TABLE object handling is much alike ORA\_VARCHAR2\_TABLE.
    -The main difference is internal data representation. Currently 2 types of -bind is allowed : as C-integer, or as C-double type. To select one of them, -you may specify additional bind parameter _ora\_internal\_type_ as either -**SQLT\_INT** or **SQLT\_FLT** for C-integer and C-double types.
    -Integer size is architecture-specific and is usually 32 or 64 bit.
    -Double is standard IEEE 754 type.
    -
    -_ora\_internal\_type_ defaults to double (SQLT\_FLT).
    -
    -_max\_len_ is ignored for OCI\_NUMBER\_TABLE.
    -
    -Currently, you cannot bind full native Oracle NUMBER(38). If you really need, -send request to dbi-dev list.
    -
    -The usage example is here:
    -
    - $statement='
    - DECLARE
    - tbl SYS.DBMS_SQL.NUMBER_TABLE;
    - BEGIN
    - tbl := :mytable;
    - :cc := tbl(2);
    - tbl(4) := -1;
    - tbl(5) := -2;
    - :mytable := tbl;
    - END;
    - ';
    -
    - $sth=$dbh->prepare( $statement );
    -
    - if( ! defined($sth) ){
    - die "Prepare error: ",$dbh->errstr,"\n";
    - }
    -
    - @arr=( 1,"2E0","3.5" );
    -

    [continued in next message]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)