Package: release.debian.org Severity: normal User: release.debian.org@packages.debian.org Usertags: unblock Please unblock package libdbd-oracle-perl to use newer, supported dependencies. A hint for oracle-instantclient-devel being out of the archive instead of oracle-instantclient12.1-devel may be needed. [ Reason ] Bug #1016992 explains that the version in testing does not use the dependencies currently supported by Oracle. As of release 21 of the Oracle Instant Client, the package name of the dependencies does no longer include the release version. Thus the change in name that is triggering the block in testing, i.e. oracle-instantclient12.1-devel is now oracle-instantclient-devel Support for Oracle Instant Client release 21 is not included was included in DBD::Oracle 1.81 and some fixes to build on Debian in 1.83. [ Impact ] If not permitted, then bookworm will end up with a version that uses a client no longer supported by Oracle. [ Tests ] DBD::Oracle tests succeeded in the same box used to build 1.80-4. [ Risks ] DBD::Oracle 1.83 was released more than 1 year ago, and the the packaging changes are minimal. The reverse-depends list this package as an optional requirement. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing unblock libdbd-oracle-perl/1.83-1 -- ⢀⣴⠾⠻⢶⣦⠀ ⣾⠁⢠⠒⠀⣿⡁ Alex Muntada <alexm@debian.org> ⢿⡄⠘⠷⠚⠋ Debian Developer 🍥 log.alexm.org ⠈⠳⣄⠀⠀⠀⠀
diff -Nru libdbd-oracle-perl-1.80/CONTRIBUTING.md libdbd-oracle-perl-1.83/CONTRIBUTING.md --- libdbd-oracle-perl-1.80/CONTRIBUTING.md 1970-01-01 00:00:00.000000000 +0000 +++ libdbd-oracle-perl-1.83/CONTRIBUTING.md 2022-01-17 02:06:35.000000000 +0000 @@ -0,0 +1,111 @@ +# CONTRIBUTING + +Thank you for considering contributing to {{ $dist }}. +This file contains instructions that will help you work with +the source code. + +## Repository branches structure + +The two main branches of this repository are: + +* **master** + +The main development branch. This branch has to +be processed by Dist::Zilla to generate the +code as it will appear in the CPAN distribution. See the +next section for more details. + +* **releases** + +Contains the code as it appears on CPAN. Each official +release is also tagged with its version. + +## Working on the master branch + +The distribution is managed with [Dist::Zilla][distzilla]. +This means than many of the usual files you might expect +are not in the repository, but are generated at release time. + +However, you can run tests directly using the 'prove' tool: + +``` bash +$ prove -l +$ prove -lv t/some_test_file.t +$ prove -lvr t/ +``` + +In most cases, 'prove' is entirely sufficient for you to test any +patches you have. + +You may need to satisfy some dependencies. The easiest way to satisfy +dependencies is to install the last release -- this is available at +https://metacpan.org/release/{{ $dist }}. + +If you use cpanminus, you can do it without downloading the tarball first: + +``` bash +$ cpanm --reinstall --installdeps --with-recommends {{ $dist =~ s/-/::/gr }} +``` + +Dist::Zilla is a very powerful authoring tool, but requires a number of +author-specific plugins. If you would like to use it for contributing, +install it from CPAN, then run one of the following commands, depending on +your CPAN client: + +``` bash +$ cpan `dzil authordeps --missing` +$ dzil authordeps --missing | cpanm +``` + +You should then also install any additional requirements not needed by the +dzil build but may be needed by tests or other development: + +``` bash +# cpan `dzil listdeps --author --missing` +$ dzil listdeps --author --missing | cpanm +``` + +You can also do this via cpanm directly: + +``` bash +$ cpanm --reinstall --installdeps --with-develop --with-recommends {{ $dist =~ s/-/::/gr }} +``` + +Once installed, here are some dzil commands you might try: + +``` bash +$ dzil build +$ dzil test +$ dzil test --release +$ dzil xtest +$ dzil listdeps --json +$ dzil build --notgz +``` + + +## This Is Complicated. Is There an Easier Way? + +Actually, yes there is. You can also work directly on the `releases` branch, +which corresponds to the code is generated by Dist::Zilla and +correspond to what is uploaded to CPAN. + +It won't contain any of the changes brought to the codebase since the last +CPAN release, but for a small patch that shouldn't be a problem. + +## Sending Patches + +The code for this distribution is hosted on [GitHub][repository]. + +You can submit bug reports via the [repository's issue track][bugtracker]. + +You can also submit code changes by forking the repository, pushing your code +changes to your clone, and then submitting a pull request. Detailed +instructions for doing that is available here: + +* https://help.github.com/ +* https://help.github.com/articles/creating-a-pull-request + +[distzilla]: http://dzil.org/. +[repository]: https://github.com/perl5-dbi/DBD-Oracle/ +[bugtracker]: https://github.com/perl5-dbi/DBD-Oracle/issues + diff -Nru libdbd-oracle-perl-1.80/CONTRIBUTING.mkd libdbd-oracle-perl-1.83/CONTRIBUTING.mkd --- libdbd-oracle-perl-1.80/CONTRIBUTING.mkd 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/CONTRIBUTING.mkd 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ -# CONTRIBUTING - -Thank you for considering contributing to {{ $dist }}. -This file contains instructions that will help you work with -the source code. - -## Repository branches structure - -The two main branches of this repository are: - -* **master** - -The main development branch. This branch has to -be processed by Dist::Zilla to generate the -code as it will appear in the CPAN distribution. See the -next section for more details. - -* **releases** - -Contains the code as it appears on CPAN. Each official -release is also tagged with its version. - -## Working on the master branch - -The distribution is managed with [Dist::Zilla][distzilla]. -This means than many of the usual files you might expect -are not in the repository, but are generated at release time. - -However, you can run tests directly using the 'prove' tool: - -``` bash -$ prove -l -$ prove -lv t/some_test_file.t -$ prove -lvr t/ -``` - -In most cases, 'prove' is entirely sufficient for you to test any -patches you have. - -You may need to satisfy some dependencies. The easiest way to satisfy -dependencies is to install the last release -- this is available at -https://metacpan.org/release/{{ $dist }}. - -If you use cpanminus, you can do it without downloading the tarball first: - -``` bash -$ cpanm --reinstall --installdeps --with-recommends {{ $dist =~ s/-/::/gr }} -``` - -Dist::Zilla is a very powerful authoring tool, but requires a number of -author-specific plugins. If you would like to use it for contributing, -install it from CPAN, then run one of the following commands, depending on -your CPAN client: - -``` bash -$ cpan `dzil authordeps --missing` -$ dzil authordeps --missing | cpanm -``` - -You should then also install any additional requirements not needed by the -dzil build but may be needed by tests or other development: - -``` bash -# cpan `dzil listdeps --author --missing` -$ dzil listdeps --author --missing | cpanm -``` - -You can also do this via cpanm directly: - -``` bash -$ cpanm --reinstall --installdeps --with-develop --with-recommends {{ $dist =~ s/-/::/gr }} -``` - -Once installed, here are some dzil commands you might try: - -``` bash -$ dzil build -$ dzil test -$ dzil test --release -$ dzil xtest -$ dzil listdeps --json -$ dzil build --notgz -``` - - -## This Is Complicated. Is There an Easier Way? - -Actually, yes there is. You can also work directly on the `releases` branch, -which corresponds to the code is generated by Dist::Zilla and -correspond to what is uploaded to CPAN. - -It won't contain any of the changes brought to the codebase since the last -CPAN release, but for a small patch that shouldn't be a problem. - -## Sending Patches - -The code for this distribution is hosted on [GitHub][repository]. - -You can submit bug reports via the [repository's issue track][bugtracker]. - -You can also submit code changes by forking the repository, pushing your code -changes to your clone, and then submitting a pull request. Detailed -instructions for doing that is available here: - -* https://help.github.com/ -* https://help.github.com/articles/creating-a-pull-request - -[distzilla]: http://dzil.org/. -[repository]: https://github.com/perl5-dbi/DBD-Oracle/ -[bugtracker]: https://github.com/perl5-dbi/DBD-Oracle/issues - diff -Nru libdbd-oracle-perl-1.80/CONTRIBUTORS libdbd-oracle-perl-1.83/CONTRIBUTORS --- libdbd-oracle-perl-1.80/CONTRIBUTORS 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/CONTRIBUTORS 2022-01-17 02:06:35.000000000 +0000 @@ -7,6 +7,8 @@ 'thank you' to all of them. * Aaron Crane + * Alex Muntada + * Alex Muntada * Alice Maz * Carsten Grohmann * cjardine @@ -18,9 +20,12 @@ * Dean Pearce * gregor herrmann * Gwen Shapira + * Håkon Hægland + * H.Merijn Brand - Tux * H.Merijn Brand - Tux * Jochen Hayek * Joe Crotty + * John Smith * jurl * lbaxter * Michael Portnoy diff -Nru libdbd-oracle-perl-1.80/Changes libdbd-oracle-perl-1.83/Changes --- libdbd-oracle-perl-1.80/Changes 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/Changes 2022-01-17 02:06:35.000000000 +0000 @@ -1,5 +1,30 @@ Revision history for DBD::Oracle +1.83 + + Build improvements on Debian-ish systems (GH#112, Alex Muntada) + Add rpath to ORACLE_HOME to DBD/Oracle/Oracle.bundle (GH#129, hackonhagland). + +1.82 2021-12-29 + + Second try at github #130. Still not fully cooperating but better. + +1.81 2021-12-24 + + [BUG FIXES] + + Run nonassigned pl/sql tests based off versions known to have the issue. - (GH#70, Wesley Hinds) + Oracle Instant Client 21 support - (Tux) + Add rpath to ORACLE_HOME to DBD/Oracle/Oracle.bundle - (GH#128, hakonhagland) + fix materialised views being misclassified as tables in ->table_info - (GH#132, John Smith) + Fix bugtracker ref in dist metadata github - (GH#130, John Smith) + + [MISCELLANEOUS] + + Updates to POD and README file + Moved old README file to t/TESTING.md + Updated links + 1.80 2019-07-25 [BUG FIXES] diff -Nru libdbd-oracle-perl-1.80/INSTALL libdbd-oracle-perl-1.83/INSTALL --- libdbd-oracle-perl-1.80/INSTALL 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/INSTALL 2022-01-17 02:06:35.000000000 +0000 @@ -21,8 +21,11 @@ ## Manual installation -As a last resort, you can manually install it. Download the tarball, untar it, -install configure prerequisites (see below), then build it: +As a last resort, you can manually install it. If you have not already +downloaded the release tarball, you can find the download link on the module's +MetaCPAN page: https://metacpan.org/pod/DBD::Oracle + +Untar the tarball, install configure prerequisites (see below), then build it: % perl Makefile.PL % make && make test @@ -46,7 +49,7 @@ This distribution requires other modules to be installed before this distribution's installer can be run. They can be found under the "configure_requires" key of META.yml or the -"{prereqs}{configure}{requires}" key of META.json. +. ## Other Prerequisites @@ -59,7 +62,7 @@ * to run tests, PHASE = test They can all be found in the "PHASE_requires" key of MYMETA.yml or the -"{prereqs}{PHASE}{requires}" key of MYMETA.json. +. ## Documentation diff -Nru libdbd-oracle-perl-1.80/LICENSE libdbd-oracle-perl-1.83/LICENSE --- libdbd-oracle-perl-1.80/LICENSE 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/LICENSE 2022-01-17 02:06:35.000000000 +0000 @@ -1,4 +1,4 @@ -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. @@ -12,7 +12,7 @@ --- The GNU General Public License, Version 1, February 1989 --- -This software is Copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is Copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software, licensed under: @@ -272,7 +272,7 @@ --- The Artistic License 1.0 --- -This software is Copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is Copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software, licensed under: @@ -292,21 +292,21 @@ - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through - textual modification. + textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright - Holder. + Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for - the package. + the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the - computing community at large as a market that must bear the fee.) + computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they - received it. + received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you @@ -373,7 +373,7 @@ 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF -MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End diff -Nru libdbd-oracle-perl-1.80/MANIFEST libdbd-oracle-perl-1.83/MANIFEST --- libdbd-oracle-perl-1.80/MANIFEST 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/MANIFEST 2022-01-17 02:06:35.000000000 +0000 @@ -1,23 +1,21 @@ -CONTRIBUTING.mkd +CONTRIBUTING.md CONTRIBUTORS Changes INSTALL LICENSE MANIFEST -META.json META.yml Makefile.PL Oracle.h Oracle.xs README README.help.txt -README.mkdn +TESTING.md TODO cpanfile dbdimp.c dbdimp.h dbivport.h -doap.xml examples/README examples/bind.pl examples/commit.pl @@ -93,7 +91,6 @@ t/60reauth.t t/70meta.t t/80ora_charset.t -t/README t/lib/DBDOracleTestLib.pm t/lib/ExecuteArray.pm t/rt13865.t diff -Nru libdbd-oracle-perl-1.80/META.json libdbd-oracle-perl-1.83/META.json --- libdbd-oracle-perl-1.80/META.json 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/META.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,132 +0,0 @@ -{ - "abstract" : "Oracle database driver for the DBI module", - "author" : [ - "Tim Bunce <timb@cpan.org>", - "John Scoles <byterock@cpan.org>", - "Yanick Champoux <yanick@cpan.org>", - "Martin J. Evans <mjevans@cpan.org>" - ], - "dynamic_config" : 0, - "generated_by" : "Dist::Zilla version 6.012, CPAN::Meta::Converter version 2.150010", - "license" : [ - "perl_5" - ], - "meta-spec" : { - "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", - "version" : 2 - }, - "name" : "DBD-Oracle", - "prereqs" : { - "configure" : { - "requires" : { - "Config" : "0", - "DBI" : "1.623", - "Data::Dumper" : "0", - "Devel::Peek" : "0", - "Encode" : "0", - "ExtUtils::MakeMaker" : "0", - "Math::BigInt" : "0", - "Test::More" : "0", - "Test::NoWarnings" : "0" - } - }, - "develop" : { - "requires" : { - "Pod::Coverage::TrustPod" : "0", - "Test::CPAN::Meta" : "0", - "Test::EOF" : "0", - "Test::EOL" : "0", - "Test::Kwalitee" : "1.21", - "Test::More" : "0.88", - "Test::NoBreakpoints" : "0.15", - "Test::NoTabs" : "0", - "Test::Pod" : "1.41", - "Test::Pod::Coverage" : "1.08", - "Test::Portability::Files" : "0" - } - }, - "runtime" : { - "requires" : { - "DBI" : "0", - "DynaLoader" : "0", - "Exporter" : "0", - "perl" : "5.006", - "strict" : "0", - "warnings" : "0" - } - }, - "test" : { - "recommends" : { - "CPAN::Meta" : "2.120900" - }, - "requires" : { - "B" : "0", - "Carp" : "0", - "Data::Dumper" : "0", - "Devel::Peek" : "0", - "Encode" : "0", - "ExtUtils::MakeMaker" : "0", - "File::Spec" : "0", - "IO::Handle" : "0", - "IPC::Open3" : "0", - "Math::BigInt" : "0", - "Symbol" : "0", - "Test::More" : "0", - "Test::NoWarnings" : "0", - "Thread::Semaphore" : "0", - "lib" : "0", - "utf8" : "0", - "vars" : "0" - } - } - }, - "provides" : { - "DBD::Oracle" : { - "file" : "lib/DBD/Oracle.pm", - "version" : "1.80" - }, - "DBD::Oracle::GetInfo" : { - "file" : "lib/DBD/Oracle/GetInfo.pm", - "version" : "1.80" - }, - "DBD::Oracle::Object" : { - "file" : "lib/DBD/Oracle/Object.pm", - "version" : "1.80" - } - }, - "release_status" : "stable", - "version" : "1.80", - "x_contributors" : [ - "Aaron Crane <arc@cpan.org>", - "Alice Maz <alice@alicemaz.com>", - "Carsten Grohmann <mail@carstengrohmann.de>", - "cjardine <cjardine@50811bd7-b8ce-0310-adc1-d9db26280581>", - "Dag Lem <dag@nimrod.no>", - "David E. Wheeler <david@justatheory.com>", - "David Perry <perry@pythian.com>", - "David Steinbrunner <dsteinbrunner@pobox.com>", - "Dean Hamstead <djzort@cpan.org>", - "Dean Pearce <deanpearce@gmail.com>", - "gregor herrmann <gregoa@debian.org>", - "Gwen Shapira <shapira@pythian.com>", - "H.Merijn Brand - Tux <h.m.brand@xs4all.nl>", - "Jochen Hayek <jochen.hayek@ext.eex.com>", - "Joe Crotty <joe.crotty@returnpath.net>", - "jurl <jurl@50811bd7-b8ce-0310-adc1-d9db26280581>", - "lbaxter <lbaxter@50811bd7-b8ce-0310-adc1-d9db26280581>", - "Michael Portnoy <portnoy@pythian.com>", - "Mike O'Regan <moregan@stresscafe.com>", - "robert <robert@50811bd7-b8ce-0310-adc1-d9db26280581>", - "StephenCIQG <StephenCIQG@50811bd7-b8ce-0310-adc1-d9db26280581>", - "Tony Cook <tony@develop-help.com>", - "Wesley Hinds <wesley.hinds@swri.org>" - ], - "x_generated_by_perl" : "v5.22.0", - "x_help_wanted" : [ - "developer", - "documenter", - "tester" - ], - "x_serialization_backend" : "Cpanel::JSON::XS version 3.0222" -} - diff -Nru libdbd-oracle-perl-1.80/META.yml libdbd-oracle-perl-1.83/META.yml --- libdbd-oracle-perl-1.80/META.yml 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/META.yml 2022-01-17 02:06:35.000000000 +0000 @@ -8,6 +8,7 @@ build_requires: B: '0' Carp: '0' + Config: '0' Data::Dumper: '0' Devel::Peek: '0' Encode: '0' @@ -21,20 +22,16 @@ Test::NoWarnings: '0' Thread::Semaphore: '0' lib: '0' + perl: '5.008' + strict: '0' utf8: '0' vars: '0' + warnings: '0' configure_requires: - Config: '0' - DBI: '1.623' - Data::Dumper: '0' - Devel::Peek: '0' - Encode: '0' ExtUtils::MakeMaker: '0' - Math::BigInt: '0' - Test::More: '0' - Test::NoWarnings: '0' + perl: '5.006' dynamic_config: 0 -generated_by: 'Dist::Zilla version 6.012, CPAN::Meta::Converter version 2.150010' +generated_by: 'Dist::Zilla version 6.024, CPAN::Meta::Converter version 2.150010' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html @@ -43,23 +40,29 @@ provides: DBD::Oracle: file: lib/DBD/Oracle.pm - version: '1.80' + version: '1.83' DBD::Oracle::GetInfo: file: lib/DBD/Oracle/GetInfo.pm - version: '1.80' + version: '1.83' DBD::Oracle::Object: file: lib/DBD/Oracle/Object.pm - version: '1.80' + version: '1.83' requires: - DBI: '0' + DBI: '1.623' + Data::Dumper: '0' DynaLoader: '0' Exporter: '0' - perl: '5.006' + perl: '5.008' strict: '0' warnings: '0' -version: '1.80' +resources: + homepage: https://github.com/singingfish/DBD-Oracle + repository: https://github.com/singingfish/DBD-Oracle.git +version: '1.83' x_contributors: - 'Aaron Crane <arc@cpan.org>' + - 'Alex Muntada <alexm@alexm.org>' + - 'Alex Muntada <alex.muntada@gmail.com>' - 'Alice Maz <alice@alicemaz.com>' - 'Carsten Grohmann <mail@carstengrohmann.de>' - 'cjardine <cjardine@50811bd7-b8ce-0310-adc1-d9db26280581>' @@ -71,9 +74,12 @@ - 'Dean Pearce <deanpearce@gmail.com>' - 'gregor herrmann <gregoa@debian.org>' - 'Gwen Shapira <shapira@pythian.com>' + - 'Håkon Hægland <hakon.hagland@gmail.com>' - 'H.Merijn Brand - Tux <h.m.brand@xs4all.nl>' + - 'H.Merijn Brand - Tux <linux@tux.freedom.nl>' - 'Jochen Hayek <jochen.hayek@ext.eex.com>' - 'Joe Crotty <joe.crotty@returnpath.net>' + - 'John Smith <john.smith@nxp.nz>' - 'jurl <jurl@50811bd7-b8ce-0310-adc1-d9db26280581>' - 'lbaxter <lbaxter@50811bd7-b8ce-0310-adc1-d9db26280581>' - 'Michael Portnoy <portnoy@pythian.com>' @@ -82,9 +88,10 @@ - 'StephenCIQG <StephenCIQG@50811bd7-b8ce-0310-adc1-d9db26280581>' - 'Tony Cook <tony@develop-help.com>' - 'Wesley Hinds <wesley.hinds@swri.org>' -x_generated_by_perl: v5.22.0 +x_generated_by_perl: v5.32.1 x_help_wanted: - developer - documenter - tester -x_serialization_backend: 'YAML::Tiny version 1.70' +x_serialization_backend: 'YAML::Tiny version 1.73' +x_spdx_expression: 'Artistic-1.0-Perl OR GPL-1.0-or-later' diff -Nru libdbd-oracle-perl-1.80/Makefile.PL libdbd-oracle-perl-1.83/Makefile.PL --- libdbd-oracle-perl-1.80/Makefile.PL 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/Makefile.PL 2022-01-17 02:06:35.000000000 +0000 @@ -18,7 +18,7 @@ # new static perl in the DBI directory by saying 'make perl' # and then using _that_ perl to make this one. use DBI 1.623; -use DBI::DBD; # DBD creation tools +use DBI::DBD; # DBD creation tools # Some MakeMaker's forged some FileHandle methods @@ -49,11 +49,11 @@ OBJECT => '$(O_FILES)', DEFINE => '', DIR => [], - clean => { FILES => 'xstmp.c Oracle.xsi dll.base dll.exp sqlnet.log libOracle.def mk.pm DBD_ORA_OBJ.*' }, + clean => { FILES => 'xstmp.c Oracle.xsi dll.base dll.exp sqlnet.log libOracle.def mk.pm DBD_ORA_OBJ.*' }, dist => { - DIST_DEFAULT => 'clean distcheck disttest tardist', - PREOP => '$(MAKE) -f Makefile.old distdir', - COMPRESS => 'gzip -v9', SUFFIX => 'gz', + DIST_DEFAULT => 'clean distcheck disttest tardist', + PREOP => '$(MAKE) -f Makefile.old distdir', + COMPRESS => 'gzip -v9', SUFFIX => 'gz', }, META_MERGE => { configure_requires => { "DBI" => '1.623' }, @@ -61,12 +61,12 @@ "ExtUtils::MakeMaker" => 0, "Test::Simple" => '0.90'}, resources => { - bugtracker => 'https://github.com/perl5-dbi/DBD-Oracle/issues', + bugtracker => { web => 'https://github.com/perl5-dbi/DBD-Oracle/issues'}, homepage => 'https://metacpan.org/pod/DBD::Oracle', repository => { type => 'git', - url => 'git://github.com/yanick/DBD-Oracle.git', - web => 'http://github.com/yanick/DBD-Oracle/tree', + url => 'git://github.com/perl5-dbi/DBD-Oracle.git', + web => 'http://github.com/perl5-dbi/DBD-Oracle', }, }, }, @@ -85,7 +85,7 @@ $opts{CCFLAGS} = "-P $Config{ccflags}" if $Config{cc} eq 'bcc32'; # force C++ $opts{LINKTYPE} = 'static' if $Config{dlsrc} =~ /dl_none/; -my(@MK, %MK, $MK_TEXT, %MK_expanding); # parsed macros from Oracle's makefiles +my(@MK, %MK, $MK_TEXT, %MK_expanding); # parsed macros from Oracle's makefiles my %mk_target_deps; my %mk_target_rules; @@ -97,7 +97,6 @@ Try to use Oracle's own 'build' rule. Defaults to true. - =item -r With I<-b>, use this names build rule (eg -r=build64). @@ -175,32 +174,32 @@ # Options (rarely needed) # to turn off an option prefix with 'no', ie 'perl Makefile.PL -nob' #$::opt_ic10 = 1; # Build for Oracle 10g instantclient -$::opt_b = 1; # try to use Oracle's own 'build' rule -$::opt_r = ''; # With -b above, use this names build rule (eg -r=build64) -$::opt_m = ''; # path to oracle.mk file to read -$::opt_h = ''; # path to oracle header files -$::opt_p = ''; # alter preference for oracle.mk -$::opt_n = ''; # Oracle .mk macro name to use for library list to link with -$::opt_c = 0; # don't encourage use of shared library -$::opt_l = 0; # try direct-link to libclntsh -$::opt_g = ''; # enable debugging (-g for compiler and linker) -$::opt_s = ''; # Find a symbol in oracle libs, Don't build a Makefile -$::opt_S = ''; # Find a symbol in oracle & system libs, Don't build a Makefile -$::opt_v = 0; # be more verbose -$::opt_d = 0; # much more verbose for debugging -$::opt_f = 0; # include text of oracle's .mk file within generated Makefile -$::opt_F = 0; # force - ignore errors -$::opt_W = 0; # just write a basic default Makefile (won't build) -$::opt_w = 0; # enable many gcc compiler warnings +$::opt_b = 1; # try to use Oracle's own 'build' rule +$::opt_r = ''; # With -b above, use this names build rule (eg -r=build64) +$::opt_m = ''; # path to oracle.mk file to read +$::opt_h = ''; # path to oracle header files +$::opt_p = ''; # alter preference for oracle.mk +$::opt_n = ''; # Oracle .mk macro name to use for library list to link with +$::opt_c = 0; # don't encourage use of shared library +$::opt_l = 0; # try direct-link to libclntsh +$::opt_g = ''; # enable debugging (-g for compiler and linker) +$::opt_s = ''; # Find a symbol in oracle libs, Don't build a Makefile +$::opt_S = ''; # Find a symbol in oracle & system libs, Don't build a Makefile +$::opt_v = 0; # be more verbose +$::opt_d = 0; # much more verbose for debugging +$::opt_f = 0; # include text of oracle's .mk file within generated Makefile +$::opt_F = 0; # force - ignore errors +$::opt_W = 0; # just write a basic default Makefile (won't build) +$::opt_w = 0; # enable many gcc compiler warnings $::opt_V = 0; # force assumption of specified Oracle version - # If == 8 then we don't use the new OCI_INIT code - # and we force our emulation of OCILobWriteAppend + # If == 8 then we don't use the new OCI_INIT code + # and we force our emulation of OCILobWriteAppend Getopt::Long::config( qw( no_ignore_case ) ); GetOptions(qw(b! r=s v! d! g! p! l! c! f! F! W! w! m=s h=s n=s s=s S=s V=s )) or die pod2usage( -verbose => 99, -sections => [ 'OPTIONS' ] ); -$::opt_g &&= '-g'; # convert to actual string +$::opt_g &&= '-g'; # convert to actual string $::opt_v = 1 if $::opt_d; $Verbose = 1 if $::opt_v; my $is_developer = (-d ".svn" && -f "MANIFEST.SKIP"); @@ -255,10 +254,10 @@ See the appropriate troubleshooting guide for your OS for more information. ABORTED! } unless (-d $OH and $^O eq 'VMS') - or -d "$OH/sdk/." # Instant Client with SDK - or -d "$OH/lib/." # normal Oracle installation + or -d "$OH/sdk/." # Instant Client with SDK + or -d "$OH/lib/." # normal Oracle installation or glob("$OH/libclntsh.$so*") # pre-sdk instant client or rpm - or -e "$OH/oci.dll"; # Windows Instant Client + or -e "$OH/oci.dll"; # Windows Instant Client print "Installing on a $^O, Ver#$osvers\n"; print "Using Oracle in $OH\n"; @@ -277,8 +276,8 @@ # --- How shall we link with Oracle? Let me count the ways... -my $mkfile; # primary .mk file to use -my @mkfiles; # $mkfile plus any files it 'includes' +my $mkfile; # primary .mk file to use +my @mkfiles; # $mkfile plus any files it 'includes' my $linkwith = ""; my $linkwith_msg = ""; my $need_ldlp_env; @@ -287,16 +286,16 @@ my @libclntsh = glob("$OH/libclntsh.$so*"); if ($^O eq 'VMS') { - my $OCIINCLUDE = join " ", vmsify("$OH/rdbms/"), - vmsify("$OH/rdbms/public"), - vmsify("$OH/rdbms/demo/"), - vmsify("$OH/rdbms/demo/oci_demo/"), - vmsify("$OH/netconfig/demo/"); # eg nzt.h in 8.1.7 on VMS + my $OCIINCLUDE = join " ", vmsify("$OH/rdbms/"), + vmsify("$OH/rdbms/public"), + vmsify("$OH/rdbms/demo/"), + vmsify("$OH/rdbms/demo/oci_demo/"), + vmsify("$OH/netconfig/demo/"); # eg nzt.h in 8.1.7 on VMS $opts{INC} = "$OCIINCLUDE $dbi_arch_dir"; $opts{OBJECT} = 'oracle.obj dbdimp.obj oci7.obj oci8.obj' if $] < 5.005; unless ($ENV{PERL_ENV_TABLES}) { - print qq{ + print qq{ The logical PERL_ENV_TABLES is not set. This may mean that some of the UTF functionallity tests may fail, @@ -306,7 +305,7 @@ table, please set this logical: \$ DEFINE PERL_ENV_TABLES LNM\$PROCESS - \a\n}; + \a\n}; sleep 3; } } @@ -315,9 +314,9 @@ my $OCIDIR = ""; find( sub { - print "Found $_ directory\n" if /^OCI\d*$/i; - $OCIDIR = $_ if /^OCI\d*$/i && $OCIDIR lt $_; - $File::Find::prune = 1 if -d $_ && $_ !~ /^\./; + print "Found $_ directory\n" if /^OCI\d*$/i; + $OCIDIR = $_ if /^OCI\d*$/i && $OCIDIR lt $_; + $File::Find::prune = 1 if -d $_ && $_ !~ /^\./; }, $OH ); $OCIDIR = 'sdk' if !$OCIDIR && -d "$OH/sdk"; # Instant Client SDK @@ -338,14 +337,14 @@ my %OCILIB; my $oci_compiler_dir; my @oci_compiler_dirs = - map { -d "$OH/$OCIDIR/lib/$_" ? "$OH/$OCIDIR/lib/$_": () } - $Config{cc} eq 'bcc32' ? qw(BORLAND BC) : qw(MSVC); + map { -d "$OH/$OCIDIR/lib/$_" ? "$OH/$OCIDIR/lib/$_": () } + $Config{cc} eq 'bcc32' ? qw(BORLAND BC) : qw(MSVC); find( sub { - $File::Find::prune = 1 if -d $_ && $_ !~ /^\./; - return unless /^(OCI|ORA).*\.LIB$/i; - ($oci_compiler_dir = $File::Find::dir) =~ s:^.*/::; - print "Found $OCIDIR/lib/$oci_compiler_dir/$_ library\n"; - $OCILIB{uc($_)} = $_; + $File::Find::prune = 1 if -d $_ && $_ !~ /^\./; + return unless /^(OCI|ORA).*\.LIB$/i; + ($oci_compiler_dir = $File::Find::dir) =~ s:^.*/::; + print "Found $OCIDIR/lib/$oci_compiler_dir/$_ library\n"; + $OCILIB{uc($_)} = $_; }, @oci_compiler_dirs ); # sort the version numbered libs into assending order my @OCILIB = sort grep { /(OCI|ORA)\d\d+\./i } keys %OCILIB; @@ -359,8 +358,8 @@ that you have your OCI installed in your oracle home ($OH) directory and that it has the following files (and probably more): - $OH\\$OCIDIR\\include\\oratypes.h - $OH\\$OCIDIR\\lib\\$oci_compiler_dir\\$OCILIB.lib + $OH\\$OCIDIR\\include\\oratypes.h + $OH\\$OCIDIR\\lib\\$oci_compiler_dir\\$OCILIB.lib Please install OCI or send comments back to dbi-users\@perl.org if you have an OCI directory other than $OCIDIR. @@ -370,8 +369,8 @@ ppm install ftp://ftp.esoftmatic.com/outgoing/DBI/5.8.3/DBD-Oracle.ppd } unless (-e "$OH/$OCIDIR/include/oratypes.h" - && -e "$OH/$OCIDIR/lib/$oci_compiler_dir/$OCILIB.lib") - or $::opt_F; + && -e "$OH/$OCIDIR/lib/$oci_compiler_dir/$OCILIB.lib") + or $::opt_F; print "Using $OCIDIR/lib/$oci_compiler_dir/$OCILIB.lib\n"; $opts{LIBS} = [ "-L$OH/$OCIDIR/LIB/$oci_compiler_dir $OCILIB" ]; @@ -418,11 +417,11 @@ # the libclntsh.$so (without version suffix) may be missing # we need it to link to so try to create it eval { - print "You don't have a libclntsh.$so file, only @libclntsh\n"; - my $libclntsh_v = (grep { /\d$/ } sort @libclntsh)[0]; # tacky but sufficient - print "So I'm going to create a $OH/libclntsh.$so symlink to $libclntsh_v\n"; + print "You don't have a libclntsh.$so file, only @libclntsh\n"; + my $libclntsh_v = (grep { /\d$/ } sort @libclntsh)[0]; # tacky but sufficient + print "So I'm going to create a $OH/libclntsh.$so symlink to $libclntsh_v\n"; symlink($libclntsh_v, "$OH/libclntsh.$so") - or warn "Can't create symlink $OH/libclntsh.$so to $libclntsh_v: $!\n"; + or warn "Can't create symlink $OH/libclntsh.$so to $libclntsh_v: $!\n"; } unless -e "$OH/libclntsh.$so"; check_ldlibpthname($OH); @@ -434,7 +433,7 @@ my $lib = "clntsh"; $linkwith_msg = "-l$lib."; - $opts{LIBS} = [ "-L$OH -l$lib $syslibs" ]; + $opts{LIBS} = [ "-L$OH -Wl,-rpath,$OH -l$lib $syslibs" ]; my $inc = join " ", map { "-I$_" } find_headers(); $opts{INC} = "$inc -I$dbi_arch_dir"; @@ -448,12 +447,12 @@ $MK{CCINCLUDES} = '-I$(ICINCHOME)'; # undo odd refinition in demo_xe.mk # From linux Oracle XE (10.2.0): - # ICINCHOME=$(ORACLE_HOME)/rdbms/public/ - # ICLIBHOME=$(ORACLE_HOME)/lib/ - # ICLIBPATH=-L$(ICLIBHOME) - # THREADLIBS=-lpthread [initially -lthread then redefined] - # CCLIB=$(ICLIBPATH) -lclntsh $(THREADLIBS) - # CCINCLUDES = -I$(ICINCHOME) [see above] + # ICINCHOME=$(ORACLE_HOME)/rdbms/public/ + # ICLIBHOME=$(ORACLE_HOME)/lib/ + # ICLIBPATH=-L$(ICLIBHOME) + # THREADLIBS=-lpthread [initially -lthread then redefined] + # CCLIB=$(ICLIBPATH) -lclntsh $(THREADLIBS) + # CCINCLUDES = -I$(ICINCHOME) [see above] # CCFLAGS=$(CCINCLUDES) -DLINUX -D_GNU_SOURCE -D_REENTRANT -g [initially without -DLINUX -D_GNU_SOURCE] my $cclib = expand_mkvars($MK{CCLIB}, 0, 1); my $ccflags = expand_mkvars($MK{CCFLAGS}, 0, 1); @@ -465,27 +464,27 @@ check_ldlibpthname(); } -else { # --- trawl the guts of Oracle's make files looking the how it wants to link +else { # --- trawl the guts of Oracle's make files looking the how it wants to link #Lincoln: pick the right library path check_ldlibpthname(); my $libdir = ora_libdir(); my @ora_libs = <$OH/$libdir/lib*>; if (@ora_libs < 6) { # just a helpful hint - warn "\nYou don't seem to have many Oracle libraries installed. If the" - ."\nbuild fails you probably need to install more Oracle software.\n\n"; - sleep 6; + warn "\nYou don't seem to have many Oracle libraries installed. If the" + ."\nbuild fails you probably need to install more Oracle software.\n\n"; + sleep 6; } # can we give the shared library a helping hand? my @shared = grep { m:/lib(cl(ie)?ntsh|oracle).\w+$:o } @ora_libs; # show original value of ORA_CLIENT_LIB if defined ... print "\$ORA_CLIENT_LIB=$ENV{ORA_CLIENT_LIB}\n" - if defined $ENV{ORA_CLIENT_LIB}; + if defined $ENV{ORA_CLIENT_LIB}; # ... before we then set it how it probably should be set # XXX but we still need to write it into the generated Makefile. $ENV{ORA_CLIENT_LIB} = 'shared' - if !defined $ENV{ORA_CLIENT_LIB} - && ($opts{LINKTYPE}||'') ne 'static' && @shared && !$::opt_c; + if !defined $ENV{ORA_CLIENT_LIB} + && ($opts{LINKTYPE}||'') ne 'static' && @shared && !$::opt_c; my $linkvia = fetch_oci_macros($mkfile) if -f $mkfile; @@ -501,83 +500,83 @@ my @build_rules = grep { $mk_target_rules{$_} } qw(build build64 build32); my $build_target = "build"; if (@build_rules && $::opt_b) { - print "\n"; + print "\n"; - $build_target = "build32" if $mk_target_rules{build32}; - $build_target = "build64" if $mk_target_rules{build64} && perl_is_64bit(); - $build_target = $::opt_r if $::opt_r; + $build_target = "build32" if $mk_target_rules{build32}; + $build_target = "build64" if $mk_target_rules{build64} && perl_is_64bit(); + $build_target = $::opt_r if $::opt_r; - print "Attempting to discover Oracle OCI $build_target rules\n"; + print "Attempting to discover Oracle OCI $build_target rules\n"; - # create dummy C file to keep 'make $mkfile' happy - my $DBD_ORA_OBJ = 'DBD_ORA_OBJ'; + # create dummy C file to keep 'make $mkfile' happy + my $DBD_ORA_OBJ = 'DBD_ORA_OBJ'; open DBD_ORA_C, ">$DBD_ORA_OBJ.c" - or die "Can't create temporary $DBD_ORA_OBJ.c file in current directory: $!\n"; + or die "Can't create temporary $DBD_ORA_OBJ.c file in current directory: $!\n"; print DBD_ORA_C "int main() { return 1; }\n"; close DBD_ORA_C; - sleep 2; # - system("make $DBD_ORA_OBJ.o CC='$Config{cc}'"); # make a valid .o file. + sleep 2; # + system("make $DBD_ORA_OBJ.o CC='$Config{cc}'"); # make a valid .o file. - my $make = "$Config{make} -f $mkfile $build_target" - ." ECHODO=echo ECHO=echo GENCLNTSH='echo genclntsh' CC=true" - ." OPTIMIZE= CCFLAGS=" - ." EXE=DBD_ORA_EXE OBJS=$DBD_ORA_OBJ.o"; - print "by executing: [$make]\n"; - my @cmds = `$make 2>&1`; - chomp @cmds; - print "returned:\n[".join("]\n[",@cmds)."]\n" if $::opt_v; - warn "WARNING: Oracle build rule discovery failed ($?)\n" if $?; - warn "Add path to $Config{make} command into your PATH environment variable.\n" - if $? && "@cmds" =~ /make.*not found/; # hint + my $make = "$Config{make} -f $mkfile $build_target" + . q/ ECHODO=echo ECHO=echo GENCLNTSH='echo genclntsh' CC=true/ + . q/ OPTIMIZE= CCFLAGS=/ + . qq/ EXE=DBD_ORA_EXE OBJS=$DBD_ORA_OBJ.o/; + print "by executing: [$make]\n"; + my @cmds = `$make 2>&1`; + chomp @cmds; + print "returned:\n[".join("]\n[",@cmds)."]\n" if $::opt_v; + warn "WARNING: Oracle build rule discovery failed ($?)\n" if $?; + warn "Add path to $Config{make} command into your PATH environment variable.\n" + if $? && "@cmds" =~ /make.*not found/; # hint - my @filtered_cmds; + my @filtered_cmds; while (my $line = shift @cmds) { - # join lines split with \'s - while ($line =~ s/\\$/ /) { $line .= shift @cmds; } - # remove any echo's as the following line should be the result of the echo - next if $line =~ /^\s*\S*echo\s+/; - next if $line =~ /^\s*\S*make\s+/; # remove recursive calls to make - next if $line =~ /^\s*\S*make(\[\d\])?:/; # remove message rom "make:" or "make[x]:" - - next if $line =~ /^\s*$/; # remove any blank lines - push @filtered_cmds, $line; - } - print "reduced to:\n[".join("]\n[",@filtered_cmds)."]\n" - if $::opt_v && "@filtered_cmds" ne "@cmds"; - @cmds = @filtered_cmds; - - my @prolog; push @prolog, shift @cmds while @cmds && $cmds[0] !~ /DBD_ORA_EXE/; - print "Oracle oci build prolog:\n \t[", join("]\n\t[", @prolog), "]\n" if @prolog; - print "Oracle oci build command:\n\t[", join("]\n\t[", @cmds ), "]\n"; - if (@cmds == 1 && (my $build = shift @cmds) =~ /DBD_ORA_EXE/) { - $build =~ s/\s*true\s+//; # remove dummy compiler - $build =~ s/$DBD_ORA_OBJ.o//; # remove dummy object file - $build =~ s/\S+\s+DBD_ORA_EXE//; # remove dummy exe file and preceding flag - $build =~ s/-o build\S*//; # remove -o target that confuses gcc at least on Sun - $linkwith = $build; - # delete problematic crt?.o on solaris - $linkwith = del_crtobj($linkwith, 1) if $^O eq 'solaris'; - } - else { - print "WARNING: Unable to interpret Oracle build commands from $mkfile.\a\n"; - print "(Will continue by using fallback approach.)\n"; - sleep 2; - $::opt_b = 0; - } - unlink "$DBD_ORA_OBJ.c", "$DBD_ORA_OBJ.o" - unless $^O eq 'darwin'; # why? - print "\n"; + # join lines split with \'s + while ($line =~ s/\\$/ /) { $line .= shift @cmds; } + # remove any echo's as the following line should be the result of the echo + next if $line =~ m/^\s*\S*echo\s+/; + next if $line =~ m/^\s*\S*make\s+/; # remove recursive calls to make + next if $line =~ m/^\s*\S*make(\[\d\])?:/; # remove message rom "make:" or "make[x]:" + + next if $line =~ m/^\s*$/; # remove any blank lines + push @filtered_cmds, $line; + } + print "reduced to:\n[".join("]\n[",@filtered_cmds)."]\n" + if $::opt_v && "@filtered_cmds" ne "@cmds"; + @cmds = @filtered_cmds; + + my @prolog; push @prolog, shift @cmds while @cmds && $cmds[0] !~ /DBD_ORA_EXE/; + print "Oracle oci build prolog:\n \t[", join("]\n\t[", @prolog), "]\n" if @prolog; + print "Oracle oci build command:\n\t[", join("]\n\t[", @cmds ), "]\n"; + if (@cmds == 1 && (my $build = shift @cmds) =~ /DBD_ORA_EXE/) { + $build =~ s/\s*true\s+//; # remove dummy compiler + $build =~ s/$DBD_ORA_OBJ.o//; # remove dummy object file + $build =~ s/\S+\s+DBD_ORA_EXE//; # remove dummy exe file and preceding flag + $build =~ s/-o build\S*//; # remove -o target that confuses gcc at least on Sun + $linkwith = $build; + # delete problematic crt?.o on solaris + $linkwith = del_crtobj($linkwith, 1) if $^O eq 'solaris'; + } + else { + print "WARNING: Unable to interpret Oracle build commands from $mkfile.\a\n"; + print "(Will continue by using fallback approach.)\n"; + sleep 2; + $::opt_b = 0; + } + unlink "$DBD_ORA_OBJ.c", "$DBD_ORA_OBJ.o" + unless $^O eq 'darwin'; # why? + print "\n"; } else { - print "WARNING: Oracle $mkfile doesn't define a 'build' rule.\n" if $::opt_b; - $::opt_b = 0; - print "\n"; - print "WARNING: I will now try to guess how to build and link DBD::Oracle for you.$BELL\n"; - print " This kind of guess work is very error prone and Oracle-version sensitive.\n"; - print " It is possible that it won't be supported in future versions of DBD::Oracle.\n"; - print " *PLEASE* notify dbi-users about exactly _why_ you had to build it this way.\n"; - print "\n"; - sleep 6; + print "WARNING: Oracle $mkfile doesn't define a 'build' rule.\n" if $::opt_b; + $::opt_b = 0; + print "\n"; + print "WARNING: I will now try to guess how to build and link DBD::Oracle for you.$BELL\n"; + print " This kind of guess work is very error prone and Oracle-version sensitive.\n"; + print " It is possible that it won't be supported in future versions of DBD::Oracle.\n"; + print " *PLEASE* notify dbi-users about exactly _why_ you had to build it this way.\n"; + print "\n"; + sleep 6; } $linkwith =~ s/-Y P,/-YP,/g if $Config{gccversion}; @@ -651,8 +650,8 @@ # # Jay: Add Librarys where one gets Unresolved symbols # - if ( ( $osvers >= 11 and $client_version_full =~ /^8\.1\.6/ ) - or ( $osvers >= 11 and $OH =~ m,/8\.1\.6, ) ) { + if ( ( $osvers >= 11 and $client_version_full =~ m/^8\.1\.6/ ) + or ( $osvers >= 11 and $OH =~ m|/8\.1\.6| ) ) { my @extraLib = qw[libqsmashr.sl libclntsh.sl]; foreach my $extraLib (@extraLib) { if (-r "$OH/lib/$extraLib") { @@ -663,9 +662,9 @@ } if ($osvers >= 11 and $linkwith =~ m/-l:libcl.a/) { - print "WARNING: stripping -l:libcl.a from liblist (conflict with ld looking for shared libs)\n"; - $linkwith =~ s/\s*-l:libcl.a\b//g; - } + print "WARNING: stripping -l:libcl.a from liblist (conflict with ld looking for shared libs)\n"; + $linkwith =~ s/\s*-l:libcl.a\b//g; + } #lincoln: this is bringing back everything we thought we removed... (like libcl.a) # I wonder if this should targetted less specifically than only HPUX 11 @@ -680,59 +679,59 @@ } my $ccf = join " ", map { $_ || '' } @Config{qw(ccflags ccldflags cccdlflags)}; - if ($Config{cc} =~ /gcc/i) { - print "WARNING: perl was not built with -fpic or -fPIC in compiler flags.\n", - " You may need to rebuild perl from sources.\n", - " See instructions in DBD::Oracle::Troubleshooting::Hpux\n" - unless $ccf =~ m/-fpic\b/i; + if ($Config{cc} =~ m/gcc/i) { + print "WARNING: perl was not built with -fpic or -fPIC in compiler flags.\n", + " You may need to rebuild perl from sources.\n", + " See instructions in DBD::Oracle::Troubleshooting::Hpux\n" + unless $ccf =~ m/-fpic\b/i; } else { print "WARNING: perl was not built with +z or +Z in compiler flags.\n", " You may need to rebuild perl from sources.\n", " See instructions in DBD::Oracle::Troubleshooting::Hpux\n" - unless $ccf =~ m/\+[zZ]/; + unless $ccf =~ m/\+[zZ]/; } } - if ($::opt_b) { # The simple approach - $opts{dynamic_lib} = { OTHERLDFLAGS => "$::opt_g $linkwith" }; - $linkwith_msg = "OTHERLDFLAGS = $linkwith [from '$build_target' rule]"; - } - else { # the not-so-simple approach! - # get a cut down $linkwith to pass to MakeMaker liblist - my $linkwith_s = expand_mkvars($linkwith, 1, 1); - - # convert "/full/path/libFOO.a" into "-L/full/path -lFOO" - # to cater for lack of smarts in MakeMaker / Liblist - # which ignores /foo/bar.a entries! - my $lib_ext_re = "(a|$Config{dlext}|$Config{so})"; - $linkwith_s =~ s!(\S+)/lib(\w+)\.($lib_ext_re)\b!-L$1 -l$2!g; - - # Platform specific fix-ups: - # delete problematic crt?.o on solaris - $linkwith_s = del_crtobj($linkwith_s) if $^O eq 'solaris'; - $linkwith_s =~ s/-l:lib(\w+)\.sl\b/-l$1/g; # for hp-ux - # this kind of stuff should be in a ./hints/* file: - $linkwith_s .= " -lc" if $Config{osname} eq 'dynixptx' - or $Config{archname} =~ /-pc-sco3\.2v5/; - if ($^O eq 'solaris' and $linkwith_s =~ /-lthread/ - and $osvers >= 2.3 and $osvers <= 2.6 - ) { - print "WARNING: Solaris 2.5 bug #1224467 may cause '_rmutex_unlock' error.\n"; - print "Deleting -lthread from link list as a possible workround ($osvers).\n"; - $linkwith_s =~ s/\s*-lthread\b/ /g; - } - - # extract object files, keep for use later - my @linkwith_o; - push @linkwith_o, $1 while $linkwith_s =~ s/(\S+\.[oa])\b//; - # also extract AIX .exp files since they confuse MakeMaker - push @linkwith_o, $1 while $linkwith_s =~ s/(-bI:\S+\.exp)\b//; - - $linkwith_msg = "@linkwith_o $linkwith_s [from $linkvia]"; - $opts{LIBS} = [ "-L$libhome $linkwith_s" ]; - $opts{dynamic_lib} = { OTHERLDFLAGS => "$::opt_g @linkwith_o \$(COMPOBJS)" }; + if ($::opt_b) { # The simple approach + $opts{dynamic_lib} = { OTHERLDFLAGS => "$::opt_g $linkwith" }; + $linkwith_msg = "OTHERLDFLAGS = $linkwith [from '$build_target' rule]"; + } + else { # the not-so-simple approach! + # get a cut down $linkwith to pass to MakeMaker liblist + my $linkwith_s = expand_mkvars($linkwith, 1, 1); + + # convert "/full/path/libFOO.a" into "-L/full/path -lFOO" + # to cater for lack of smarts in MakeMaker / Liblist + # which ignores /foo/bar.a entries! + my $lib_ext_re = "(a|$Config{dlext}|$Config{so})"; + $linkwith_s =~ s!(\S+)/lib(\w+)\.($lib_ext_re)\b!-L$1 -l$2!g; + + # Platform specific fix-ups: + # delete problematic crt?.o on solaris + $linkwith_s = del_crtobj($linkwith_s) if $^O eq 'solaris'; + $linkwith_s =~ s/-l:lib(\w+)\.sl\b/-l$1/g; # for hp-ux + # this kind of stuff should be in a ./hints/* file: + $linkwith_s .= " -lc" if $Config{osname} eq 'dynixptx' + or $Config{archname} =~ /-pc-sco3\.2v5/; + if ($^O eq 'solaris' and $linkwith_s =~ /-lthread/ + and $osvers >= 2.3 and $osvers <= 2.6 + ) { + print "WARNING: Solaris 2.5 bug #1224467 may cause '_rmutex_unlock' error.\n"; + print "Deleting -lthread from link list as a possible workround ($osvers).\n"; + $linkwith_s =~ s/\s*-lthread\b/ /g; + } + + # extract object files, keep for use later + my @linkwith_o; + push @linkwith_o, $1 while $linkwith_s =~ s/(\S+\.[oa])\b//; + # also extract AIX .exp files since they confuse MakeMaker + push @linkwith_o, $1 while $linkwith_s =~ s/(-bI:\S+\.exp)\b//; + + $linkwith_msg = "@linkwith_o $linkwith_s [from $linkvia]"; + $opts{LIBS} = [ "-L$libhome $linkwith_s" ]; + $opts{dynamic_lib} = { OTHERLDFLAGS => "$::opt_g @linkwith_o \$(COMPOBJS)" }; } my $OCIINCLUDE = expand_mkvars($MK{INCLUDE} || '', 0, 0); @@ -750,7 +749,7 @@ $opts{DEFINE} .= ' -Wall -Wno-comment' if $Config{gccversion}; -$opts{DEFINE} .= ' -Xa' if $Config{cc} eq 'clcc'; # CenterLine CC +$opts{DEFINE} .= ' -Xa' if $Config{cc} eq 'clcc'; # CenterLine CC @@ -763,8 +762,8 @@ # Use OCIEnvNlsCreate if available for best unicode behaviour #$opts{DEFINE} .= ' -DNEW_OCI_INIT' if $client_version >= 9.2; $opts{DEFINE} .= ($^O ne 'VMS') - ? " -DORA_OCI_VERSION=\\\"$client_version_full\\\"" - : " -DORA_OCI_VERSION=\"$client_version_full\""; + ? " -DORA_OCI_VERSION=\\\"$client_version_full\\\"" + : " -DORA_OCI_VERSION=\"$client_version_full\""; # force additional special behavior for oci 8. For now, this means # emulating OciLobWriteAppend # use this if, for some reason the default handling for this function @@ -775,10 +774,10 @@ print "\nclient_version=$client_version\n\n"; $opts{DEFINE} .= " -DORA_OCI_102" if ($::opt_V && $client_version == 10.2) - or ( $client_version >= 10.2); + or ( $client_version >= 10.2); $opts{DEFINE} .= " -DORA_OCI_112" if ($::opt_V && $client_version == 11.2) - or ( $client_version >= 11.2); + or ( $client_version >= 11.2); print "\nDEFINE=$opts{DEFINE}\n\n"; # OCIStmntFetch2() is a feature of OCI 9.0.0 @@ -790,11 +789,11 @@ $BELL = "<BELL>" if ($ENV{LOGNAME}||'') eq 'timbo'; $::opt_g = '-g'; if ($Config{gccversion}) { - $opts{DEFINE} .= ' -Wall -Wcast-align -Wpointer-arith'; - $opts{DEFINE} .= ' -Wbad-function-cast -Wcast-qual'; - #$opts{DEFINE} .= ' -Wconversion'; # very noisy so remove to see what people say - $opts{DEFINE} .= ' -Wimplicit -Wimplicit-int -Wimplicit-function-declaration -Werror-implicit-function-declaration -Wimport -Winline -Wlong-long -Wmissing-braces -Wmissing-format-attribute -Wmissing-noreturn -Wmultichar -Wpacked -Wparentheses -Wpointer-arith -Wreturn-type -Wsequence-point -Wsign-compare -Wswitch -Wtrigraphs -Wundef -Wuninitialized -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wwrite-strings -Wbad-function-cast -Wmissing-declarations -Wnested-externs' - if $::opt_w; + $opts{DEFINE} .= ' -Wall -Wcast-align -Wpointer-arith'; + $opts{DEFINE} .= ' -Wbad-function-cast -Wcast-qual'; + #$opts{DEFINE} .= ' -Wconversion'; # very noisy so remove to see what people say + $opts{DEFINE} .= ' -Wimplicit -Wimplicit-int -Wimplicit-function-declaration -Werror-implicit-function-declaration -Wimport -Winline -Wlong-long -Wmissing-braces -Wmissing-format-attribute -Wmissing-noreturn -Wmultichar -Wpacked -Wparentheses -Wpointer-arith -Wreturn-type -Wsequence-point -Wsign-compare -Wswitch -Wtrigraphs -Wundef -Wuninitialized -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wwrite-strings -Wbad-function-cast -Wmissing-declarations -Wnested-externs' + if $::opt_w; } $opts{dynamic_lib}->{OTHERLDFLAGS} .= " $::opt_g"; } @@ -804,12 +803,12 @@ # files, we sadly have to build static on HP-UX 9 :( if ($^O eq 'hpux') { if ($osvers < 10) { - print "WARNING: Forced to build static not dynamic on $^O $osvers.$BELL\n"; - $opts{LINKTYPE} = 'static'; + print "WARNING: Forced to build static not dynamic on $^O $osvers.$BELL\n"; + $opts{LINKTYPE} = 'static'; } else { - print "WARNING: If you have trouble, see DBD::Oracle::Troubleshooting::Hpux...\n" - ." you may have to build your own perl, or go hunting for libraries\n"; + print "WARNING: If you have trouble, see DBD::Oracle::Troubleshooting::Hpux...\n" + ." you may have to build your own perl, or go hunting for libraries\n"; } print "WARNING: If you have trouble, try perl Makefile.PL -l\n" unless $::opt_l; sleep 5; @@ -845,11 +844,11 @@ print "Linker: ". (find_bin('ld')||"not found") ."\n" unless $^O eq 'VMS'; print "Sysliblist: ".read_sysliblist()."\n"; print "Oracle makefiles would have used these definitions but we override them:\n" - if $MK{CFLAGS} || $MK{LDFLAGS} || $MK{LDSTRING}; -print " CC: $MK{CC}\n" if $MK{CC}; -print " CFLAGS: $MK{CFLAGS}\n" if $MK{CFLAGS}; + if $MK{CFLAGS} || $MK{LDFLAGS} || $MK{LDSTRING}; +print " CC: $MK{CC}\n" if $MK{CC}; +print " CFLAGS: $MK{CFLAGS}\n" if $MK{CFLAGS}; print " [".mkvar('CFLAGS',0,1,0). "]\n" if $MK{CFLAGS}; -print " CLIBS: $MK{CLIBS}\n" if $MK{CLIBS}; +print " CLIBS: $MK{CLIBS}\n" if $MK{CLIBS}; print " [".mkvar('CLIBS',0,1,0). "]\n" if $MK{CLIBS}; if ($mk_target_rules{build} && !$::opt_b) { my $rules = join "\n", '', @{ $mk_target_rules{build} }; @@ -963,17 +962,17 @@ my @oh = grep { (glob("$_/libclntsh.$so*"))[0] } @path; if (!@oh) { # failing that, try LD_LIBRARY_PATH or equiv - my (undef, undef, @ldlibpth) = ldlibpth_info(1); - print "using ldlib @ldlibpth\n" if $::opt_v; - @oh = grep { (glob("$_/libclntsh.$so*"))[0] } @ldlibpth; - # for instant client @oh may be actual ORACLE_HOME - # but for non-IC ORACLE_HOME may be dir above a /lib* - s:/lib\w*/?$:: for @oh; # remove possible trailing lib dir + my (undef, undef, @ldlibpth) = ldlibpth_info(1); + print "using ldlib @ldlibpth\n" if $::opt_v; + @oh = grep { (glob("$_/libclntsh.$so*"))[0] } @ldlibpth; + # for instant client @oh may be actual ORACLE_HOME + # but for non-IC ORACLE_HOME may be dir above a /lib* + s:/lib\w*/?$:: for @oh; # remove possible trailing lib dir } if (!@oh) { # else try the traditional kind of install - # this should work for non-instant-client installs ($OH/bin & $OH/lib*) - @oh = grep { (glob("$_/../lib*/libclntsh.$so*"))[0] } @path; - s:/[^/]/?$:: for @oh; + # this should work for non-instant-client installs ($OH/bin & $OH/lib*) + @oh = grep { (glob("$_/../lib*/libclntsh.$so*"))[0] } @path; + s:/[^/]/?$:: for @oh; } if (!@oh && lc($^O) eq 'linux') { # Try the standard Linux RPM location my @loh = glob("/usr/lib/oracle/*/*/lib/libclntsh.$so*"); @@ -994,37 +993,37 @@ my $default_home; if ( ! $oh ) { if ( $Config{osname} eq "MSWin32") { - # Win32::TieRegistry is prefered, but it requires Win32API::Registry - # which is not available in mingw or cygwin - eval { - require Win32::TieRegistry; - $Win32::TieRegistry::Registry->Delimiter("/"); - $hkey = $Win32::TieRegistry::Registry->{"LMachine/SOFTWARE/Oracle/"} + # Win32::TieRegistry is prefered, but it requires Win32API::Registry + # which is not available in mingw or cygwin + eval { + require Win32::TieRegistry; + $Win32::TieRegistry::Registry->Delimiter("/"); + $hkey = $Win32::TieRegistry::Registry->{"LMachine/SOFTWARE/Oracle/"} and $req_ok = 1; - }; - eval { # older name of Win32::TieRegistry - require Tie::Registry; - $Tie::Registry::Registry->Delimiter("/"); - $hkey = $Tie::Registry::Registry->{"LMachine/SOFTWARE/Oracle/"} + }; + eval { # older name of Win32::TieRegistry + require Tie::Registry; + $Tie::Registry::Registry->Delimiter("/"); + $hkey = $Tie::Registry::Registry->{"LMachine/SOFTWARE/Oracle/"} and $req_ok = 1; - } unless $req_ok; - eval { - $default_home = $hkey->{ORACLE_HOME} || ''; - }; - eval { - $Val = sub { - # Return value - my ($hkey) = @_; - return $hkey->{ORACLE_HOME} || ''; - }; - $Keys = sub { - # Return list of sub-folder keys - my ($hkey) = @_; - # MAC: %$hkey and related method calls don't work under - # perl5db, so don't try single stepping through here - return map {m:/$: ? $hkey->{$_} : ()} keys %$hkey; - }; - } if $hkey; + } unless $req_ok; + eval { + $default_home = $hkey->{ORACLE_HOME} || ''; + }; + eval { + $Val = sub { + # Return value + my ($hkey) = @_; + return $hkey->{ORACLE_HOME} || ''; + }; + $Keys = sub { + # Return list of sub-folder keys + my ($hkey) = @_; + # MAC: %$hkey and related method calls don't work under + # perl5db, so don't try single stepping through here + return map {m:/$: ? $hkey->{$_} : ()} keys %$hkey; + }; + } if $hkey; } # Win32::Registry imports some symbols into main:: @@ -1032,29 +1031,29 @@ # MAC: it is available under mingw and might be available under cygwin # If cygwin doesn't have it, move the rest inside the other if block eval { - require Win32::Registry; - $main::HKEY_LOCAL_MACHINE->Open('SOFTWARE\\ORACLE', $hkey); - my $dummy = $main::HKEY_LOCAL_MACHINE; # avoid single use complaint - eval { - my $hval; - $hkey->GetValues($hval); - $default_home = $hval->{ORACLE_HOME}[2] || ''; - }; - $Val = sub { - # Return value - my ($hkey) = @_; - my $hval; - $hkey->GetValues($hval); - return $hval->{ORACLE_HOME}[2] || ''; - }; - $Keys = sub { - # Return list of sub-folder keys - my ($hkey) = @_; - my @hkey; - $hkey->GetKeys(\@hkey); - @hkey = map { $hkey->Open($_, $_); $_ } @hkey; - return @hkey; - }; + require Win32::Registry; + $main::HKEY_LOCAL_MACHINE->Open('SOFTWARE\\ORACLE', $hkey); + my $dummy = $main::HKEY_LOCAL_MACHINE; # avoid single use complaint + eval { + my $hval; + $hkey->GetValues($hval); + $default_home = $hval->{ORACLE_HOME}[2] || ''; + }; + $Val = sub { + # Return value + my ($hkey) = @_; + my $hval; + $hkey->GetValues($hval); + return $hval->{ORACLE_HOME}[2] || ''; + }; + $Keys = sub { + # Return list of sub-folder keys + my ($hkey) = @_; + my @hkey; + $hkey->GetKeys(\@hkey); + @hkey = map { $hkey->Open($_, $_); $_ } @hkey; + return @hkey; + }; } unless $req_ok; # Workaround Win32::TieRegistry FETCH error during global destruction. @@ -1063,38 +1062,38 @@ # Look for ORACLE_HOME in all ORACLE sub-folders, use last one found # before 8.1.5, there should be only one eval { - my ($oh1, %oh); - my @hkey = ($hkey); - # JLU: December 5, 2002: if the "default" home is set and has - # an OCI directory, then use it. - if ($default_home && -d $default_home && -d $default_home . "/oci") { - $oh = $default_home; - } else { - # use previous logic if default home doesn't have OCI - # directory - while (@hkey) { - $hkey = shift @hkey; - $oh = $oh1, $oh{$oh1} = 1 - if ($oh1 = &$Val($hkey)) && -d $oh1; - push @hkey, &$Keys($hkey); - } - if (1 < keys %oh) { - # JLU: 8/21/01 Oracle's default home is the first one in - # the path, at least with 8i - print "\n\007Multiple Oracle homes: ", join(" ", sort keys %oh), "\n\n"; - my @path = split(";", $ENV{PATH}); - my $dir; - foreach $dir (@path) { - # the path will be c:\path\to\home\bin, so remove \bin if it's there. - $dir =~ s/\\bin$//; - if (defined($oh{$dir})) { - print "$dir is first in the PATH, so we'll use that as Oracle's default home.\n\n"; - $oh = $dir; - last; - } - } - } - } + my ($oh1, %oh); + my @hkey = ($hkey); + # JLU: December 5, 2002: if the "default" home is set and has + # an OCI directory, then use it. + if ($default_home && -d $default_home && -d $default_home . "/oci") { + $oh = $default_home; + } else { + # use previous logic if default home doesn't have OCI + # directory + while (@hkey) { + $hkey = shift @hkey; + $oh = $oh1, $oh{$oh1} = 1 + if ($oh1 = &$Val($hkey)) && -d $oh1; + push @hkey, &$Keys($hkey); + } + if (1 < keys %oh) { + # JLU: 8/21/01 Oracle's default home is the first one in + # the path, at least with 8i + print "\n\007Multiple Oracle homes: ", join(" ", sort keys %oh), "\n\n"; + my @path = split(";", $ENV{PATH}); + my $dir; + foreach $dir (@path) { + # the path will be c:\path\to\home\bin, so remove \bin if it's there. + $dir =~ s/\\bin$//; + if (defined($oh{$dir})) { + print "$dir is first in the PATH, so we'll use that as Oracle's default home.\n\n"; + $oh = $dir; + last; + } + } + } + } } if defined $Keys; } @@ -1106,14 +1105,17 @@ sub read_sysliblist { my $syslibs = (-f "$OH/lib/sysliblist") - ? read_file("$OH/lib/sysliblist") - : (-f "$OH/rdbms/lib/sysliblist") ? read_file("$OH/rdbms/lib/sysliblist") : ''; + ? read_file("$OH/lib/sysliblist") + : (-f "$OH/rdbms/lib/sysliblist") ? read_file("$OH/rdbms/lib/sysliblist") : ''; if ($^O eq "hpux") { $syslibs =~ s/-l:lib(\w+).(sl|a)\b/-l$1/g; $syslibs =~ s/\s*-ldld\b//g; $linkwith =~ m/-lcl\b/ or $syslibs =~ s/\s*-lcl\b//g; } + if (lc(@Config{qw(myuname)}) =~ /debian/) { + $syslibs .= " -Wl,--no-as-needed -lnnz12 -lons -lclntshcore -lipc1 -lmql1"; + } return $syslibs; } @@ -1145,8 +1147,8 @@ my @del; push @del, $1 while $str =~ s:([^\s=]*\bcrt[1in]\.o)\b::; if ($orig ne $str) { - print "Deleted @del from link args.\n" if $verbose; - print "del_crtobj: $orig\n : $str\n@del\n" if $::opt_v; + print "Deleted @del from link args.\n" if $verbose; + print "del_crtobj: $orig\n : $str\n@del\n" if $::opt_v; } return $str; } @@ -1155,19 +1157,19 @@ sub find_mkfile { my @mk_oci32 = ( - 'rdbms/demo/demo_xe.mk', + 'rdbms/demo/demo_xe.mk', 'rdbms/demo/demo_rdbms32.mk', 'rdbms/demo/demo_rdbms.mk', 'rdbms/lib/ins_rdbms.mk', #Oracle 11 full client 'sdk/demo/demo.mk' #OIC .mk location ); my @mk_oci64 = ( - 'rdbms/demo/demo_xe.mk', - 'rdbms/lib/oracle.mk', - 'rdbms/demo/oracle.mk', - 'rdbms/demo/demo_rdbms.mk', - 'rdbms/demo/demo_rdbms64.mk', - 'rdbms/lib/ins_rdbms.mk', #Oracle 11 full client + 'rdbms/demo/demo_xe.mk', + 'rdbms/lib/oracle.mk', + 'rdbms/demo/oracle.mk', + 'rdbms/demo/demo_rdbms.mk', + 'rdbms/demo/demo_rdbms64.mk', + 'rdbms/lib/ins_rdbms.mk', #Oracle 11 full client 'sdk/demo/demo.mk' # git issue 20 - path on mac os ); my @mk_oci = perl_is_64bit() ? @mk_oci64 : @mk_oci32; @@ -1180,37 +1182,37 @@ my @mkplaces = ($::opt_p) ? (@mk_oci) : (@mk_oci); if ($::opt_m) { - $::opt_m = cwd()."/$::opt_m" unless $::opt_m =~ m:^/:; - die "-m $::opt_m: not found" unless -f $::opt_m; - unshift @mkplaces, $::opt_m; + $::opt_m = cwd()."/$::opt_m" unless $::opt_m =~ m:^/:; + die "-m $::opt_m: not found" unless -f $::opt_m; + unshift @mkplaces, $::opt_m; } my $mkfile; - foreach my $place (@mkplaces) { - $place = "$OH/$place" - unless $place =~ m:^[/\.]:; # abs or relative path - next unless -f $place; - $mkfile ||= $place; # use first one found - print "Found $place\n"; + for my $place (@mkplaces) { + $place = "$OH/$place" + unless $place =~ m:^[/\.]:; # abs or relative path + next unless -f $place; + $mkfile ||= $place; # use first one found + print "Found $place\n"; } unless ($^O eq 'MSWin32' || $^O eq 'VMS' || ($mkfile && -f $mkfile) || $::opt_F) { - $::opt_l or return ($mkfile = undef); - die qq{ - Unable to locate an oracle.mk or other suitable *.mk - file in your Oracle installation. (I looked in - @mkplaces under $OH) - - The oracle.mk (or demo_rdbms.mk) file is part of the Oracle - RDBMS product. You need to build DBD::Oracle on a - system which has one of these Oracle components installed. - (Other *.mk files such as the env_*.mk files will not work.) - Alternatively you can use Oracle Instant Client. - - In the unlikely event that a suitable *.mk file is installed - somewhere non-standard you can specify where it is using the -m option: - perl Makefile.PL -m /path/to/your.mk + $::opt_l or return ($mkfile = undef); + die qq{ + Unable to locate an oracle.mk or other suitable *.mk + file in your Oracle installation. (I looked in + @mkplaces under $OH) + + The oracle.mk (or demo_rdbms.mk) file is part of the Oracle + RDBMS product. You need to build DBD::Oracle on a + system which has one of these Oracle components installed. + (Other *.mk files such as the env_*.mk files will not work.) + Alternatively you can use Oracle Instant Client. + + In the unlikely event that a suitable *.mk file is installed + somewhere non-standard you can specify where it is using the -m option: + perl Makefile.PL -m /path/to/your.mk - See the appropriate troubleshooting guide for your OS for more information and some alternatives. - }; + See the appropriate troubleshooting guide for your OS for more information and some alternatives. + }; } print "Using $mkfile\n"; @@ -1227,32 +1229,32 @@ # Don't include the following definitions in the generated # makefile (note that %MK stills gets these values). my @edit = qw( - SHELL CC CPP CFLAGS CCFLAGS OPTIMIZE ASFLAGS RCC LD LDFLAGS - AR AS CHMOD ECHO EXE OBJS PERL OBJ_EXT LIB_EXT VERSION + SHELL CC CPP CFLAGS CCFLAGS OPTIMIZE ASFLAGS RCC LD LDFLAGS + AR AS CHMOD ECHO EXE OBJS PERL OBJ_EXT LIB_EXT VERSION ); my %edit; @edit{@edit} = ('$_ = ""') x @edit; $edit{ORA_NLS} = $edit{ORA_NLS33} = $edit{ORA_NLS32} = q{ - print "Deleting $_\n", - " because it is not already set in the environment\n", - " and it can cause ORA-01019 errors.\n"; - $_ = ''; + print "Deleting $_\n", + " because it is not already set in the environment\n", + " and it can cause ORA-01019 errors.\n"; + $_ = ''; } unless $ENV{ORA_NLS} || $ENV{ORA_NLS33} || $ENV{ORA_NLS32} - || 1; # Old problem? Let's try without it for a while + || 1; # Old problem? Let's try without it for a while $edit{COMPOBJS} = q{ - # Firstly a Solaris specific edit: - $_ = del_crtobj($_) if $^O eq 'solaris'; + # Firstly a Solaris specific edit: + $_ = del_crtobj($_) if $^O eq 'solaris'; - # Delete any object files in COMPOBJS that don't actually exist - my $of; - foreach $of (split(/=|\s+/)) { - next if !$of or $of eq "COMPOBJS"; - my $obj = expand_mkvars($of,0,0); - next if -e $obj; - print "Deleting $of from COMPOBJS because $obj doesn't exist.\n"; - s:\Q$of::; - } + # Delete any object files in COMPOBJS that don't actually exist + my $of; + foreach $of (split(/=|\s+/)) { + next if !$of or $of eq "COMPOBJS"; + my $obj = expand_mkvars($of,0,0); + next if -e $obj; + print "Deleting $of from COMPOBJS because $obj doesn't exist.\n"; + s:\Q$of::; + } }; # deal with (some subversions) of Oracle8.0.3's incompatible use of OBJ_EXT @@ -1266,117 +1268,117 @@ my $lastline = ''; my @lines = read_inc_file($file); for(1; $_ = shift(@lines); $lastline = $_){ - # Join split lines but retain backwack and newlines: - $_ .= shift @lines while(m/\\[\r\n]+$/); - chomp; - push @MK, '' if $_ eq '' and $lastline ne ''; # squeeze multiple blank lines - next unless $_; - - if ($incompat_ext) { - s/\.(\$\(OBJ_EXT\))/$1/g; - s/\.(\$\(LIB_EXT\))/$1/g; - } - # skip compiler options for undesirable compilers - m/^ifdef (\w+)/ and do { - if ($ignore_def{$1}) { - $_ = shift @lines until m/^endif/; - next; - } - }; + # Join split lines but retain backwack and newlines: + $_ .= shift @lines while(m/\\[\r\n]+$/); + chomp; + push @MK, '' if $_ eq '' and $lastline ne ''; # squeeze multiple blank lines + next unless $_; + + if ($incompat_ext) { + s/\.(\$\(OBJ_EXT\))/$1/g; + s/\.(\$\(LIB_EXT\))/$1/g; + } + # skip compiler options for undesirable compilers + m/^ifdef (\w+)/ and do { + if ($ignore_def{$1}) { + $_ = shift @lines until m/^endif/; + next; + } + }; if (m!^([-\w/+.\$()\s]+)\s*:+\s*([^=]*)!) { # skip targets my @tgts = split(/ /, $1); # multiple target names in Oracle9i's demo_rdbms.mk - for (@tgts) { $mk_target_deps{$_} = $2 || '' } - my @rules; + for (@tgts) { $mk_target_deps{$_} = $2 || '' } + my @rules; while (@lines && $lines[0] =~ m!^\t! && chomp $lines[0]) { my $tmp_line = shift @lines; - while($tmp_line =~ m!\\$!) { # continuations! + while($tmp_line =~ m!\\$!) { # continuations! $tmp_line =~ s/\s+\\$/ /; $tmp_line .= shift @lines; chomp($tmp_line); } - push @rules, $tmp_line; - #print "target @tgts => $mk_target_deps{$tgt} => @{$mk_target_rules{$tgt}}\n"; + push @rules, $tmp_line; + #print "target @tgts => $mk_target_deps{$tgt} => @{$mk_target_rules{$tgt}}\n"; } - for (@tgts) { push @{ $mk_target_rules{$_} ||= [] }, @rules } + for (@tgts) { push @{ $mk_target_rules{$_} ||= [] }, @rules } next; } - next if m!^\t!; # skip target build rules - next if m/^\s*\.SUFFIXES/; + next if m!^\t!; # skip target build rules + next if m/^\s*\.SUFFIXES/; - unless($MK{mkver}) { # still want to get version number - my $line = $_; $line =~ s/[\\\r\n]/ /g; - $MK{mkver} = $mkver = $1 - if $line =~ m/\$Header:.*?\.mk.+(\d+\.\d+)/; - } - - # We always store values into %MK before checking %edit - # %edit can edit this in addition to $_ if needed. - my $name; - if (m/^\s*(\w+)\s*(\+?)=\s*/) { - $name = $1; - my $append = $2; - my $value = $'; - $value =~ s/^\@`/`/; - if ($append) { - my $expanded = expand_mkvars($value, 0, 1); - print "Appending '$expanded' to $name\n" if $::opt_v; - $value = $MK{$name} ? "$MK{$name} $expanded" : $expanded; - } - elsif ($MK{$name} && $MK{$name} ne $value) { - print "$name macro redefined by Oracle\n from $MK{$name}\n to $value\n" - if $::opt_d; - } - $MK{$name} = $value; - $MK{$name} =~ s/^([^#]*)#.*/$1/; # remove comments - - if (exists $edit{$name}) { - my $pre = $_; - eval $edit{$name}; # execute code to edit $_ - print "Edit $name ($edit{$name}) failed: $@\n" if $@; - if ($_ ne $pre and $::opt_v) { - $_ ? print "Edited $name definition\n from: $pre\n to: $_\n" - : print "Deleted $name definition: $pre\n"; - } - } - } + unless($MK{mkver}) { # still want to get version number + my $line = $_; $line =~ s/[\\\r\n]/ /g; + $MK{mkver} = $mkver = $1 + if $line =~ m/\$Header:.*?\.mk.+(\d+\.\d+)/; + } - push(@MK, $_); + # We always store values into %MK before checking %edit + # %edit can edit this in addition to $_ if needed. + my $name; + if (m/^\s*(\w+)\s*(\+?)=\s*/) { + $name = $1; + my $append = $2; + my $value = $'; + $value =~ s/^\@`/`/; + if ($append) { + my $expanded = expand_mkvars($value, 0, 1); + print "Appending '$expanded' to $name\n" if $::opt_v; + $value = $MK{$name} ? "$MK{$name} $expanded" : $expanded; + } + elsif ($MK{$name} && $MK{$name} ne $value) { + print "$name macro redefined by Oracle\n from $MK{$name}\n to $value\n" + if $::opt_d; + } + $MK{$name} = $value; + $MK{$name} =~ s/^([^#]*)#.*/$1/; # remove comments + + if (exists $edit{$name}) { + my $pre = $_; + eval $edit{$name}; # execute code to edit $_ + print "Edit $name ($edit{$name}) failed: $@\n" if $@; + if ($_ ne $pre and $::opt_v) { + $_ ? print "Edited $name definition\n from: $pre\n to: $_\n" + : print "Deleted $name definition: $pre\n"; + } + } + } + + push(@MK, $_); } # --- now decide what to link with --- my $linkvia; if ($::opt_n) { - $linkvia = "\$($::opt_n)" if $MK{$::opt_n}; - warn "Can't use '$::opt_n': not defined by .mk files\n" - unless $linkvia; + $linkvia = "\$($::opt_n)" if $MK{$::opt_n}; + warn "Can't use '$::opt_n': not defined by .mk files\n" + unless $linkvia; } # modern Oracle .mk files define OCISTATICLIBS and OCISHAREDLIBS if (!$linkvia && ($MK{OCISHAREDLIBS} || $MK{OCISTATICLIBS})) { - $linkvia = ''; - if ($MK{OCISTATICLIBS} && - ( ($opts{LINKTYPE}||'') eq 'static' - || "@ARGV" =~ m/\bLINKTYPE=static\b/ - || $::opt_c) + $linkvia = ''; + if ($MK{OCISTATICLIBS} && + ( ($opts{LINKTYPE}||'') eq 'static' + || "@ARGV" =~ m/\bLINKTYPE=static\b/ + || $::opt_c) ) { - $linkvia .= '$(DEF_ON) ' if $MK{DEF_ON}; - $linkvia .= '$(SSCOREED) ' if $MK{SSCOREED}; - $linkvia .= '$(OCISTATICLIBS)'; - } - else { - $linkvia .= '$(SSDBED) ' if $MK{SSDBED}; - $linkvia .= '$(DEF_OPT) ' if $MK{DEF_OPT}; - if ($client_version_full =~ /^8\.0\./ and $^O eq 'dec_osf' and $osvers >= 4.0) { - $linkvia .= '$(SCOREPT) $(NAETAB) $(NAEDHS) $(LLIBRDBMS_CLT) $(LLIBMM) '; - $linkvia .= '$(NETLIBS) $(CORELIBS) $(LLIBCOMMON) $(LLIBEPC) '; - $need_ldlp_env = "LD_LIBRARY_PATH"; - } - $linkvia .= '$(OCISHAREDLIBS)'; - } + $linkvia .= '$(DEF_ON) ' if $MK{DEF_ON}; + $linkvia .= '$(SSCOREED) ' if $MK{SSCOREED}; + $linkvia .= '$(OCISTATICLIBS)'; + } + else { + $linkvia .= '$(SSDBED) ' if $MK{SSDBED}; + $linkvia .= '$(DEF_OPT) ' if $MK{DEF_OPT}; + if ($client_version_full =~ m/^8\.0\./ and $^O eq 'dec_osf' and $osvers >= 4.0) { + $linkvia .= '$(SCOREPT) $(NAETAB) $(NAEDHS) $(LLIBRDBMS_CLT) $(LLIBMM) '; + $linkvia .= '$(NETLIBS) $(CORELIBS) $(LLIBCOMMON) $(LLIBEPC) '; + $need_ldlp_env = "LD_LIBRARY_PATH"; + } + $linkvia .= '$(OCISHAREDLIBS)'; + } } $linkvia = '$(LIBCLNTSH)' if !$linkvia && $MK{LIBCLNTSH}; @@ -1385,29 +1387,29 @@ $linkvia = '$(OCILDLIBS)' if !$linkvia && $MK{OCILDLIBS}; # Now we get into strange land of twisty turny macros - if (!$linkvia && $MK{PROLDLIBS}) { # Oracle 7.3.x - # XXX tweak for threaded perl? - use PROLLSsharedthread - if ($MK{PROLDLIBS} =~ /thread/i && $MK{PROLLSshared}) { - $linkvia = '$(PROLLSshared)'; - } - else { - $linkvia = '$(PROLDLIBS)'; - } + if (!$linkvia && $MK{PROLDLIBS}) { # Oracle 7.3.x + # XXX tweak for threaded perl? - use PROLLSsharedthread + if ($MK{PROLDLIBS} =~ /thread/i && $MK{PROLLSshared}) { + $linkvia = '$(PROLLSshared)'; + } + else { + $linkvia = '$(PROLDLIBS)'; + } } elsif (!$linkvia && int($mkver) == 1) { - if ($MK{LLIBOCIC}) { - $linkvia = '$(LLIBOCIC) $(TTLIBS)'; - } else { - print "WARNING: Guessing what to link with.\n"; - $linkvia = '-locic $(TTLIBS)'; # XXX GUESS HACK - } + if ($MK{LLIBOCIC}) { + $linkvia = '$(LLIBOCIC) $(TTLIBS)'; + } else { + print "WARNING: Guessing what to link with.\n"; + $linkvia = '-locic $(TTLIBS)'; # XXX GUESS HACK + } } - elsif (!$linkvia && $MK{CCLIB}) { # Oracle XE - $linkvia = '$(CCLIB)'; + elsif (!$linkvia && $MK{CCLIB}) { # Oracle XE + $linkvia = '$(CCLIB)'; } unless ($linkvia){ - die "ERROR parsing $file: Unable to determine what to link with.\n" - ."Please send me copies of these files (one per mail message):\n@mkfiles\n"; + die "ERROR parsing $file: Unable to determine what to link with.\n" + ."Please send me copies of these files (one per mail message):\n@mkfiles\n"; } $MK_TEXT = join("\n", @MK); return $linkvia; @@ -1418,23 +1420,23 @@ my $file = shift; my $fh; unless ($fh = new FileHandle "<$file") { - # Workaround more oracle bungling (Oracle 7.3.2/Solaris x86) - my $alt; ($alt = $file) =~ s/\.dk\.mk$/\.mk/; - $fh = new FileHandle "<$alt"; - die "Unable to read $file: $!" unless $fh; + # Workaround more oracle bungling (Oracle 7.3.2/Solaris x86) + my $alt; ($alt = $file) =~ s/\.dk\.mk$/\.mk/; + $fh = new FileHandle "<$alt"; + die "Unable to read $file: $!" unless $fh; } print "Reading $file\n"; my @lines; push(@mkfiles, $file); while(<$fh>) { - # soak up while looking for include directives - push(@lines, $_), next - unless /^\s*include\s+(.*?)\s*$/m; - my $inc_file = $1; - # deal with "include $(ORACLE_HOME)/..." - # (can't use expand_mkvars() here) - $inc_file =~ s/\$\((ORACLE_HOME|ORACLE_ROOT)\)/$ENV{$ORACLE_ENV}/og; - push(@lines, read_inc_file($inc_file)); + # soak up while looking for include directives + push(@lines, $_), next + unless /^\s*include\s+(.*?)\s*$/m; + my $inc_file = $1; + # deal with "include $(ORACLE_HOME)/..." + # (can't use expand_mkvars() here) + $inc_file =~ s/\$\((ORACLE_HOME|ORACLE_ROOT)\)/$ENV{$ORACLE_ENV}/og; + push(@lines, read_inc_file($inc_file)); } print "Read a total of ".@lines." lines from $file (including inclusions)\n" if $::opt_v; return @lines; @@ -1447,14 +1449,14 @@ my $cmd = $orig; my $debug = $::opt_d || $::opt_v; print "Evaluating `$orig`\n" - if $debug && !$expand_shellescape{$orig}; + if $debug && !$expand_shellescape{$orig}; # ensure we have no $(...) vars left - strip out undefined ones: $cmd =~ s/\$[({](\w+)[})]/mkvar("$1", 1, 0, $level+1)/ge; print " expanded `$cmd`\n" if $debug and $cmd ne $orig; my $result = `$cmd`; $result =~ s/\s+$/ /; # newlines etc to single space print " returned '$result'\n" - if $debug && !$expand_shellescape{$orig}; + if $debug && !$expand_shellescape{$orig}; $expand_shellescape{$orig} = $result; $result; } @@ -1462,22 +1464,22 @@ sub expand_mkvars { my ($string, $strip, $backtick, $level, $maxlevel) = @_; - return if(!defined $string); + return if(!defined $string); $level ||= 1; local($_) = $string; print "$level Expanding $_\n" if $::opt_d; # handle whizzo AIX make feature used by Oracle s/\$[({] (\w+) \? ([^(]*?) : ([^(]*?) [})]/ - my ($vname, $vT, $vF) = ($1,$2,$3); - $MK{$vname} = (mkvar($vname, 1, $backtick, $level+1)) ? $vT : $vF + my ($vname, $vT, $vF) = ($1,$2,$3); + $MK{$vname} = (mkvar($vname, 1, $backtick, $level+1)) ? $vT : $vF /xge; # can recurse s/\$[({] (\w+) [})]/ - mkvar("$1", $strip, $backtick, $level+1, $maxlevel) + mkvar("$1", $strip, $backtick, $level+1, $maxlevel) /xge; # can recurse s/`(.*?[^\\])`/expand_shellescape("$1", $level+1)/esg if $backtick; # can recurse - s/\s*\\\n\s*/ /g; # merge continuations - s/\s+/ /g; # shrink whitespace + s/\s*\\\n\s*/ /g; # merge continuations + s/\s+/ /g; # shrink whitespace print "$level Expanded $string\n to $_\n\n" if $::opt_d and $_ ne $string; $_; } @@ -1491,14 +1493,14 @@ return $ENV{$ORACLE_ENV} if $var eq 'ORACLE_HOME'; my $val = $MK{$var}; if (!defined $val and exists $ENV{$var}) { - $val = $ENV{$var}; - print "Using value of $var from environment: $val\n" - unless $var eq 'LD_LIBRARY_PATH'; + $val = $ENV{$var}; + print "Using value of $var from environment: $val\n" + unless $var eq 'LD_LIBRARY_PATH'; } return $default unless defined $val; if ($MK_expanding{$var}) { - print "Definition of \$($var) includes \$($var).\n"; - return "\$($var)"; + print "Definition of \$($var) includes \$($var).\n"; + return "\$($var)"; } local($MK_expanding{$var}) = 1; return $val if $maxlevel && $level >= $maxlevel; @@ -1509,8 +1511,8 @@ sub read_file { my $file = shift; unless (open(ROL, "<$file")) { - warn "WARNING: Unable to open $file: $!\n"; - return ""; + warn "WARNING: Unable to open $file: $!\n"; + return ""; } my $text = join "", <ROL>; $text =~ s/\n+/ /g; @@ -1540,20 +1542,21 @@ # compensate for case where final .0 isn't in the install directory name (my $client_version_trim = $client_version_full) =~ s/\.0$//; - my @try = grep { -d $_ } ( # search the ORACLE_HOME we're using first + my @try = grep { -d $_ } ( # search the ORACLE_HOME we're using first # --- Traditional full-install locations "$OH/rdbms/public", # prefer public over others "$OH/rdbms", "$OH/plsql", # oratypes.h sometimes here (eg HPUX 11.23 Itanium Oracle 9.2.0), # --- Oracle SDK Instant Client locations "$OH/sdk/include", + "$OH/include", # --- Oracle RPM Instant Client locations map { ( $_, $_."64" ) } map { ( $_, "/usr$_" ) } map { "/include/oracle/$_/client" } - $client_version, - $client_version_trim, - $client_version_full, + $client_version, + $client_version_trim, + $client_version_full, #"/include/oracle/$client_version_full/client", # Instant Client for RedHat FC3 #"/include/oracle/$client_version_trim/client", # Instant Client for RedHat FC3 @@ -1589,14 +1592,14 @@ print "Found header files in @h_dir.\n" if @h_dir; if (!$h_file{'oratypes.h'} || !$h_file{'ocidfn.h'}) { - print "\n\n*********************************************************\n"; - print "I can't find the header files I need in your Oracle installation.\n"; - print "You probably need to install some more Oracle components.\n"; - print "For Instant Client that means the SDK package.\n"; - print "I'll keep going, but the compile will probably fail.\n"; - print "See the appropriate troubleshooting guide for your OS for more information.$BELL\n"; - print "*********************************************************\n\n"; - sleep 5; + print "\n\n*********************************************************\n"; + print "I can't find the header files I need in your Oracle installation.\n"; + print "You probably need to install some more Oracle components.\n"; + print "For Instant Client that means the SDK package.\n"; + print "I'll keep going, but the compile will probably fail.\n"; + print "See the appropriate troubleshooting guide for your OS for more information.$BELL\n"; + print "*********************************************************\n\n"; + sleep 5; } return @h_dir; } @@ -1622,92 +1625,90 @@ print "PATH=$ENV{PATH}\n" if $::opt_v; if (find_bin($sqlplus_exe)) { - local $ENV{SQLPATH} = ""; # avoid $SQLPATH/login.sql causing sqlplus to hang - # Try to use the _SQLPLUS_RELEASE predefined variable from sqlplus - # Documented in the SQL*Plus reference guide: - # http://download-west.oracle.com/docs/cd/B12037_01/server.101/b12170/ch13.htm#i2675128 - # Output is in the following format: - # DEFINE _SQLPLUS_RELEASE = "902000400" (CHAR) Representing 9.2.0.4.0 - # DEFINE _SQLPLUS_RELEASE = "1001000200" (CHAR) Representing 10.1.0.2.0 - open FH, ">define.sql" or warn "Can't create define.sql: $!"; - print FH "DEFINE _SQLPLUS_RELEASE\nQUIT\n"; - close FH; - my $sqlplus_release = `$sqlplus_exe -S /nolog \@define.sql 2>&1`; - if ($sqlplus_release =~ /(SP2-0750)|(SP2-0642)/) { - - - my $x = $ENV{ORACLE_HOME}; - delete $ENV{ORACLE_HOME}; - $sqlplus_release = `$sqlplus_exe -S /nolog \@define.sql 2>&1`; - $ENV{ORACLE_HOME} = $x; - } - unlink "define.sql"; - print $sqlplus_release; # the _SQLPLUS_RELEASE may not be on first line: - if ($sqlplus_release =~ /DEFINE _SQLPLUS_RELEASE = "(\d?\d)(\d\d)(\d\d)(\d\d)(\d\d)"/) { - $client_version_full = sprintf("%d.%d.%d.%d", $1, $2, $3, $4); - } - else { - my $ldlib_note = ($Config{ldlibpthname}) - ? "Specifically, your $Config{ldlibpthname} environment variable" - : "Many systems need an environment variable (such as LD_LIBRARY_PATH, DYLD_LIBRARY_PATH)"; - warn qq{ - If sqlplus failed due to a linker/symbol/relocation/library error or similar problem - then it's likely that you've not configured your environment correctly. - $ldlib_note - set to include the directory containing the Oracle libraries. - \a\n}; - sleep 5; - } + local $ENV{SQLPATH} = ""; # avoid $SQLPATH/login.sql causing sqlplus to hang + # Try to use the _SQLPLUS_RELEASE predefined variable from sqlplus + # Documented in the SQL*Plus reference guide: + # http://download-west.oracle.com/docs/cd/B12037_01/server.101/b12170/ch13.htm#i2675128 + # Output is in the following format: + # DEFINE _SQLPLUS_RELEASE = "902000400" (CHAR) Representing 9.2.0.4.0 + # DEFINE _SQLPLUS_RELEASE = "1001000200" (CHAR) Representing 10.1.0.2.0 + open my $FH, '>', 'define.sql' or warn "Can't create define.sql: $!"; + print $FH "DEFINE _SQLPLUS_RELEASE\nQUIT\n"; + close $FH; + my $sqlplus_release = `$sqlplus_exe -S /nolog \@define.sql 2>&1`; + if ($sqlplus_release =~ m/(SP2-0750)|(SP2-0642)/) { + my $x = $ENV{ORACLE_HOME}; + delete $ENV{ORACLE_HOME}; + $sqlplus_release = `$sqlplus_exe -S /nolog \@define.sql 2>&1`; + $ENV{ORACLE_HOME} = $x; + } + unlink "define.sql"; + print $sqlplus_release; # the _SQLPLUS_RELEASE may not be on first line: + if ($sqlplus_release =~ /DEFINE _SQLPLUS_RELEASE = "(\d?\d)(\d\d)(\d\d)(\d\d)(\d\d)"/) { + $client_version_full = sprintf("%d.%d.%d.%d", $1, $2, $3, $4); + } + else { + my $ldlib_note = ($Config{ldlibpthname}) + ? "Specifically, your $Config{ldlibpthname} environment variable" + : "Many systems need an environment variable (such as LD_LIBRARY_PATH, DYLD_LIBRARY_PATH)"; + warn qq{ + If sqlplus failed due to a linker/symbol/relocation/library error or similar problem + then it's likely that you've not configured your environment correctly. + $ldlib_note + set to include the directory containing the Oracle libraries. + \a\n}; + sleep 5; + } } else { - warn "Can't find sqlplus. Pity, it would have helped.\n"; + warn "Can't find sqlplus. Pity, it would have helped.\n"; } if (!$client_version_full && $OH && open INST, "<$OH/install/unix.rgs") { - local $/ = undef; - <INST> =~ m/^(rdbms|sql\*plus)\s+([\d.]+)/m; - $client_version_full = $2 if $2; - close INST; + local $/ = undef; + <INST> =~ m/^(rdbms|sql\*plus)\s+([\d.]+)/m; + $client_version_full = $2 if $2; + close INST; } if (!$client_version_full && $OH && -x "$OH/orainst/inspdver" ) { - open INST, "$OH/orainst/inspdver |"; # client only install does not have this - my @inspdver = <INST>; - close INST; - foreach (@inspdver) { - $client_version_full = $1 if m/^(\d+\.\d+\.\d+)\S*\s+.*RDBMS/; - next unless $::opt_v - or m/RDBMS/i or m/PL.SQL/i - or m/Precomp/i or m/Pro\*C/i; - print $_; - } + open my $INST, "$OH/orainst/inspdver |"; # client only install does not have this + my @inspdver = <$INST>; + close $INST; + foreach (@inspdver) { + $client_version_full = $1 if m/^(\d+\.\d+\.\d+)\S*\s+.*RDBMS/; + next unless $::opt_v + or m/RDBMS/i or m/PL.SQL/i + or m/Precomp/i or m/Pro\*C/i; + print $_; + } } if (!$client_version_full) { - print "I'm having trouble finding your Oracle version number... trying harder\n" - unless $force_version; - if ( $OH =~ m\.\d+\.\d+(\.\d+)?)! ) { #decode it from $OH if possible - $client_version_full = $1; - } - elsif ( "$OH/" =~ m!\D(8|9|10)(\d)(\d?)\D!) { # scary but handy - $client_version_full = join ".", $1, $2, ($3||'0'); - } - elsif ( "$OH/" =~ m!/10g!) { # scary but handy - $client_version_full = "10.0.0.0"; - } + print "I'm having trouble finding your Oracle version number... trying harder\n" + unless $force_version; + if ( $OH =~ m\.\d+\.\d+(\.\d+)?)! ) { #decode it from $OH if possible + $client_version_full = $1; + } + elsif ( "$OH/" =~ m!\D(8|9|10)(\d)(\d?)\D!) { # scary but handy + $client_version_full = join ".", $1, $2, ($3||'0'); + } + elsif ( "$OH/" =~ m!/10g!) { # scary but handy + $client_version_full = "10.0.0.0"; + } elsif ( "$OH/" =~ m!/usr/lib/oracle/(\d+\.\d)/!) { # Linux RPM $client_version_full = "$1.0.0"; } } if ($force_version && $force_version ne $client_version_full) { - print "Forcing Oracle version to be treated as $force_version\n"; - $client_version_full = $force_version; + print "Forcing Oracle version to be treated as $force_version\n"; + $client_version_full = $force_version; } - if ($client_version_full && $client_version_full !~ m/^(7|8|9|1\d)\.\d+/ + if ($client_version_full && $client_version_full !~ m/^([789]|[12][0-9])\.[0-9]+/ ) { - print "Oracle version seems to be $client_version_full but that looks wrong so I'll ignore it.\n"; - $client_version_full = ""; + print "Oracle version seems to be $client_version_full but that looks wrong so I'll ignore it.\n"; + $client_version_full = ""; } if (!$client_version_full) { @@ -1740,16 +1741,16 @@ $::opt_s ||= $::opt_S; print "Searching for symbol '$::opt_s' in $OH ...\n"; my $dlext = $Config{dlext}; - system(qq{ cd $OH; for i in lib/*.[ao] lib/*.$dlext */lib/*.[ao]; - do echo " searching oracle \$i ..."; PATH=/usr/ccs/bin:\$PATH nm \$i | grep $::opt_s; done + system(qq{ cd $OH; for i in lib/*.[ao] lib/*.$dlext */lib/*.[ao]; + do echo " searching oracle \$i ..."; PATH=/usr/ccs/bin:\$PATH nm \$i | grep $::opt_s; done }); if ($::opt_S) { - my @libpth = split ' ', $Config{libpth}; - print "Searching for symbol '$::opt_s' in @libpth ...\n"; - @libpth = map { ("$_/lib*.$dlext", "$_/lib*.a") } @libpth; - system(qq{ cd $OH; for i in @libpth; - do echo " searching \$i ..."; PATH=/usr/ccs/bin:\$PATH nm \$i | grep $::opt_s; done - }); + my @libpth = split ' ', $Config{libpth}; + print "Searching for symbol '$::opt_s' in @libpth ...\n"; + @libpth = map { ("$_/lib*.$dlext", "$_/lib*.a") } @libpth; + system(qq{ cd $OH; for i in @libpth; + do echo " searching \$i ..."; PATH=/usr/ccs/bin:\$PATH nm \$i | grep $::opt_s; done + }); } print "Search done.\n"; print "(Please only include the 'interesting' parts when mailing.)\n"; @@ -1774,75 +1775,75 @@ sub post_initialize { - my $self = shift; + my $self = shift; - print "\nNote: \$ORACLE_HOME/lib must be added to your $need_ldlp_env environment variable\n", - "before running \"make test\" and whenever DBD::Oracle is used.\n\n" - if $need_ldlp_env && ($ENV{$need_ldlp_env}||'') !~ m:\Q$OH/lib\b:; - - eval { # This chunk is for Oracle::OCI - require Data::Dumper; - print main::MK_PM Data::Dumper->Purity(1)->Terse(0)->Indent(1)->Useqq(1) - ->Dump([\%opts, $self], [qw(dbd_oracle_mm_opts dbd_oracle_mm_self)]); - }; - if ($@) { - warn "Can't dump config to mk.pm so you won't be able to build Oracle::OCI later if you wanted to: $@\n"; - print main::MK_PM qq{die "You need to reinstall DBD::Oracle after installing Data::Dumper\n"; }; - } - close main::MK_PM or die "Error closing mk.pm: $!\n"; - - foreach (qw(mk.pm Oracle.h dbdimp.h ocitrace.h)) { - $self->{PM}->{$_} = '$(INST_ARCHAUTODIR)/'.$_; - } - - # Add $linkwith to EXTRALIBS for those doing static linking - $self->{EXTRALIBS} .= " -L\$(LIBHOME)"; - $self->{EXTRALIBS} .= " $linkwith" if $linkwith; + print "\nNote: \$ORACLE_HOME/lib must be added to your $need_ldlp_env environment variable\n", + "before running \"make test\" and whenever DBD::Oracle is used.\n\n" + if $need_ldlp_env && ($ENV{$need_ldlp_env}||'') !~ m:\Q$OH/lib\b:; + + eval { # This chunk is for Oracle::OCI + require Data::Dumper; + print main::MK_PM Data::Dumper->Purity(1)->Terse(0)->Indent(1)->Useqq(1) + ->Dump([\%opts, $self], [qw(dbd_oracle_mm_opts dbd_oracle_mm_self)]); + }; + if ($@) { + warn "Can't dump config to mk.pm so you won't be able to build Oracle::OCI later if you wanted to: $@\n"; + print main::MK_PM qq{die "You need to reinstall DBD::Oracle after installing Data::Dumper\n"; }; + } + close main::MK_PM or die "Error closing mk.pm: $!\n"; + + foreach (qw(mk.pm Oracle.h dbdimp.h ocitrace.h)) { + $self->{PM}->{$_} = '$(INST_ARCHAUTODIR)/'.$_; + } - ''; + # Add $linkwith to EXTRALIBS for those doing static linking + $self->{EXTRALIBS} .= " -L\$(LIBHOME)"; + $self->{EXTRALIBS} .= " $linkwith" if $linkwith; + + ''; } sub postamble { - return main::dbd_postamble(@_); + return main::dbd_postamble(@_); } sub const_loadlibs { - my $self = shift; + my $self = shift; - # ExtUtils::MM_Unix v1.50 (invoked by ExtUtils::MakeMaker) - # requires that $self->{LD_RUN_PATH} be defined and not be - # an empty string for Makefile to specify its use during the - # build. This is required by both SUPER::const_loadlibs - # and SUPER::dynamic_lib. hence it is best if we define - # or modify $self->{LD_RUN_PATH} here *before* calling - # SUPER::const_loadlibs. + # ExtUtils::MM_Unix v1.50 (invoked by ExtUtils::MakeMaker) + # requires that $self->{LD_RUN_PATH} be defined and not be + # an empty string for Makefile to specify its use during the + # build. This is required by both SUPER::const_loadlibs + # and SUPER::dynamic_lib. hence it is best if we define + # or modify $self->{LD_RUN_PATH} here *before* calling + # SUPER::const_loadlibs. - # edit LD_RUN_PATH ... - my ($ldrp) = $self->{LD_RUN_PATH}; - # remove redundant /lib or /usr/lib as it can cause problems - $ldrp =~ s!:(/usr)?/lib$!! if $ldrp; + # edit LD_RUN_PATH ... + my ($ldrp) = $self->{LD_RUN_PATH}; + # remove redundant /lib or /usr/lib as it can cause problems + $ldrp =~ s!:(/usr)?/lib$!! if $ldrp; # if it's empty then set it manually #Lincoln: if pick the right library path my $libdir = main::ora_libdir(); $ldrp ||= "$OH/$libdir:$OH/rdbms/$libdir"; - $self->{LD_RUN_PATH} = $ldrp; + $self->{LD_RUN_PATH} = $ldrp; - local($_) = $self->SUPER::const_loadlibs(@_); + local($_) = $self->SUPER::const_loadlibs(@_); - print "Ignoring LD_RUN_PATH='$ENV{LD_RUN_PATH}' in environment\n" if $ENV{LD_RUN_PATH}; - print "LD_RUN_PATH=$ldrp\n"; - return $_; + print "Ignoring LD_RUN_PATH='$ENV{LD_RUN_PATH}' in environment\n" if $ENV{LD_RUN_PATH}; + print "LD_RUN_PATH=$ldrp\n"; + return $_; } sub post_constants { - my $self = shift; - return '' unless $::opt_f; - # Oracle Definitions, based on $(ORACLE_HOME)/proc/lib/proc.mk - ' + my $self = shift; + return '' unless $::opt_f; + # Oracle Definitions, based on $(ORACLE_HOME)/proc/lib/proc.mk + ' ################################################################### # ORACLE_HOME = '.$OH.' @@ -1859,96 +1860,96 @@ sub const_cccmd { - my ($self) = shift; - print "Using DBD::Oracle $self->{VERSION}.\n"; + my ($self) = shift; + print "Using DBD::Oracle $self->{VERSION}.\n"; - local($_) = $self->SUPER::const_cccmd(@_); - # If perl Makefile.PL *-g* then switch on debugging - if ($::opt_g) { - if ($^O eq "MSWin32" and $Config::Config{cc} eq 'cl') { - s/\s-/ -Zi -/; - s/-O1//; - } else { - s/\s-O\d?\b//; # delete optimise option - s/\s-/ -g -/; # add -g option - } - } - # are we using the non-bundled hpux compiler? - if ($^O eq "hpux" and $Config::Config{ccflags} =~ /-Aa\b/) { - print "Changing -Aa to -Ae for HP-UX in ccmd.\n" - if s/-Aa\b/-Ae/g; # allow "long long" in oratypes.h - } + local($_) = $self->SUPER::const_cccmd(@_); + # If perl Makefile.PL *-g* then switch on debugging + if ($::opt_g) { + if ($^O eq "MSWin32" and $Config::Config{cc} eq 'cl') { + s/\s-/ -Zi -/; + s/-O1//; + } else { + s/\s-O\d?\b//; # delete optimise option + s/\s-/ -g -/; # add -g option + } + } + # are we using the non-bundled hpux compiler? + if ($^O eq "hpux" and $Config::Config{ccflags} =~ /-Aa\b/) { + print "Changing -Aa to -Ae for HP-UX in ccmd.\n" + if s/-Aa\b/-Ae/g; # allow "long long" in oratypes.h + } - $_; + $_; } sub cflags { - my ($self) = shift; - local($_) = $self->SUPER::cflags(@_); - # If perl Makefile.PL *-g* then switch on debugging - if ($::opt_g) { - if ($^O eq "MSWin32" and $Config::Config{cc} eq 'cl') { - s/\s-/ -Zi -/; - s/-O1//; - - } else { - s/\s-O\d?\b//; # delete optimise option - s/\s-/ -g -/; # add -g option - } - } - # are we using the non-bundled hpux compiler? - if ($^O eq "hpux" and $Config::Config{ccflags} =~ /-Aa\b/) { - print "Changing -Aa to -Ae for HP-UX in cflags.\n" - if s/-Aa\b/-Ae/g; # allow "long long" in oratypes.h - } - $_; + my ($self) = shift; + local($_) = $self->SUPER::cflags(@_); + # If perl Makefile.PL *-g* then switch on debugging + if ($::opt_g) { + if ($^O eq "MSWin32" and $Config::Config{cc} eq 'cl') { + s/\s-/ -Zi -/; + s/-O1//; + + } else { + s/\s-O\d?\b//; # delete optimise option + s/\s-/ -g -/; # add -g option + } + } + # are we using the non-bundled hpux compiler? + if ($^O eq "hpux" and $Config::Config{ccflags} =~ /-Aa\b/) { + print "Changing -Aa to -Ae for HP-UX in cflags.\n" + if s/-Aa\b/-Ae/g; # allow "long long" in oratypes.h + } + $_; } sub dynamic_lib { - my($self) = shift; + my($self) = shift; + + unless ($^O eq 'VMS') { + my $m = $self->SUPER::dynamic_lib(@_); + if ($^O eq 'darwin') { + $m = "NMEDIT = nmedit\n" . $m . + "\t\$(NMEDIT) -R ./hints/macos_bundle.syms \$(INST_DYNAMIC) || true\n"; + } + elsif (($^O eq 'hpux') and ($osvers <11)) { + $m =~ s/LD_RUN_PATH=(\S+)\s+(\S+)/$2 -Wl,+b $1/; + + } + return ($m); + } - unless ($^O eq 'VMS') { - my $m = $self->SUPER::dynamic_lib(@_); - if ($^O eq 'darwin') { - $m = "NMEDIT = nmedit\n" . $m . - "\t\$(NMEDIT) -R ./hints/macos_bundle.syms \$(INST_DYNAMIC) || true\n"; - } - elsif (($^O eq 'hpux') and ($osvers <11)) { - $m =~ s/LD_RUN_PATH=(\S+)\s+(\S+)/$2 -Wl,+b $1/; - - } - return ($m); - } - - # special code for VMS only - my(%attribs) = @_; - return '' unless $self->needs_linking(); #might be because of a subdir - return '' unless $self->has_link_code(); - - my $OtherText; - my($otherldflags) = $attribs{OTHERLDFLAGS} || ""; - my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || ""; - my @m; - push @m, "OTHERLDFLAGS = $otherldflags\n"; - push @m, "INST_DYNAMIC_DEP = $inst_dynamic_dep\n"; + # special code for VMS only + my(%attribs) = @_; + return '' unless $self->needs_linking(); #might be because of a subdir + return '' unless $self->has_link_code(); + + my $OtherText; + my($otherldflags) = $attribs{OTHERLDFLAGS} || ""; + my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || ""; + my @m; + push @m, "OTHERLDFLAGS = $otherldflags\n"; + push @m, "INST_DYNAMIC_DEP = $inst_dynamic_dep\n"; if ($] < 5.00450) { - push @m, ' + push @m, ' $(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt rtls.opt $(INST_ARCHAUTODIR).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP) - $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR) - $(NOECHO) If F$TrnLNm("PerlShr").eqs."" Then Define/NoLog/User PerlShr Sys$Share:PerlShr.',$Config::Config{'dlext'},' - Lnproc $(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,rtls.opt/Option,$(PERL_INC)perlshr_attr.opt/Option i + $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR) + $(NOECHO) If F$TrnLNm("PerlShr").eqs."" Then Define/NoLog/User PerlShr Sys$Share:PerlShr.',$Config::Config{'dlext'},' + Lnproc $(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,rtls.opt/Option,$(PERL_INC)perlshr_attr.opt/Option i '; } else { - push @m, ' + push @m, ' $(INST_DYNAMIC) : $(INST_STATIC) $(PERL_INC)perlshr_attr.opt $(INST_ARCHAUTODIR).exists $(EXPORT_LIST) $(PERL_ARCHIVE) $(INST_DYNAMIC_DEP) - $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR) - $(NOECHO) If F$TrnLNm("PerlShr").eqs."" Then Define/NoLog/User PerlShr Sys$Share:PerlShr.',$Config::Config{'dlext'},' - Lnproc $(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,$(PERL_INC)perlshr_attr.opt/Option i + $(NOECHO) $(MKPATH) $(INST_ARCHAUTODIR) + $(NOECHO) If F$TrnLNm("PerlShr").eqs."" Then Define/NoLog/User PerlShr Sys$Share:PerlShr.',$Config::Config{'dlext'},' + Lnproc $(MMS$TARGET)$(OTHERLDFLAGS) $(BASEEXT).opt/Option,$(PERL_INC)perlshr_attr.opt/Option i '; } - push @m, $self->dir_target('$(INST_ARCHAUTODIR)'); - join('',@m); + push @m, $self->dir_target('$(INST_ARCHAUTODIR)'); + join('',@m); } } @@ -2014,18 +2015,17 @@ # SUID and SGID, and warn if either is set my @files = map { ($_,$_.'0') } qw( - oratclsh lsnrctl oemevent onrsd osslogin tnslsnr - tnsping trcasst trcroute cmctl cmadmin cmgw names namesctl otrccref - otrcfmt otrcrep otrccol + oratclsh lsnrctl oemevent onrsd osslogin tnslsnr + tnsping trcasst trcroute cmctl cmadmin cmgw names namesctl otrccref + otrcfmt otrcrep otrccol ); my @bad; - foreach (@files) { - my $file = "$ENV{ORACLE_HOME}/bin/$_"; - my ($mode) = (stat($file))[2]; - next unless defined $mode; - push @bad, $file if ($mode & 04000 and $mode & 00111) - or ($mode & 02000 and $mode & 00111); + for my $file (map { "$ENV{ORACLE_HOME}/bin/$_" } @files) { + my ($mode) = (stat($file))[2]; + next unless defined $mode; + push @bad, $file if ($mode & 04000 and $mode & 00111) + or ($mode & 02000 and $mode & 00111); } return unless @bad; @@ -2049,7 +2049,7 @@ return if /^\s+U _(dlsym|dlclose)/; } - warn <<"END_WARNING"; + warn <<"END_WARNING"; WARNING: symbol table may need modification in Oracle library: $oracle_lib If the build fails in the linking stage, manual modification is diff -Nru libdbd-oracle-perl-1.80/Oracle.xs libdbd-oracle-perl-1.83/Oracle.xs --- libdbd-oracle-perl-1.80/Oracle.xs 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/Oracle.xs 2022-01-17 02:06:35.000000000 +0000 @@ -114,9 +114,13 @@ #endif /* __CYGWIN32__ */ - INCLUDE: Oracle.xsi + + +# ------------------------------------------------------------ +# statement interface +# ------------------------------------------------------------ MODULE = DBD::Oracle PACKAGE = DBD::Oracle::st @@ -281,7 +285,9 @@ - +# ------------------------------------------------------------ +# database level interface +# ------------------------------------------------------------ MODULE = DBD::Oracle PACKAGE = DBD::Oracle::db void @@ -702,6 +708,10 @@ } + +# ------------------------------------------------------------ +# driver level interface +# ------------------------------------------------------------ MODULE = DBD::Oracle PACKAGE = DBD::Oracle::dr void diff -Nru libdbd-oracle-perl-1.80/README libdbd-oracle-perl-1.83/README --- libdbd-oracle-perl-1.80/README 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/README 2022-01-17 02:06:35.000000000 +0000 @@ -1,7 +1,7 @@ DBD::Oracle -- an Oracle interface for Perl 5. - Copyright (c) 1994-2006 Tim Bunce, Ireland. + Copyright (c) 1994-2020 Tim Bunce, et. al. See the COPYRIGHT section in the Oracle.pm file for terms. See also the MAINTAINER section in the Oracle.pm @@ -114,9 +114,9 @@ this user has sufficient privileges to create, insert into, select from and drop a table, is also able to create, call and drop a procedure and is able to select from systemtables like 'v$sessions'. Using 'system/manager' might -work but is not recommended! See also +work but is not recommended! See also README.login.txt and TESTING.md. -README.login.txt. +Run tests with: make test @@ -267,30 +267,6 @@ DBI 'home page': http://dbi.perl.org -Old archive site for Perl DB information: - ftp://ftp.demon.co.uk/pub/perl/db/ -Mailing list archive: /DBI/perldb-interest/ -Perl 4 Oraperl (v2.4) /perl4/oraperl/ - -Jeff Stander's stuff stands out for Oraperl: -Directories of interest might be - /pub/Oracle/sources - /pub/Oracle/sources/jstander - /pub/Oracle/sources/jstander/distrib - /pub/Oracle/sources/jstander/tsmlib - /pub/Oracle/sources/jstander/wdbex - /pub/Oracle/sources/web/scripts - /pub/Oracle/sources/dba - /pub/Oracle/sources/dba/imp2sql7 - /pub/Oracle/sources/Lonnroth - /pub/Oracle/sources/harrison - -http://www.bf.rmit.edu.au/~orafaq/perlish.html -ftp://ftp.bf.rmit.edu.au/pub/perl/db -ftp://ftp.bf.rmit.edu.au/pub/Oracle -ftp://ftp.bf.rmit.edu.au/pub/Oracle/sources -ftp://ftp.bf.rmit.edu.au/pub/Oracle/OS/MS/NT/ntoraperl.zip - DBI and DBD::Oracle are very portable. If Perl and Oracle run on a platform then the chances are that DBD::Oracle will as well. diff -Nru libdbd-oracle-perl-1.80/README.mkdn libdbd-oracle-perl-1.83/README.mkdn --- libdbd-oracle-perl-1.80/README.mkdn 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/README.mkdn 1970-01-01 00:00:00.000000000 +0000 @@ -1,4259 +0,0 @@ -# NAME - -DBD::Oracle - Oracle database driver for the DBI module - -# VERSION - -version 1.80 - -# SYNOPSIS - - use DBI; - - $dbh = DBI->connect("dbi:Oracle:$dbname", $user, $passwd); - - $dbh = DBI->connect("dbi:Oracle:host=$host;sid=$sid", $user, $passwd); - - # See the DBI module documentation for full details - - # for some advanced uses you may need Oracle type values: - use DBD::Oracle qw(:ora_types); - -# DESCRIPTION - -DBD::Oracle is a Perl module which works with the DBI module to provide -access to Oracle databases. - -This documentation describes driver specific behaviour and restrictions. It is -not supposed to be used as the only reference for the user. In any case -consult the [DBI](https://metacpan.org/pod/DBI) documentation first! - -# CONSTANTS - -- :ora\_session\_modes - - ORA\_SYSDBA ORA\_SYSOPER ORA\_SYSASM ORA\_SYSBACKUP ORA\_SYSDG ORA\_SYSKM - -- :ora\_types - - 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 - -- SQLCS\_IMPLICIT -- SQLCS\_NCHAR - - SQLCS\_IMPLICIT and SQLCS\_NCHAR are _character set form_ values. - See notes about Unicode elsewhere in this document. - -- SQLT\_INT -- SQLT\_FLT - - These types are used only internally, and may be specified as internal - bind type for ORA\_NUMBER\_TABLE. See notes about ORA\_NUMBER\_TABLE elsewhere - in this document - -- ORA\_OCI - - Oracle doesn't provide a formal API for determining the exact version - number of the OCI client library used, so DBD::Oracle has to go digging - (and sometimes has to more or less guess). The ORA\_OCI constant - holds the result of that process. - - In string context ORA\_OCI returns the full "A.B.C.D" version string. - - In numeric context ORA\_OCI returns the major.minor version number - (8.1, 9.2, 10.0 etc). But note that version numbers are not actually - floating point and so if Oracle ever makes a release that has a two - digit minor version, such as `9.10` it will have a lower numeric - value than the preceding `9.9` release. So use with care. - - The contents and format of ORA\_OCI are subject to change (it may, - for example, become a _version object_ in later releases). - I recommend that you avoid checking for exact values. - -- :ora\_fetch\_orient - - OCI_FETCH_CURRENT OCI_FETCH_NEXT OCI_FETCH_FIRST OCI_FETCH_LAST - OCI_FETCH_PRIOR OCI_FETCH_ABSOLUTE OCI_FETCH_RELATIVE - - These constants are used to set the orientation of a fetch on a scrollable cursor. - -- :ora\_exe\_modes - - OCI_STMT_SCROLLABLE_READONLY - -- :ora\_fail\_over - - OCI_FO_END OCI_FO_ABORT OCI_FO_REAUTH OCI_FO_BEGIN OCI_FO_ERROR - OCI_FO_NONE OCI_FO_SESSION OCI_FO_SELECT OCI_FO_TXNAL OCI_FO_RETRY - -# DBI CLASS METHODS - -## **connect** - -This method creates a database handle by connecting to a database, and is the DBI equivalent of the "new" method. -To open a connection to an Oracle database you need to specify a database connection string (URL), username and password. - -The connection string is always of the form: "dbi:Oracle:<db identifier>" -There are several ways to identify a database: - -1. If the database is local, specifying the SID or service name will be enough. -2. If the database is defined in a TNSNAMES.ORA file, you can use the service name given in the file -3. To connect without TNSNAMES.ORA file, you can use an EZCONNECT url, of the form: -//host\[:port\]\[/service\_name\] - -If port name is not specified, 1521 is the default. If service name is not specified, the hostname will be used as a service name. - -The following examples show several ways a connection can be created: - - $dbh = DBI->connect('dbi:Oracle:DB','username','password'); - - $dbh = DBI->connect('dbi:Oracle:DB','username/password',''); - - $dbh = DBI->connect('dbi:Oracle:','username@DB','password'); - - $dbh = DBI->connect('dbi:Oracle:host=foobar;sid=DB;port=1521', 'scott/tiger', ''); - - $dbh = DBI->connect("dbi:Oracle://myhost:1522/ORCL",'username', 'password'); - -### OS authentication - -To connect to a local database with a user which has been set up to -authenticate via the OS ("ALTER USER username IDENTIFIED EXTERNALLY"): - - $dbh = DBI->connect('dbi:Oracle:','/',''); - -Note the lack of a connection name (use the ORACLE\_SID environment -variable). If an explicit SID is used you will probably get an ORA-01004 error. - -That only works for local databases. (Authentication to remote Oracle -databases using your Unix login name without a password is possible -but it is not secure and not recommended so not documented here. - -### Oracle Environment Variables - -To use DBD::ORACLE to connect to an Oracle database, ORACLE\_HOME environment variable should be set correctly. -In general, the value used should match the version of Oracle that was used to build DBD::Oracle. If using dynamic linking then ORACLE\_HOME should match the version of Oracle that will be used to load in the Oracle client libraries (via LD\_LIBRARY\_PATH, ldconfig, or similar on Unix). - -Oracle can use two environment variables to specify default connections: ORACLE\_SID and TWO\_TASK. - -To use them, specify either a local SID or service name, or a service name that is specified in the TNSNAMES.ORA file. - -Note that if you have \*both\* local and remote databases, and you have ORACLE\_SID \*and\* TWO\_TASK set, and you don't specify a fully -qualified connect string on the command line, TWO\_TASK takes precedence over ORACLE\_SID (i.e. you get connected to remote system). - -It is highly recommended not to rely on environment variables and to always explicitly specify the SID in the connection string. This can prevent serious mistakes such as dropping a schema in the wrong database, and generally makes debugging and troubleshooting easier. - -Also remember that depending on the operating system you are using the differing "ORACLE" environment variables may be case sensitive, so if you are not connecting as you should double check the case of both the variable and its value. - -### Timezones - -If the query is run through SQL\*Net (mostly queries that are executed on remote servers), Oracle will return the time zone based on the setting of the UNIX environment variable "TZ" for the user who started the listener. - -If the query is run locally, Oracle will return the time zone based on the "TZ" environment variable setting of the user running -the query. - -With local queries, you can change the time zone for a particular user by simply changing the setting of "TZ". To check the current setting, -issue the UNIX "date" command. - -### Oracle DRCP - -DBD::Oracle supports DRCP (Database Resident Connection Pool) so -if you have an 11.2 database and DRCP is enabled you can direct -all of your connections to it by adding ':POOLED' to the SID or -setting a connection attribute of ora\_drcp, or set the SERVER=POOLED -when using a TNSENTRY style connection or even by setting an -environment variable ORA\_DRCP. All of which are demonstrated below; - - $dbh = DBI->connect('dbi:Oracle:DB:POOLED','username','password') - - $dbh = DBI->connect('dbi:Oracle:','username@DB:POOLED','password') - - $dbh = DBI->connect('dbi:Oracle:DB','username','password',{ora_drcp=>1}) - - $dbh = DBI->connect('dbi:Oracle:DB','username','password',{ora_drcp=>1, - ora_drcp_class=>'my_app', - ora_drcp_min =>10}) - - $dbh = DBI->connect('dbi:Oracle:host=foobar;sid=ORCL;port=1521;SERVER=POOLED', 'scott/tiger', '') - - $dbh = DBI->connect('dbi:Oracle:', q{scott/tiger@(DESCRIPTION= - (ADDRESS=(PROTOCOL=TCP)(HOST= foobar)(PORT=1521)) - (CONNECT_DATA=(SID=ORCL)(SERVER=POOLED)))}, "") - - if the ORA_DRCP environment variable is set then just this - - $dbh = DBI->connect('dbi:Oracle:DB','username','password') - -You can find a white paper on setting up DRCP and its advantages at [http://www.oracle.com/technetwork/articles/oracledrcp11g-1-133381.pdf](http://www.oracle.com/technetwork/articles/oracledrcp11g-1-133381.pdf). - -Please note that DRCP support in DBD::Oracle is relatively new so the -mechanics or its implementation are subject to change. - -### TAF (Transparent Application Failover) - -Transparent Application Failover (TAF) is the feature in OCI that -allows for clients to automatically reconnect to an instance in the -event of a failure of the instance. The reconnect happens -automatically from within the OCI (Oracle Call Interface) library. -DBD::Oracle now supports a callback function that will fire when a TAF -event takes place. You may use the callback to inform the -user a failover is taking place or to setup the session again -once the failover has succeeded. - -You will have to set up TAF on your instance before you can use this -callback. You can test your instance to see if you can use TAF -callback with - - $dbh->ora_can_taf(); - -If you try to set up a callback without it being enabled DBD::Oracle -will croak. - -NOTE: Currently, you must enable TAF during DBI's connect. However -once enabled you can change the TAF settings. - -It is outside the scope of this document to go through all of the -possible TAF situations you might want to set up but here is a simple -example: - -The TNS entry for the instance has had the following added to the -CONNECT\_DATA section - - (FAILOVER_MODE= - (TYPE=select) - (METHOD=basic) - (RETRIES=10) - (DELAY=10)) - -You will also have to create your own perl function that will be -called from the client. You can name it anything you want and it will -always be passed two parameters, the failover event value and the -failover type. You can also set a sleep value in case of failover -error and the OCI client will sleep for the specified seconds before it -attempts another event. - - use DBD::Oracle(qw(:ora_fail_over)); - #import the ora fail over constants - - #set up TAF on the connection - # NOTE since DBD::Oracle uses call_pv you may need to pass a full - # name space as the function e.g., 'main::handle_taf' - # NOTE from 1.49_00 ora_taf_function can accept a code ref as well - # as a sub name as it now uses call_sv - my $dbh = DBI->connect('dbi:Oracle:XE', 'hr', 'hr', - {ora_taf_function => 'main::handle_taf'}); - - #create the perl TAF event function - - sub handle_taf { - # NOTE from 1.49_00 the $dbh handle was passed to your callback - my ($fo_event,$fo_type, $dbh) = @_; - if ($fo_event == OCI_FO_BEGIN){ - - print " Instance Unavailable Please stand by!! \n"; - printf(" Your TAF type is %s \n", - (($fo_type==OCI_FO_NONE) ? "NONE" - :($fo_type==OCI_FO_SESSION) ? "SESSION" - :($fo_type==OCI_FO_SELECT) ? "SELECT" - : "UNKNOWN!")); - } - elsif ($fo_event == OCI_FO_ABORT){ - print " Failover aborted. Failover will not take place.\n"; - } - elsif ($fo_event == OCI_FO_END){ - printf(" Failover ended ...Resuming your %s\n",(($fo_type==OCI_FO_NONE) ? "NONE" - :($fo_type==OCI_FO_SESSION) ? "SESSION" - :($fo_type==OCI_FO_SELECT) ? "SELECT" - : "UNKNOWN!")); - } - elsif ($fo_event == OCI_FO_REAUTH){ - print " Failed over user. Resuming services\n"; - } - elsif ($fo_event == OCI_FO_ERROR){ - print " Failover error ...\n"; - sleep 5; # sleep before having another go - return OCI_FO_RETRY; - } - else { - printf(" Bad Failover Event: %d.\n", $fo_event); - - } - return 0; - } - -The TAF types are as follows - - OCI_FO_SESSION indicates the user has requested only session failover. - OCI_FO_SELECT indicates the user has requested select failover. - OCI_FO_NONE indicates the user has not requested a failover type. - OCI_FO_TXNAL indicates the user has requested a transaction failover. - -The TAF events are as follows - - OCI_FO_BEGIN indicates that failover has detected a lost connection and failover is starting. - OCI_FO_END indicates successful completion of failover. - OCI_FO_ABORT indicates that failover was unsuccessful, and there is no option of retrying. - OCI_FO_ERROR also indicates that failover was unsuccessful, but it gives the application the opportunity to handle the error and retry failover. - OCI_FO_REAUTH indicates that you have multiple authentication handles and failover has occurred after the original authentication. It indicates that a user handle has been re-authenticated. To find out which, the application checks the OCI_ATTR_SESSION attribute of the service context handle (which is the first parameter). - -### Connect Attributes - -#### ora\_ncs\_buff\_mtpl - -You can customize the size of the buffer when selecting LOBs with -the built-in AUTO Lob. The default value is 4 which is probably -excessive for most situations but is needed for backward -compatibility. If you not converting between a NCS on the DB and the -Client then you might want to set this to 1 to reduce memory usage. - -This value can also be specified with the `ORA_DBD_NCS_BUFFER` -environment variable in which case it sets the value at the connect -stage. - -#### ora\_drcp - -For Oracle 11.2 or greater. - -Set to _1_ to enable DRCP. Can also be set via the `ORA_DRCP` environment variable. - -#### ora\_drcp\_class - -If you are using DRCP, you can set a CONNECTION\_CLASS for your pools -as well. As sessions from a DRCP cannot be shared by users, you can -use this setting to identify the same user across different -applications. OCI will ensure that sessions belonging to a 'class' are -not shared outside the class'. - -The values for ora\_drcp\_class cannot contain a '\*' and must be less -than 1024 characters. - -This value can be also be specified with the `ORA_DRCP_CLASS` -environment variable. - -Note that a connection class must be specified in order to enable -inter-process sharing of server side sessions. - -#### ora\_drcp\_min - -This optional value specifies the minimum number of sessions that are -initially allocated for the application process. New sessions are only -allocated after this value has been reached. - -The default value is 0 and any value greater than or equal to 0 is valid. - -For multi-process applications, it is recommended to leave the value at 0. -This ensures that each process is only occupying a server session while -the process is doing database work. - -For multi-threaded applications, the value could be set to the number of -concurrent statements the application is planning or expecting to run. -Please note that DRCP has not been tested with multi-threading. - -This value can also be specified with the `ORA_DRCP_MIN` environment -variable. - -#### ora\_drcp\_max - -This optional value specifies the maximum number of sessions that can -be open at one time. Once reached no more sessions can be opened -until one becomes free. The default value is 40 and any value above 0 -is valid. You should not set this value lower than ora\_drcp\_min as -that will just waste resources. - -This value can also be specified with the `ORA_DRCP_MAX` environment -variable. - -#### ora\_drcp\_incr - -This optional value specifies the next increment for sessions to be -started if the current number of sessions are less than -ora\_drcp\_max. The default value is 1 and any value above 0 is -valid as long as the value of ora\_drcp\_min + ora\_drcp\_incr is not -greater than ora\_drcp\_max. - -This value can also be specified with the `ORA_DRCP_INCR` environment -variable. - -#### ora\_drcp\_rlb - -This optional value controls whether run-time connection load balancing -is used for Oracle RAC. The default value is 0, which disables the feature. -Set the value to 1 to enable the feature. - -This value can also be specified with the `ORA_DRCP_RLB` environment -variable. - -#### ora\_taf - -This attribute was removed in 1.49\_00 as it was redundant. To -enable TAF simply set ["ora\_taf\_function"](#ora_taf_function). - -#### ora\_taf\_function - -If your Oracle instance has been configured to use TAF events you can -enable the TAF callback by setting this option. - -The name of the Perl subroutine (or a code ref from 1.49\_00) that will -be called from OCI when a TAF event occurs. You must supply a perl -function to use the callback and it will always receive at least two -parameters; the failover event value and the failover type. From -1.49\_00 the dbh is passed as the third argument. Below is an example -of a TAF function - - sub taf_event{ - # NOTE from 1.49_00 the $dbh handle is passed to the callback - my ($event, $type, $dbh) = @_; - - print "My TAF event=$event\n"; - print "My TAF type=$type\n"; - return; - } - -Note if passing a sub name you will probably have to use the full name -space when setting the TAF function e.g., 'main::my\_taf\_function' and -not just 'my\_taf\_function'. - -#### ora\_taf\_sleep - -This attribute was removed in 1.49\_00 as it was redundant. If you want -to sleep between retries simple add a sleep to your callback sub. - -#### ora\_session\_mode - -The ora\_session\_mode attribute can be used to connect with SYSDBA, -SYSOPER, ORA\_SYSASM, ORA\_SYSBACKUP, ORA\_SYSKM and ORA\_SYSDG authorization. -The ORA\_SYSDBA, ORA\_SYSOPER, ORA\_SYSASM, ORA\_SYSBACKUP, ORA\_SYSKM -and ORA\_SYSDG constants can be imported using - - use DBD::Oracle qw(:ora_session_modes); - -This is one case where setting ORACLE\_SID may be useful since -connecting as SYSDBA or SYSOPER via SQL\*Net is frequently disabled -for security reasons. - -Example: - - $dsn = "dbi:Oracle:"; # no dbname here - $ENV{ORACLE_SID} = "orcl"; # set ORACLE_SID as needed - delete $ENV{TWO_TASK}; # make sure TWO_TASK isn't set - - $dbh = DBI->connect($dsn, "", "", { ora_session_mode => ORA_SYSDBA }); - -It has been reported that this only works if `$dsn` does not contain -a SID so that Oracle then uses the value of ORACLE\_SID (not -TWO\_TASK) environment variable to connect to a local instance. Also -the username and password should be empty, and the user executing the -script needs to be part of the dba group or osdba group. - -Note that this does not work with DRCP. - -#### ora\_oratab\_orahome - -Passing a true value for the ora\_oratab\_orahome attribute will make -DBD::Oracle change `$ENV{ORACLE_HOME}` to make the Oracle home directory -that specified in the `/etc/oratab` file _if_ the database to connect to -is specified as a SID that exists in the oratab file, and DBD::Oracle was -built to use the Oracle 7 OCI API (not Oracle 8+). - -#### ora\_module\_name - -After connecting to the database the value of this attribute is passed -to the SET\_MODULE() function in the `DBMS_APPLICATION_INFO` PL/SQL -package. This can be used to identify the application to the DBA for -monitoring and performance tuning purposes. For example: - - my $dbh = DBI->connect($dsn, $user, $passwd, { ora_module_name => $0 }); - - $dbh->{ora_module_name} = $y; - -The maximum size is 48 bytes. - -NOTE: You will need an Oracle client 10.1 or later to use this. - -#### ora\_driver\_name - -For 11g and later you can now set the name of the driver layer using OCI. -Perl, Perl5, ApachePerl so on. Names starting with "ORA" are reserved. You -can enter up to 8 characters. If none is enter then this will default to -DBDOxxxx where xxxx is the current version number. This value can be -retrieved on the server side using V$SESSION\_CONNECT\_INFO or -GV$SESSION\_CONNECT\_INFO - - my $dbh = DBI->connect($dsn, $user, $passwd, { ora_driver_name => 'ModPerl_1' }); - - $dbh->{ora_driver_name} = $q; - -#### ora\_client\_info - -Allows you to add any value (up to 64 bytes) to your session and it can be -retrieved on the server side from the `V$SESSION`a view. - - my $dbh = DBI->connect($dsn, $user, $passwd, { ora_client_info => 'Remote2' }); - - $dbh->{ora_client_info} = "Remote2"; - -NOTE: You will need an Oracle client 10.1 or later to use this. - -#### ora\_client\_identifier - -Allows you to specify the user identifier in the session handle. - -Most useful for web applications as it can pass in the session user -name which might be different to the connection user name. Can be up -to 64 bytes long but do not to include the password for security -reasons and the first character of the identifier should not be -':'. This value can be retrieved on the server side using `V$SESSION` -view. - - my $dbh = DBI->connect($dsn, $user, $passwd, { ora_client_identifier => $some_web_user }); - - $dbh->{ora_client_identifier} = $local_user; - -#### ora\_action - -Allows you to specify any string up to 32 bytes which may be retrieved -on the server side using `V$SESSION` view. - - my $dbh = DBI->connect($dsn, $user, $passwd, { ora_action => "Login"}); - - $dbh->{ora_action} = "New Long Query 22"; - -NOTE: You will need an Oracle client 10.1 or later to use this. - -#### ora\_dbh\_share - -Requires at least Perl 5.8.0 compiled with ithreads. - -Allows you to share -database connections between threads. The first connect will make the -connection, all following calls to connect with the same ora\_dbh\_share -attribute will use the same database connection. The value must be a -reference to a already shared scalar which is initialized to an empty -string. - - our $orashr : shared = '' ; - - $dbh = DBI->connect ($dsn, $user, $passwd, {ora_dbh_share => \$orashr}) ; - -#### ora\_events - -Set this attribute to `1` to enable Oracle Fast Application Notification -(FAN) in a new OCI environment. Can also be set via the `ORA_EVENTS` -environment variable. - -#### ora\_envhp - -The first time a connection is made a new OCI 'environment' is -created by DBD::Oracle and stored in the driver handle. -Subsequent connects reuse (share) that same OCI environment -by default. - -The ora\_envhp attribute can be used to disable the reuse of the OCI -environment from a previous connect. If the value is `0` then -a new OCI environment is allocated and used for this connection. - -The OCI environment holds information about the client side context, -such as the local NLS environment. By altering `%ENV` and setting -ora\_envhp to 0 you can create connections with different NLS -settings. This is most useful for testing. - -Note that for DRCP, setting `ora_envhp = 0` has no effect. Here, -a new session pool is created, using the current NLS environment, -for each new combination of dbname, uid/pwd, connection class, -and charset/ncharset. - -#### ora\_charset, ora\_ncharset - -For oracle versions >= 9.2 you can specify the client charset and -ncharset with the ora\_charset and ora\_ncharset attributes. You -still need to pass `ora_envhp = 0` for all but the first connect. - -These attributes override the settings from environment variables. - - $dbh = DBI->connect ($dsn, $user, $passwd, - {ora_charset => 'AL32UTF8'}); - -#### ora\_verbose - -Use this value to enable DBD::Oracle only tracing. Simply either set -the ora\_verbose attribute on the connect() method to the trace level -you desire like this - - my $dbh = DBI->connect($dsn, "", "", {ora_verbose=>6}); - -or set it directly on the DB handle like this; - - $dbh->{ora_verbose} =6; - -In both cases the DBD::Oracle trace level is set to 6, which is the highest -level tracing most of the calls to OCI. - -NOTE: In future versions of DBD::Oracle ora\_verbose will be changed so -that it is simply a switch to turn DBI's DBD tracing on or off. A -true value will turn it on and a false value will turn it off. DBI's -"DBD" tracing was not available when ora\_verbose was created and -ora\_verbose adds an additional test to every trace test. - -#### ora\_oci\_success\_warn - -Use this value to print otherwise silent OCI warnings that may happen -when an execute or fetch returns "Success With Info" or when you want -to tune RowCaching and LOB Reads - - $dbh->{ora_oci_success_warn} = 1; - -#### ora\_objects - -Use this value to enable extended embedded oracle objects mode. In extended: - -1. Embedded objects are returned as <DBD::Oracle::Object> instance (including type-name etc.) instead of simple ARRAY. -2. Determine object type for each instance. All object attributes are returned (not only super-type's attributes). - - $dbh->{ora_objects} = 1; - -#### ora\_ph\_type - -The default placeholder datatype for the database session. -The `TYPE` or ["ora\_type"](#ora_type) attributes to ["bind\_param" in DBI](https://metacpan.org/pod/DBI#bind_param) and -["bind\_param\_inout" in DBI](https://metacpan.org/pod/DBI#bind_param_inout) override the datatype for individual placeholders. -The most frequent reason for using this attribute is to permit trailing spaces -in values passed by placeholders. - -Constants for the values allowed for this attribute can be imported using - - use DBD::Oracle qw(:ora_types); - -Only the following values are permitted for this attribute. - -- ORA\_VARCHAR2 - - Oracle clients using OCI 8 will strip trailing spaces and allow embedded \\0 bytes. - Oracle clients using OCI 9.2 do not strip trailing spaces and allow embedded \\0 bytes. - This is the normal default placeholder type. - -- ORA\_STRING - - Do not strip trailing spaces and end the string at the first \\0. - -- ORA\_CHAR - - Do not strip trailing spaces and allow embedded \\0. - Force 'blank-padded comparison semantics'. - - For example: - - use DBD::Oracle qw(:ora_types); - - $SQL="select username from all_users where username = ?"; - #username is a char(8) - $sth=$dbh->prepare($SQL)"; - $sth->bind_param(1,'bloggs',{ ora_type => ORA_CHAR}); - - Will pad bloggs out to 8 characters and return the username. - -#### ora\_parse\_error\_offset - -If the previous error was from a failed `prepare` due to a syntax error, -this attribute gives the offset into the `Statement` attribute where the -error was found. - -#### ora\_array\_chunk\_size - -Due to OCI limitations, DBD::Oracle needs to buffer up rows of -bind values in its `execute_for_fetch` implementation. This attribute -sets the number of rows to buffer at a time (default value is 1000). - -The `execute_for_fetch` function will collect (at most) this many -rows in an array, send them off to the DB for execution, then go back -to collect the next chunk of rows and so on. This attribute can be -used to limit or extend the number of rows processed at a time. - -Note that this attribute also applies to `execute_array`, since that -method is implemented using `execute_for_fetch`. - -#### ora\_connect\_with\_default\_signals - -Sometimes the Oracle client seems to change some of the signal -handlers of the process during the connect phase. For instance, some -users have observed Perl's default `$SIG{INT}` handler being ignored -after connecting to an Oracle database. If this causes problems in -your application, set this attribute to an array reference of signals -you would like to be localized during the connect process. Once the -connect is complete, the signal handlers should be returned to their -previous state. - -For example: - - $dbh = DBI->connect ($dsn, $user, $passwd, - {ora_connect_with_default_signals => [ 'INT' ] }); - -NOTE disabling the signal handlers the OCI library sets up may affect -functionality in the OCI library. - -NOTE If you are using connect\_cached then the above example will lead -to DBI thinking each connection is different as an anonymous array reference -is being used. To avoid this when using connect\_cached you are advised -to use: - - my @ora_default_signals = (...); - $dbh = DBI->connect($dsn, $user, $passwd, - {ora_connect_with_default_signals => \@ora_default_signals}); - -In more recent Perl versions you could possibly make use of new state -variables. - -## **connect\_cached** - -Implemented by DBI, no driver-specific impact. -Please note that connect\_cached has not been tested with DRCP. - -## **data\_sources** - - @data_sources = DBI->data_sources('Oracle'); - @data_sources = $dbh->data_sources(); - -Returns a list of available databases. You will have to set either the 'ORACLE\_HOME' or -'TNS\_ADMIN' environment value to retrieve this list. It will read these values from -TNSNAMES.ORA file entries. - -# METHODS COMMON TO ALL HANDLES - -For all of the methods below, **$h** can be either a database handle (**$dbh**) -or a statement handle (**$sth**). Note that _$dbh_ and _$sth_ can be replaced with -any variable name you choose: these are just the names most often used. Another -common variable used in this documentation is $_rv_, which stands for "return value". - -## **err** - - $rv = $h->err; - -Returns the error code from the last method called. - -## **errstr** - - $str = $h->errstr; - -Returns the last error that was reported by Oracle. Starting with "ORA-00000" code followed by the error message. - -## **state** - - $str = $h->state; - -Oracle hasn't supported SQLSTATE since the early versions OCI. It will return empty when the command succeeds and -'S1000' (General Error) for all other errors. - -While this method can be called as either `$sth->state` or `$dbh->state`, it -is usually clearer to always use `$dbh->state`. - -## **trace** - -Implemented by DBI, no driver-specific impact. - -## **trace\_msg** - -Implemented by DBI, no driver-specific impact. - -## **parse\_trace\_flag** and **parse\_trace\_flags** - -Implemented by DBI, no driver-specific impact. - -## **func** - -DBD::Oracle uses the `func` method to support a variety of functions. - -## **Private database handle functions** - -Some of these functions are called through the method func() -which is described in the DBI documentation. Any function that begins with ora\_ -can be called directly. - -## **plsql\_errstr** - -This function returns a string which describes the errors -from the most recent PL/SQL function, procedure, package, -or package body compile in a format similar to the output -of the SQL\*Plus command 'show errors'. - -The function returns undef if the error string could not -be retrieved due to a database error. -Look in $dbh->errstr for the cause of the failure. - -If there are no compile errors, an empty string is returned. - -Example: - - # Show the errors if CREATE PROCEDURE fails - $dbh->{RaiseError} = 0; - if ( $dbh->do( q{ - CREATE OR REPLACE PROCEDURE perl_dbd_oracle_test as - BEGIN - PROCEDURE filltab( stuff OUT TAB ); asdf - END; } ) ) {} # Statement succeeded - } - elsif ( 6550 != $dbh->err ) { die $dbh->errstr; } # Utter failure - else { - my $msg = $dbh->func( 'plsql_errstr' ); - die $dbh->errstr if ! defined $msg; - die $msg if $msg; - } - -## **dbms\_output\_enable / dbms\_output\_put / dbms\_output\_get** - -These functions use the PL/SQL DBMS\_OUTPUT package to store and -retrieve text using the DBMS\_OUTPUT buffer. Text stored in this buffer -by dbms\_output\_put or any PL/SQL block can be retrieved by -dbms\_output\_get or any PL/SQL block connected to the same database -session. - -Stored text is not available until after dbms\_output\_put or the PL/SQL -block that saved it completes its execution. This means you **CAN NOT** -use these functions to monitor long running PL/SQL procedures. - -Example 1: - - # Enable DBMS_OUTPUT and set the buffer size - $dbh->{RaiseError} = 1; - $dbh->func( 1000000, 'dbms_output_enable' ); - - # Put text in the buffer . . . - $dbh->func( @text, 'dbms_output_put' ); - - # . . . and retrieve it later - @text = $dbh->func( 'dbms_output_get' ); - -Example 2: - - $dbh->{RaiseError} = 1; - $sth = $dbh->prepare(q{ - DECLARE tmp VARCHAR2(50); - BEGIN - SELECT SYSDATE INTO tmp FROM DUAL; - dbms_output.put_line('The date is '||tmp); - END; - }); - $sth->execute; - - # retrieve the string - $date_string = $dbh->func( 'dbms_output_get' ); - -## **dbms\_output\_enable ( \[ buffer\_size \] )** - -This function calls DBMS\_OUTPUT.ENABLE to enable calls to package -DBMS\_OUTPUT procedures GET, GET\_LINE, PUT, and PUT\_LINE. Calls to -these procedures are ignored unless DBMS\_OUTPUT.ENABLE is called -first. - -The buffer\_size is the maximum amount of text that can be saved in the -buffer and must be between 2000 and 1,000,000. If buffer\_size is not -given, the default is 20,000 bytes. - -## **dbms\_output\_put ( \[ @lines \] )** - -This function calls DBMS\_OUTPUT.PUT\_LINE to add lines to the buffer. - -If all lines were saved successfully the function returns 1. Depending -on the context, an empty list or undef is returned for failure. - -If any line causes buffer\_size to be exceeded, a buffer overflow error -is raised and the function call fails. Some of the text might be in -the buffer. - -## **dbms\_output\_get** - -This function calls DBMS\_OUTPUT.GET\_LINE to retrieve lines of text from -the buffer. - -In an array context, all complete lines are removed from the buffer and -returned as a list. If there are no complete lines, an empty list is -returned. - -In a scalar context, the first complete line is removed from the buffer -and returned. If there are no complete lines, undef is returned. - -Any text in the buffer after a call to DBMS\_OUTPUT.GET\_LINE or -DBMS\_OUTPUT.GET is discarded by the next call to DBMS\_OUTPUT.PUT\_LINE, -DBMS\_OUTPUT.PUT, or DBMS\_OUTPUT.NEW\_LINE. - -## **reauthenticate ( $username, $password )** - -Starts a new session against the current database using the credentials -supplied. Note that this does not work with DRCP. - -## **private\_attribute\_info** - - $hashref = $dbh->private_attribute_info(); - $hashref = $sth->private_attribute_info(); - -Returns a hash of all private attributes used by DBD::Oracle, for either -a database or a statement handle. Currently, all the hash values are undef. - -# ATTRIBUTES COMMON TO ALL HANDLES - -## **InactiveDestroy** (boolean) - -Implemented by DBI, no driver-specific impact. - -## **RaiseError** (boolean, inherited) - -Forces errors to always raise an exception. Although it defaults to off, it is recommended that this -be turned on, as the alternative is to check the return value of every method (prepare, execute, fetch, etc.) -manually, which is easy to forget to do. - -## **PrintError** (boolean, inherited) - -Forces database errors to also generate warnings, which can then be filtered with methods such as -locally redefining _$SIG{\_\_WARN\_\_}_ or using modules such as `CGI::Carp`. This attribute is on -by default. - -## **ShowErrorStatement** (boolean, inherited) - -Appends information about the current statement to error messages. If placeholder information -is available, adds that as well. Defaults to true. - -## **Warn** (boolean, inherited) - -Enables warnings. This is on by default, and should only be turned off in a local block -for a short a time only when absolutely needed. - -## **Executed** (boolean, read-only) - -Indicates if a handle has been executed. For database handles, this value is true after the ["do"](#do) method has been called, or -when one of the child statement handles has issued an ["execute"](#execute). Issuing a ["commit"](#commit) or ["rollback"](#rollback) always resets the -attribute to false for database handles. For statement handles, any call to ["execute"](#execute) or its variants will flip the value to -true for the lifetime of the statement handle. - -## **TraceLevel** (integer, inherited) - -Sets the trace level, similar to the ["trace"](#trace) method. See the sections on -["trace"](#trace) and ["parse\_trace\_flag"](#parse_trace_flag) for more details. - -## **Active** (boolean, read-only) - -Indicates if a handle is active or not. For database handles, this indicates if the database has -been disconnected or not. For statement handles, it indicates if all the data has been fetched yet -or not. Use of this attribute is not encouraged. - -## **Kids** (integer, read-only) - -Returns the number of child processes created for each handle type. For a driver handle, indicates the number -of database handles created. For a database handle, indicates the number of statement handles created. For -statement handles, it always returns zero, because statement handles do not create kids. - -## **ActiveKids** (integer, read-only) - -Same as `Kids`, but only returns those that are active. - -## **CachedKids** (hash ref) - -Returns a hashref of handles. If called on a database handle, returns all statement handles created by use of the -`prepare_cached` method. If called on a driver handle, returns all database handles created by the ["connect\_cached"](#connect_cached) -method. - -## **ChildHandles** (array ref) - -Implemented by DBI, no driver-specific impact. - -## **PrintWarn** (boolean, inherited) - -Implemented by DBI, no driver-specific impact. - -## **HandleError** (boolean, inherited) - -Implemented by DBI, no driver-specific impact. - -## **HandleSetErr** (code ref, inherited) - -Implemented by DBI, no driver-specific impact. - -## **ErrCount** (unsigned integer) - -Implemented by DBI, no driver-specific impact. - -## **FetchHashKeyName** (string, inherited) - -Implemented by DBI, no driver-specific impact. - -## **ChopBlanks** (boolean, inherited) - -Implemented by DBI, no driver-specific impact. - -## **Taint** (boolean, inherited) - -Implemented by DBI, no driver-specific impact. - -## **TaintIn** (boolean, inherited) - -Implemented by DBI, no driver-specific impact. - -## **TaintOut** (boolean, inherited) - -Implemented by DBI, no driver-specific impact. - -## **Profile** (inherited) - -Implemented by DBI, no driver-specific impact. - -## **Type** (scalar) - -Returns `dr` for a driver handle, `db` for a database handle, and `st` for a statement handle. -Should be rarely needed. - -## **LongReadLen** - -The maximum size of long or longraw columns to retrieve. If one of -these columns is longer than LongReadLen then either a data truncation -error will be raised (LongTrunkOk is false) or the column will be -silently truncated (LongTruncOk is true). - -DBI currently defaults this to 80. - -## **LongTruncOk** - -Implemented by DBI, no driver-specific impact. - -## **CompatMode** - -Type: boolean, inherited - -The CompatMode attribute is used by emulation layers (such as Oraperl) to enable compatible behaviour in the underlying driver (e.g., DBD::Oracle) for this handle. Not normally set by application code. - -It also has the effect of disabling the 'quick FETCH' of attribute values from the handles attribute cache. So all attribute values are handled by the drivers own FETCH method. This makes them slightly slower but is useful for special-purpose drivers like DBD::Multiplex. - -# ORACLE-SPECIFIC DATABASE HANDLE METHODS - -## **ora\_can\_unicode ( \[ $refresh \] )** - -Returns a number indicating whether either of the database character sets -is a Unicode encoding. Calls ora\_nls\_parameters() and passes the optional -$refresh parameter to it. - -0 = Neither character set is a Unicode encoding. - -1 = National character set is a Unicode encoding. - -2 = Database character set is a Unicode encoding. - -3 = Both character sets are Unicode encodings. - -## **ora\_can\_taf** - -Returns true if the current connection supports TAF events. False if otherwise. - -## **ora\_nls\_parameters ( \[ $refresh \] )** - -Returns a hash reference containing the current NLS parameters, as given -by the v$nls\_parameters view. The values fetched are cached between calls. -To cause the latest values to be fetched, pass a true value to the function. - -# ORACLE-SPECIFIC DATABASE FUNCTIONS - -## **ora\_server\_version** - - $versions = $dbh->func('ora_server_version'); - -Returns an array reference of server version strings e.g., - - [11,2,0,2,0] - -# DATABASE HANDLE METHODS - -## **selectall\_arrayref** - - $ary_ref = $dbh->selectall_arrayref($sql); - $ary_ref = $dbh->selectall_arrayref($sql, \%attr); - $ary_ref = $dbh->selectall_arrayref($sql, \%attr, @bind_values); - -Returns a reference to an array containing the rows returned by preparing and executing the SQL string. -See the DBI documentation for full details. - -## **selectall\_hashref** - - $hash_ref = $dbh->selectall_hashref($sql, $key_field); - -Returns a reference to a hash containing the rows returned by preparing and executing the SQL string. -See the DBI documentation for full details. - -## **selectcol\_arrayref** - - $ary_ref = $dbh->selectcol_arrayref($sql, \%attr, @bind_values); - -Returns a reference to an array containing the first column -from each rows returned by preparing and executing the SQL string. It is possible to specify exactly -which columns to return. See the DBI documentation for full details. - -## **prepare** - - $sth = $dbh->prepare($statement, \%attr); - -Prepares a statement for later execution by the database engine and returns a reference to a statement handle object. - -### **Prepare Attributes** - -These attributes may be used in the `\%attr` parameter of the -["prepare" in DBI](https://metacpan.org/pod/DBI#prepare) database handle method. - -- ora\_placeholders - - Set to false to disable processing of placeholders. Used mainly for loading a - PL/SQL package that has been _wrapped_ with Oracle's `wrap` utility. - -- ora\_auto\_lob - - If true (the default), fetching retrieves the contents of the CLOB or - BLOB column in most circumstances. If false, fetching retrieves the - Oracle "LOB Locator" of the CLOB or BLOB value. - - See ["LOBS AND LONGS"](#lobs-and-longs) for more details. - - See also the LOB tests in 05dbi.t of Oracle::OCI for examples - of how to use LOB Locators. - -- ora\_pers\_lob - - If true the ["Simple Fetch for CLOBs and BLOBs"](#simple-fetch-for-clobs-and-blobs) method for the ["Data Interface for Persistent LOBs"](#data-interface-for-persistent-lobs) will be - used for LOBs rather than the default method ["Data Interface for LOB Locators"](#data-interface-for-lob-locators). - -- ora\_clbk\_lob - - If true the ["Piecewise Fetch with Callback"](#piecewise-fetch-with-callback) method for the ["Data - Interface for Persistent LOBs"](#data-interface-for-persistent-lobs) will be used for LOBs. - -- ora\_piece\_lob - - If true the ["Piecewise Fetch with Polling"](#piecewise-fetch-with-polling) method for the ["Data - Interface for Persistent LOBs"](#data-interface-for-persistent-lobs) will be used for LOBs. - -- ora\_piece\_size - - This is the max piece size for the ["Piecewise Fetch with Callback"](#piecewise-fetch-with-callback) - and ["Piecewise Fetch with Polling"](#piecewise-fetch-with-polling) methods, in chars for CLOBS, and - bytes for BLOBS. - -- ora\_check\_sql - - If 1 (default), force SELECT statements to be described in prepare(). - If 0, allow SELECT statements to defer describe until execute(). - - See ["Prepare Postponed Till Execute"](#prepare-postponed-till-execute) for more information. - -- ora\_exe\_mode - - This will set the execute mode of the current statement. Presently - only one mode is supported; - - OCI_STMT_SCROLLABLE_READONLY - make result set scrollable - - See ["SCROLLABLE CURSORS"](#scrollable-cursors) for more details. - -- ora\_prefetch\_rows - - Sets the number of rows to be prefetched. If it is not set, then the - default value is 1. See ["Row Prefetching"](#row-prefetching) for more details. - -- ora\_prefetch\_memory - - Sets the memory level for rows to be prefetched. The application then - fetches as many rows as will fit into that much memory. See ["Row - Prefetching"](#row-prefetching) for more details. - -- ora\_row\_cache\_off - - By default DBD::Oracle will use a row cache when fetching to cut down - the number of round trips to the server. If you do not want to use an - array fetch set this value to any value other than 0; - - See ["Row Prefetching"](#row-prefetching) for more details. - -### **Placeholders** - -There are three types of placeholders that can be used in -DBD::Oracle. - -The first is the "question mark" type, in which each placeholder is -represented by a single question mark character. This is the method -recommended by the DBI and is the most portable. Each question -mark is internally replaced by a "dollar sign number" in the order in -which they appear in the query (important when using ["bind\_param"](#bind_param)). - -The second type of placeholder is "named parameters" in the format -":foo" which is the one Oracle prefers. - - $dbh->{RaiseError} = 1; # save having to check each method call - $sth = $dbh->prepare("SELECT name, age FROM people WHERE name LIKE :name"); - $sth->bind_param(':name', "John%"); - $sth->execute; - DBI::dump_results($sth); - -Note when calling bind\_param with named parameters you must include -the leading colon. The advantage of this placeholder type is that you -can use the same placeholder more than once in the same SQL statement -but you only need to bind it once. - -The last placeholder type is a variation of the two above where you -name each placeholder :N (where N is a number). Like the named -placeholders above you can use the same placeholder multiple times in -the SQL but when you call bind\_param you only need to pass the N -(e.g., for :1 you use bind\_param(1,...) and not bind\_param(':1',...). - -The different types of placeholders cannot be mixed within a statement, but you may -use different ones for each statement handle you have. This is confusing at best, so -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" ); - - # note, that ora_internal_type defaults to SQLT_FLT for ORA_NUMBER_TABLE . - if( not $sth->bind_param_inout(":mytable", \\@arr, 10, { - ora_type => ORA_NUMBER_TABLE, - ora_maxarray_numentries => (scalar(@arr)+2), - ora_internal_type => SQLT_FLT - } ) ){ - die "bind :mytable error: ",$dbh->errstr,"\n"; - } - $cc=undef; - if( not $sth->bind_param_inout(":cc", \$cc, 100 ) ){ - die "bind :cc error: ",$dbh->errstr,"\n"; - } - - if( not $sth->execute() ){ - die "Execute failed: ",$dbh->errstr,"\n"; - } - print "Result: cc=",$cc,"\n", - "\tarr=",Data::Dumper::Dumper(\@arr),"\n"; - -The result is like: - - Result: cc=2 - arr=$VAR1 = [ - '1', - '2', - '3.5', - '-1', - '-2' - ]; - -If you change bind type to **SQLT\_INT**, like: - - ora_internal_type => SQLT_INT - -you get: - - Result: cc=2 - arr=$VAR1 = [ - 1, - 2, - 3, - -1, - -2 - ]; - -## **bind\_param\_inout\_array** - -DBD::Oracle supports this undocumented feature of DBI. See ["Returning A Value from an INSERT"](#returning-a-value-from-an-insert) for an example. - -## **bind\_param\_array** - - $rv = $sth->bind_param_array($param_num, $array_ref_or_value) - $rv = $sth->bind_param_array($param_num, $array_ref_or_value, $bind_type) - $rv = $sth->bind_param_array($param_num, $array_ref_or_value, \%attr) - -Binds an array of values to a placeholder, so that each is used in turn by a call -to the ["execute\_array"](#execute_array) method. - -## **execute** - - $rv = $sth->execute(@bind_values); - -Perform whatever processing is necessary to execute the prepared statement. - -## **execute\_array** - - $tuples = $sth->execute_array() or die $sth->errstr; - $tuples = $sth->execute_array(\%attr) or die $sth->errstr; - $tuples = $sth->execute_array(\%attr, @bind_values) or die $sth->errstr; - - ($tuples, $rows) = $sth->execute_array(\%attr) or die $sth->errstr; - ($tuples, $rows) = $sth->execute_array(\%attr, @bind_values) or die $sth->errstr; - -Execute a prepared statement once for each item in a passed-in hashref, or items that -were previously bound via the ["bind\_param\_array"](#bind_param_array) method. See the DBI documentation -for more details. - -DBD::Oracle takes full advantage of OCI's array interface so inserts and updates using this interface will run very -quickly. - -## **execute\_for\_fetch** - - $tuples = $sth->execute_for_fetch($fetch_tuple_sub); - $tuples = $sth->execute_for_fetch($fetch_tuple_sub, \@tuple_status); - - ($tuples, $rows) = $sth->execute_for_fetch($fetch_tuple_sub); - ($tuples, $rows) = $sth->execute_for_fetch($fetch_tuple_sub, \@tuple_status); - -Used internally by the ["execute\_array"](#execute_array) method, and rarely used directly. See the -DBI documentation for more details. - -## **fetchrow\_arrayref** - - $ary_ref = $sth->fetchrow_arrayref; - -Fetches the next row of data from the statement handle, and returns a reference to an array -holding the column values. Any columns that are NULL are returned as undef within the array. - -If there are no more rows or if an error occurs, this method returns undef. You should -check `$sth->err` afterwards (or use the ["RaiseError"](#raiseerror) attribute) to discover if the undef returned -was due to an error. - -Note that the same array reference is returned for each fetch, so don't store the reference and -then use it after a later fetch. Also, the elements of the array are also reused for each row, -so take care if you want to take a reference to an element. See also ["bind\_columns"](#bind_columns). - -## **fetchrow\_array** - - @ary = $sth->fetchrow_array; - -Similar to the ["fetchrow\_arrayref"](#fetchrow_arrayref) method, but returns a list of column information rather than -a reference to a list. Do not use this in a scalar context. - -## **fetchrow\_hashref** - - $hash_ref = $sth->fetchrow_hashref; - $hash_ref = $sth->fetchrow_hashref($name); - -Fetches the next row of data and returns a hashref containing the name of the columns as the keys -and the data itself as the values. Any NULL value is returned as undef value. - -If there are no more rows or if an error occurs, this method returns undef. You should -check `$sth->err` afterwards (or use the ["RaiseError"](#raiseerror) attribute) to discover if the undef returned -was due to an error. - -The optional `$name` argument should be either `NAME`, `NAME_lc` or `NAME_uc`, and indicates -what sort of transformation to make to the keys in the hash. By default Oracle uses upper case. - -## **fetchall\_arrayref** - - $tbl_ary_ref = $sth->fetchall_arrayref(); - $tbl_ary_ref = $sth->fetchall_arrayref( $slice ); - $tbl_ary_ref = $sth->fetchall_arrayref( $slice, $max_rows ); - -Returns a reference to an array of arrays that contains all the remaining rows to be fetched from the -statement handle. If there are no more rows, an empty arrayref will be returned. If an error occurs, -the data read in so far will be returned. Because of this, you should always check `$sth->err` after -calling this method, unless ["RaiseError"](#raiseerror) has been enabled. - -If `$slice` is an array reference, fetchall\_arrayref uses the ["fetchrow\_arrayref"](#fetchrow_arrayref) method to fetch each -row as an array ref. If the `$slice` array is not empty then it is used as a slice to select individual -columns by perl array index number (starting at 0, unlike column and parameter numbers which start at 1). - -With no parameters, or if $slice is undefined, fetchall\_arrayref acts as if passed an empty array ref. - -If `$slice` is a hash reference, fetchall\_arrayref uses ["fetchrow\_hashref"](#fetchrow_hashref) to fetch each row as a hash reference. - -See the DBI documentation for a complete discussion. - -## **fetchall\_hashref** - - $hash_ref = $sth->fetchall_hashref( $key_field ); - -Returns a hashref containing all rows to be fetched from the statement handle. See the DBI documentation for -a full discussion. - -## **finish** - - $rv = $sth->finish; - -Indicates to DBI that you are finished with the statement handle and are not going to use it again. Only needed -when you have not fetched all the possible rows. - -## **rows** - - $rv = $sth->rows; - -Returns the number of rows affected for updates, deletes and inserts and -1 for selects. - -## **bind\_col** - - $rv = $sth->bind_col($column_number, \$var_to_bind); - $rv = $sth->bind_col($column_number, \$var_to_bind, \%attr ); - $rv = $sth->bind_col($column_number, \$var_to_bind, $bind_type ); - -Binds a Perl variable and/or some attributes to an output column of a SELECT statement. -Column numbers count up from 1. You do not need to bind output columns in order to fetch data. - -NOTE: DBD::Oracle does not use the `$bind_type` to determine how to -bind the column; it uses what Oracle says the data type is. You can -however set the StrictlyTyped/DiscardString attributes and these will -take effect as these attributes are applied after the column is -retrieved. - -See the DBI documentation for a discussion of the optional parameters `\%attr` and `$bind_type` - -## **bind\_columns** - - $rv = $sth->bind_columns(@list_of_refs_to_vars_to_bind); - -Calls the ["bind\_col"](#bind_col) method for each column in the SELECT statement, using the supplied list. - -## **dump\_results** - - $rows = $sth->dump_results($maxlen, $lsep, $fsep, $fh); - -Fetches all the rows from the statement handle, calls `DBI::neat_list` for each row, and -prints the results to `$fh` (which defaults to `STDOUT`). Rows are separated by `$lsep` (which defaults -to a newline). Columns are separated by `$fsep` (which defaults to a comma). The `$maxlen` controls -how wide the output can be, and defaults to 35. - -This method is designed as a handy utility for prototyping and testing queries. Since it uses -"neat\_list" to format and edit the string for reading by humans, it is not recommended -for data transfer applications. - -# STATEMENT HANDLE ATTRIBUTES - -## **NUM\_OF\_FIELDS** (integer, read-only) - -Returns the number of columns returned by the current statement. A number will only be returned for -SELECT statements for INSERT, -UPDATE, and DELETE statements which contain a RETURNING clause. -This method returns undef if called before `execute()`. - -## **NUM\_OF\_PARAMS** (integer, read-only) - -Returns the number of placeholders in the current statement. - -## **NAME** (arrayref, read-only) - -Returns an arrayref of column names for the current statement. This -method will only work for SELECT statements, for SHOW statements, and for -INSERT, UPDATE, and DELETE statements which contain a RETURNING clause. -This method returns undef if called before `execute()`. - -## **NAME\_lc** (arrayref, read-only) - -The same as the `NAME` attribute, except that all column names are forced to lower case. - -## **NAME\_uc** (arrayref, read-only) - -The same as the `NAME` attribute, except that all column names are forced to upper case. - -## **NAME\_hash** (hashref, read-only) - -Similar to the `NAME` attribute, but returns a hashref of column names instead of an arrayref. The names of the columns -are the keys of the hash, and the values represent the order in which the columns are returned, starting at 0. -This method returns undef if called before `execute()`. - -## **NAME\_lc\_hash** (hashref, read-only) - -The same as the `NAME_hash` attribute, except that all column names are forced to lower case. - -## **NAME\_uc\_hash** (hashref, read-only) - -The same as the `NAME_hash` attribute, except that all column names are forced to lower case. - -## **TYPE** (arrayref, read-only) - -Returns an arrayref indicating the data type for each column in the statement. -This method returns undef if called before `execute()`. - -## **PRECISION** (arrayref, read-only) - -Returns an arrayref of integer values for each column returned by the statement. -The number indicates the precision for `NUMERIC` columns, the size in number of -characters for `CHAR` and `VARCHAR` columns, and for all other types of columns -it returns the number of _bytes_. -This method returns undef if called before `execute()`. - -## **SCALE** (arrayref, read-only) - -Returns an arrayref of integer values for each column returned by the statement. The number -indicates the scale of the that column. The only type that will return a value is `NUMERIC`. -This method returns undef if called before `execute()`. - -## **NULLABLE** (arrayref, read-only) - -Returns an arrayref of integer values for each column returned by the statement. The number -indicates if the column is nullable or not. 0 = not nullable, 1 = nullable, 2 = unknown. -This method returns undef if called before `execute()`. - -## **Database** (dbh, read-only) - -Returns the database handle this statement handle was created from. - -## **ParamValues** (hash ref, read-only) - -Returns a reference to a hash containing the values currently bound to placeholders. If the "named parameters" -type of placeholders are being used (such as ":foo"), then the keys of the hash will be the names of the -placeholders (without the colon). If the "dollar sign numbers" type of placeholders are being used, the keys of the hash will -be the numbers, without the dollar signs. If the "question mark" type is used, integer numbers will be returned, -starting at one and increasing for every placeholder. - -If this method is called before ["execute"](#execute), the literal values passed in are returned. If called after -["execute"](#execute), then the quoted versions of the values are returned. - -## **ParamTypes** (hash ref, read-only) - -Returns a reference to a hash containing the type names currently bound to placeholders. The keys -are the same as returned by the ParamValues method. The values are hashrefs containing a single key value -pair, in which the key is either 'TYPE' if the type has a generic SQL equivalent, and 'pg\_type' if the type can -only be expressed by a Postgres type. The value is the internal number corresponding to the type originally -passed in. (Placeholders that have not yet been bound will return undef as the value). This allows the output of -ParamTypes to be passed back to the ["bind\_param"](#bind_param) method. - -## **Statement** (string, read-only) - -Returns the statement string passed to the most recent "prepare" method called in this database handle, even if that method -failed. This is especially useful where "RaiseError" is enabled and the exception handler checks $@ and sees that a `prepare` -method call failed. - -## **RowsInCache** - -Returns the number of un-fetched rows in the cache for selects. - -# SCROLLABLE CURSORS - -Oracle supports the concept of a 'Scrollable Cursor' which is defined as a 'Result Set' where -the rows can be fetched either sequentially or non-sequentially. One can fetch rows forward, -backwards, from any given position or the n-th row from the current position in the result set. - -Rows are numbered sequentially starting at one and client-side caching of the partial or entire result set -can improve performance by limiting round trips to the server. - -Oracle does not support DML type operations with scrollable cursors so you are limited -to simple 'Select' operations only. As well you can not use this functionality with remote -mapped queries or if the LONG datatype is part of the select list. - -However, LOBSs, CLOBSs, and BLOBs do work as do all the regular bind, and fetch methods. - -Only use scrollable cursors if you really have a good reason to. They do use up considerable -more server and client resources and have poorer response times than non-scrolling cursors. - -## Enabling Scrollable Cursors - -To enable this functionality you must first import the 'Fetch Orientation' and the 'Execution Mode' constants by using; - - use DBD::Oracle qw(:ora_fetch_orient :ora_exe_modes); - -Next you will have to tell DBD::Oracle that you will be using scrolling by setting the ora\_exe\_mode attribute on the -statement handle to 'OCI\_STMT\_SCROLLABLE\_READONLY' with the prepare method; - - $sth=$dbh->prepare($SQL,{ora_exe_mode=>OCI_STMT_SCROLLABLE_READONLY}); - -When the statement is executed you will then be able to use 'ora\_fetch\_scroll' method to get a row -or you can still use any of the other fetch methods but with a poorer response time than if you used a -non-scrolling cursor. As well scrollable cursors are compatible with any applicable bind methods. - -## Scrollable Cursor Methods - -The following driver-specific methods are used with scrollable cursors. - -- ora\_scroll\_position - - $position = $sth->ora_scroll_position(); - - This method returns the current position (row number) attribute of the result set. Prior to the first fetch this value is 0. This is the only time - this value will be 0 after the first fetch the value will be set, so you can use this value to test if any rows have been fetched. - The minimum value will always be 1 after the first fetch. The maximum value will always be the total number of rows in the record set. - -- ora\_fetch\_scroll - - $ary_ref = $sth->ora_fetch_scroll($fetch_orient,$fetch_offset); - - Works the same as `fetchrow_arrayref`, excepts one passes in a 'Fetch Orientation' constant and a fetch\_offset - value which will then determine the row that will be fetched. It returns the row as a list containing the field values. - Null fields are returned as _undef_ values in the list. - - The valid orientation constant and fetch offset values combination are detailed below - - OCI_FETCH_CURRENT, fetches the current row, the fetch offset value is ignored. - OCI_FETCH_NEXT, fetches the next row from the current position, the fetch offset value - is ignored. - OCI_FETCH_FIRST, fetches the first row, the fetch offset value is ignored. - OCI_FETCH_LAST, fetches the last row, the fetch offset value is ignored. - OCI_FETCH_PRIOR, fetches the previous row from the current position, the fetch offset - value is ignored. - - OCI_FETCH_ABSOLUTE, fetches the row that is specified by the fetch offset value. - - OCI_FETCH_ABSOLUTE, and a fetch offset value of 1 is equivalent to a OCI_FETCH_FIRST. - OCI_FETCH_ABSOLUTE, and a fetch offset value of 0 is equivalent to a OCI_FETCH_CURRENT. - - OCI_FETCH_RELATIVE, fetches the row relative from the current position as specified by the - fetch offset value. - - OCI_FETCH_RELATIVE, and a fetch offset value of 0 is equivalent to a OCI_FETCH_CURRENT. - OCI_FETCH_RELATIVE, and a fetch offset value of 1 is equivalent to a OCI_FETCH_NEXT. - OCI_FETCH_RELATIVE, and a fetch offset value of -1 is equivalent to a OCI_FETCH_PRIOR. - - The effect that a ora\_fetch\_scroll method call has on the current position attribute is detailed below. - - OCI_FETCH_CURRENT, has no effect on the current position attribute. - OCI_FETCH_NEXT, increments current position attribute by 1 - OCI_FETCH_NEXT, when at the last row in the record set does not change current position - attribute, it is equivalent to a OCI_FETCH_CURRENT - OCI_FETCH_FIRST, sets the current position attribute to 1. - OCI_FETCH_LAST, sets the current position attribute to the total number of rows in the - record set. - OCI_FETCH_PRIOR, decrements current position attribute by 1. - OCI_FETCH_PRIOR, when at the first row in the record set does not change current position - attribute, it is equivalent to a OCI_FETCH_CURRENT. - - OCI_FETCH_ABSOLUTE, sets the current position attribute to the fetch offset value. - OCI_FETCH_ABSOLUTE, and a fetch offset value that is less than 1 does not change - current position attribute, it is equivalent to a OCI_FETCH_CURRENT. - OCI_FETCH_ABSOLUTE, and a fetch offset value that is greater than the number of records in - the record set, does not change current position attribute, it is - equivalent to a OCI_FETCH_CURRENT. - OCI_FETCH_RELATIVE, sets the current position attribute to (current position attribute + - fetch offset value). - OCI_FETCH_RELATIVE, and a fetch offset value that makes the current position less than 1, - does not change fetch offset value so it is equivalent to a OCI_FETCH_CURRENT. - OCI_FETCH_RELATIVE, and a fetch offset value that makes it greater than the number of records - in the record set, does not change fetch offset value so it is equivalent - to a OCI_FETCH_CURRENT. - - The effects of the differing orientation constants on the first fetch (current position attribute at 0) are as follows. - - OCI_FETCH_CURRENT, dose not fetch a row or change the current position attribute. - OCI_FETCH_FIRST, fetches row 1 and sets the current position attribute to 1. - OCI_FETCH_LAST, fetches the last row in the record set and sets the current position - attribute to the total number of rows in the record set. - OCI_FETCH_NEXT, equivalent to a OCI_FETCH_FIRST. - OCI_FETCH_PRIOR, equivalent to a OCI_FETCH_CURRENT. - - OCI_FETCH_ABSOLUTE, and a fetch offset value that is less than 1 is equivalent to a - OCI_FETCH_CURRENT. - OCI_FETCH_ABSOLUTE, and a fetch offset value that is greater than the number of - records in the record set is equivalent to a OCI_FETCH_CURRENT. - OCI_FETCH_RELATIVE, and a fetch offset value that is less than 1 is equivalent - to a OCI_FETCH_CURRENT. - OCI_FETCH_RELATIVE, and a fetch offset value that makes it greater than the number - of records in the record set, is equivalent to a OCI_FETCH_CURRENT. - -## Scrollable Cursor Usage - -Given a simple code like this: - - use DBI; - use DBD::Oracle qw(:ora_types :ora_fetch_orient :ora_exe_modes); - my $dbh = DBI->connect($dsn, $dbuser, ''); - my $SQL = "select id, - first_name, - last_name - from employee"; - my $sth=$dbh->prepare($SQL,{ora_exe_mode=>OCI_STMT_SCROLLABLE_READONLY}); - $sth->execute(); - my $value; - -and one assumes that the number of rows returned from the query is 20, the code snippets below will illustrate the use of ora\_fetch\_scroll -method; - -- Fetching the Last Row - - $value = $sth->ora_fetch_scroll(OCI_FETCH_LAST,0); - print "id=".$value->[0].", First Name=".$value->[1].", Last Name=".$value->[2]."\n"; - print "current scroll position=".$sth->ora_scroll_position()."\n"; - - The current position attribute to will be 20 after this snippet. This is also a way to get the number of rows in the record set, however, - if the record set is large this could take some time. - -- Fetching the Current Row - - $value = $sth->ora_fetch_scroll(OCI_FETCH_CURRENT,0); - print "id=".$value->[0].", First Name=".$value->[1].", Last Name=".$value->[2]."\n"; - print "current scroll position=".$sth->ora_scroll_position()."\n"; - - The current position attribute will still be 20 after this snippet. - -- Fetching the First Row - - $value = $sth->ora_fetch_scroll(OCI_FETCH_FIRST,0); - print "id=".$value->[0].", First Name=".$value->[1].", Last Name=".$value->[2]."\n"; - print "current scroll position=".$sth->ora_scroll_position()."\n"; - - The current position attribute will be 1 after this snippet. - -- Fetching the Next Row - - for(my $i=0;$i<=3;$i++){ - $value = $sth->ora_fetch_scroll(OCI_FETCH_NEXT,0); - print "id=".$value->[0].", First Name=".$value->[1].", Last Name=".$value->[2]."\n"; - } - print "current scroll position=".$sth->ora_scroll_position()."\n"; - - The current position attribute will be 5 after this snippet. - -- Fetching the Prior Row - - for(my $i=0;$i<=3;$i++){ - $value = $sth->ora_fetch_scroll(OCI_FETCH_PRIOR,0); - print "id=".$value->[0].", First Name=".$value->[1].", Last Name=".$value->[2]."\n"; - } - print "current scroll position=".$sth->ora_scroll_position()."\n"; - - The current position attribute will be 1 after this snippet. - -- Fetching the 10th Row - - $value = $sth->ora_fetch_scroll(OCI_FETCH_ABSOLUTE,10); - print "id=".$value->[0].", First Name=".$value->[1].", Last Name=".$value->[2]."\n"; - print "current scroll position=".$sth->ora_scroll_position()."\n"; - - The current position attribute will be 10 after this snippet. - -- Fetching the 10th to 14th Row - - for(my $i=10;$i<15;$i++){ - $value = $sth->ora_fetch_scroll(OCI_FETCH_ABSOLUTE,$i); - print "id=".$value->[0].", First Name=".$value->[1].", Last Name=".$value->[2]."\n"; - } - print "current scroll position=".$sth->ora_scroll_position()."\n"; - - The current position attribute will be 14 after this snippet. - -- Fetching the 14th to 10th Row - - for(my $i=14;$i>9;$i--){ - $value = $sth->ora_fetch_scroll(OCI_FETCH_ABSOLUTE,$i); - print "id=".$value->[0].", First Name=".$value->[1].", Last Name=".$value->[2]."\n"; - } - print "current scroll position=".$sth->ora_scroll_position()."\n"; - - The current position attribute will be 10 after this snippet. - -- Fetching the 5th Row From the Present Position. - - $value = $sth->ora_fetch_scroll(OCI_FETCH_RELATIVE,5); - print "id=".$value->[0].", First Name=".$value->[1].", Last Name=".$value->[2]."\n"; - print "current scroll position=".$sth->ora_scroll_position()."\n"; - - The current position attribute will be 15 after this snippet. - -- Fetching the 9th Row Prior From the Present Position - - $value = $sth->ora_fetch_scroll(OCI_FETCH_RELATIVE,-9); - print "id=".$value->[0].", First Name=".$value->[1].", Last Name=".$value->[2]."\n"; - print "current scroll position=".$sth->ora_scroll_position()."\n"; - - The current position attribute will be 6 after this snippet. - -- Use Finish - - $sth->finish(); - - When using scrollable cursors it is required that you use the $sth->finish() method when you are done with the cursor as this type of - cursor has to be explicitly cancelled on the server. If you do not do this you may cause resource problems on your database. - -# LOBS AND LONGS - -The key to working with LOBs (CLOB, BLOBs) is to remember the value of an Oracle LOB column is not the content of the LOB. It's a -'LOB Locator' which, after being selected or inserted needs extra processing to read or write the content of the LOB. There are also legacy LONG types (LONG, LONG RAW) -which are presently deprecated by Oracle but are still in use. These LONG types do not utilize a 'LOB Locator' and also are more limited in -functionality than CLOB or BLOB fields. - -DBD::Oracle now offers three interfaces to LOB and LONG data, - -- ["Data Interface for Persistent LOBs"](#data-interface-for-persistent-lobs) - - With this interface DBD::Oracle handles your data directly utilizing regular OCI calls, Oracle itself takes care of the LOB Locator operations in the case of - BLOBs and CLOBs treating them exactly as if they were the same as the legacy LONG or LONG RAW types. - -- ["Data Interface for LOB Locators"](#data-interface-for-lob-locators) - - With this interface DBD::Oracle handles your data utilizing LOB Locator OCI calls so it only works with CLOB and BLOB datatypes. With this interface DBD::Oracle takes care of the LOB Locator operations for you. - -- LOB Locator Method Interface - - This allows the user direct access to the LOB Locator methods, so you have to take care of the LOB Locator operations yourself. - -Generally speaking the interface that you will chose will be dependent on what end you are trying to achieve. All have their benefits and -drawbacks. - -One point to remember when working with LOBs (CLOBs, BLOBs) is if your LOB column can be in one of three states; - -- NULL - - The table cell is created, but the cell holds no locator or value. - If your LOB field is in this state then there is no LOB Locator that DBD::Oracle can work so if your encounter a - - DBD::Oracle::db::ora_lob_read: locator is not of type OCILobLocatorPtr - - error when working with a LOB. - - You can correct this by using an SQL UPDATE statement to reset the LOB column to a non-NULL (or empty LOB) value with either EMPTY\_BLOB or EMPTY\_CLOB as in this example; - - UPDATE lob_example - SET bindata=EMPTY_BLOB() - WHERE bindata IS NULL. - -- Empty - - A LOB instance with a locator exists in the cell, but it has no value. The length of the LOB is zero. In this case DBD::Oracle will return 'undef' for the field. - -- Populated - - A LOB instance with a locator and a value exists in the cell. You actually get the LOB value. - -## Data Interface for Persistent LOBs - -This is the original interface for LONG and LONG RAW datatypes and from Oracle 9iR1 and later the OCI API was extended to work directly with the other LOB datatypes. -In other words you can treat all LOB type data (BLOB, CLOB) as if it was a LONG, LONG RAW, or VARCHAR2. So you can perform INSERT, UPDATE, fetch, bind, and define operations on LOBs using the same techniques -you would use on other datatypes that store character or binary data. In some cases there are fewer round trips to the server as no 'LOB Locators' are -used, normally one can get an entire LOB is a single round trip. - -### Simple Fetch for LONGs and LONG RAWs - -As the name implies this is the simplest way to use this interface. DBD::Oracle just attempts to get your LONG datatypes as a single large piece. -There are no special settings, simply set the database handle's 'LongReadLen' attribute to a value that will be larger than the expected size of the LONG or LONG RAW. -If the size of the LONG or LONG RAW exceeds 'LongReadLen' DBD::Oracle will return an 'ORA-24345: A Truncation' error. To stop this set the database handle's 'LongTruncOk' attribute to '1'. -The maximum value of 'LongReadLen' seems to be dependent on the physical memory limits of the box that Oracle is running on. You have most likely reached this limit if you run into -an 'ORA-01062: unable to allocate memory for define buffer' error. One solution is to set the size of 'LongReadLen' to a lower value. - -For example give this table; - - CREATE TABLE test_long ( - id NUMBER, - long1 long) - -this code; - - $dbh->{LongReadLen} = 2*1024*1024; #2 meg - $SQL='select p_id,long1 from test_long'; - $sth=$dbh->prepare($SQL); - $sth->execute(); - while (my ( $p_id,$long )=$sth->fetchrow()){ - print "p_id=".$p_id."\n"; - print "long=".$long."\n"; - } - -Will select out all of the long1 fields in the table as long as they are all under 2MB in length. A value in long1 longer than this will throw an error. Adding this line; - - $dbh->{LongTruncOk}=1; - -before the execute will return all the long1 fields but they will be truncated at 2MBs. - -### Using ora\_ncs\_buff\_mtpl - -When getting CLOBs and NCLOBs in or out of Oracle, the Server will translate from the Server's NCharSet to the -Client's. If they happen to be the same or at least compatible then all of these actions are a 1 char to 1 char bases. -Thus if you set your LongReadLen buffer to 10\_000\_000 you will get up to 10\_000\_000 char. - -However if the Server has to translate from one NCharSet to another it will use bytes for conversion. The buffer -value is set to 4 \* LONG\_READ\_LEN which was very wasteful as you might only be asking for 10\_000\_000 bytes -but you were actually using 40\_000\_000 bytes of buffer under the hood. You would still get 10\_000\_000 bytes -(maybe less characters though) but you are using allot more memory that you need. - -You can now customize the size of the buffer by setting the 'ora\_ncs\_buff\_mtpl' either on the connection or statement handle. You can -also set this as 'ORA\_DBD\_NCS\_BUFFER' OS environment variable so you will have to go back and change all your code if you are getting into trouble. - -The default value is still set to 4 for backward compatibility. You can lower this value and thus increase the amount of data you can retrieve. If the -ora\_ncs\_buff\_mtpl is too small DBD::Oracle will throw and error telling you to increase this buffer by one. - -If the error is not captured then you may get at some random point later on, usually at a finish() or disconnect() or even a fetch() this error; - - ORA-03127: no new operations allowed until the active operation ends - -This is one of the more obscure ORA errors (have some fun and report it to Meta-Link they will scratch their heads for hours) - -If you get this, simply increment the ora\_ncs\_buff\_mtpl by one until it goes away. - -This should greatly increase your ability to select very large CLOBs or NCLOBs, by freeing up a large block of memory. - -You can tune this value by setting ora\_oci\_success\_warn which will display the following - - OCILobRead field 2 of 3 SUCCESS: csform 1 (SQLCS_IMPLICIT), LOBlen 10240(characters), LongReadLen - 20(characters), BufLen 80(characters), Got 28(characters) - -In the case above the query Got 28 characters (well really only 20 characters of 28 bytes) so we could use ora\_ncs\_buff\_mtpl=>2 (20\*2=40) thus saving 40bytes of memory. - -### Simple Fetch for CLOBs and BLOBs - -To use this interface for the CLOB and BLOB datatypes set the 'ora\_pers\_lob' attribute of the statement handle to '1' with the prepare method, and -set the database handle's 'LongReadLen' attribute to a value that will be larger than the expected size of the LOB. If the size of the LOB exceeds -'LongReadLen' DBD::Oracle will return an 'ORA-24345: A Truncation' error. To stop this set the database handle's 'LongTruncOk' attribute to '1'. -The maximum value of 'LongReadLen' seems to be dependent on the physical memory limits of the box that Oracle is running on in the same way that LONGs and LONG RAWs are. - -For CLOBs and NCLOBs the limit is 64k chars if there is no truncation. This is an internal OCI limit--complain to them if you want it changed. However if your CLOB is longer than this -and also larger than 'LongReadLen' then 'LongReadLen' chars are returned. - -It seems with BLOBs you are not limited by the 64k. - -For example give this table; - - CREATE TABLE test_lob (id NUMBER, - clob1 CLOB, - clob2 CLOB, - blob1 BLOB, - blob2 BLOB) - -this code; - - $dbh->{LongReadLen} = 2*1024*1024; #2 meg - $SQL='select p_id,lob_1,lob_2,blob_2 from test_lobs'; - $sth=$dbh->prepare($SQL,{ora_pers_lob=>1}); - $sth->execute(); - while (my ( $p_id,$log,$log2,$log3,$log4 )=$sth->fetchrow()){ - print "p_id=".$p_id."\n"; - print "clob1=".$clob1."\n"; - print "clob2=".$clob2."\n"; - print "blob1=".$blob2."\n"; - print "blob2=".$blob2."\n"; - } - -Will select out all of the LOBs in the table as long as they are all under 2MB in length. Longer lobs will throw an error. Adding this line; - - $dbh->{LongTruncOk}=1; - -before the execute will return all the lobs but they will be truncated at 2MBs. - -### Piecewise Fetch with Callback - -With a piecewise callback fetch DBD::Oracle sets up a function that will 'callback' to the DB during the fetch and gets your LOB (LONG, LONG RAW, CLOB, BLOB) piece by piece. -To use this interface set the 'ora\_clbk\_lob' attribute of the statement handle to '1' with the prepare method. Next set the 'ora\_piece\_size' to the size of the piece that -you want to return on the callback. Finally set the database handle's 'LongReadLen' attribute to a value that will be larger than the expected -size of the LOB. Like the ["Simple Fetch for LONGs and LONG RAWs"](#simple-fetch-for-longs-and-long-raws) and ["Simple Fetch for CLOBs and BLOBs"](#simple-fetch-for-clobs-and-blobs) the if the size of the LOB exceeds 'LongReadLen' you can use the 'LongTruncOk' attribute to truncate the LOB -or set 'LongReadLen' to a higher value. With this interface the value of 'ora\_piece\_size' seems to be constrained by the same memory limit as found on -the Simple Fetch interface. If you encounter an 'ORA-01062' error try setting the value of 'ora\_piece\_size' to a smaller value. The value for 'LongReadLen' is -dependent on the version and settings of the Oracle DB you are using. In theory it ranges from 8GBs -in 9iR1 up to 128 terabytes with 11g but you will also be limited by the physical memory of your PERL instance. - -Using the table from the last example this code; - - $dbh->{LongReadLen} = 20*1024*1024; #20 meg - $SQL='select p_id,lob_1,lob_2,blob_2 from test_lobs'; - $sth=$dbh->prepare($SQL,{ora_clbk_lob=>1,ora_piece_size=>5*1024*1024}); - $sth->execute(); - while (my ( $p_id,$log,$log2,$log3,$log4 )=$sth->fetchrow()){ - print "p_id=".$p_id."\n"; - print "clob1=".$clob1."\n"; - print "clob2=".$clob2."\n"; - print "blob1=".$blob2."\n"; - print "blob2=".$blob2."\n"; - } - -Will select out all of the LOBs in the table as long as they are all under 20MB in length. If the LOB is longer than 5MB (ora\_piece\_size) DBD::Oracle will fetch it in at least 2 pieces to a -maximum of 4 pieces (4\*5MB=20MB). Like the Simple Fetch examples Lobs longer than 20MB will throw an error. - -Using the table from the first example (LONG) this code; - - $dbh->{LongReadLen} = 20*1024*1024; #2 meg - $SQL='select p_id,long1 from test_long'; - $sth=$dbh->prepare($SQL,{ora_clbk_lob=>1,ora_piece_size=>5*1024*1024}); - $sth->execute(); - while (my ( $p_id,$long )=$sth->fetchrow()){ - print "p_id=".$p_id."\n"; - print "long=".$long."\n"; - } - -Will select all of the long1 fields from table as long as they are is under 20MB in length. If the long1 filed is longer than 5MB (ora\_piece\_size) DBD::Oracle will fetch it in at least 2 pieces to a -maximum of 4 pieces (4\*5MB=20MB). Like the other examples long1 fields longer than 20MB will throw an error. - -#### Piecewise Fetch with Polling - -With a polling piecewise fetch DBD::Oracle iterates (Polls) over the LOB during the fetch getting your LOB (LONG, LONG RAW, CLOB, BLOB) piece by piece. To use this interface set the 'ora\_piece\_lob' -attribute of the statement handle to '1' with the prepare method. Next set the 'ora\_piece\_size' to the size of the piece that -you want to return on the callback. Finally set the database handle's 'LongReadLen' attribute to a value that will be larger than the expected -size of the LOB. Like the ["Piecewise Fetch with Callback"](#piecewise-fetch-with-callback) and Simple Fetches if the size of the LOB exceeds 'LongReadLen' you can use the 'LongTruncOk' attribute to truncate the LOB -or set 'LongReadLen' to a higher value. With this interface the value of 'ora\_piece\_size' seems to be constrained by the same memory limit as found on -the ["Piecewise Fetch with Callback"](#piecewise-fetch-with-callback). - -Using the table from the example above this code; - - $dbh->{LongReadLen} = 20*1024*1024; #20 meg - $SQL='select p_id,lob_1,lob_2,blob_2 from test_lobs'; - $sth=$dbh->prepare($SQL,{ora_piece_lob=>1,ora_piece_size=>5*1024*1024}); - $sth->execute(); - while (my ( $p_id,$log,$log2,$log3,$log4 )=$sth->fetchrow()){ - print "p_id=".$p_id."\n"; - print "clob1=".$clob1."\n"; - print "clob2=".$clob2."\n"; - print "blob1=".$blob2."\n"; - print "blob2=".$blob2."\n"; - } - -Will select out all of the LOBs in the table as long as they are all under 20MB in length. If the LOB is longer than 5MB (ora\_piece\_size) DBD::Oracle will fetch it in at least 2 pieces to a -maximum of 4 pieces (4\*5MB=20MB). Like the other fetch methods LOBs longer than 20MB will throw an error. - -Finally with this code; - - $dbh->{LongReadLen} = 20*1024*1024; #2 meg - $SQL='select p_id,long1 from test_long'; - $sth=$dbh->prepare($SQL,{ora_piece_lob=>1,ora_piece_size=>5*1024*1024}); - $sth->execute(); - while (my ( $p_id,$long )=$sth->fetchrow()){ - print "p_id=".$p_id."\n"; - print "long=".$long."\n"; - } - -Will select all of the long1 fields from table as long as they are is under 20MB in length. If the long1 field is longer than 5MB (ora\_piece\_size) DBD::Oracle will fetch it in at least 2 pieces to a -maximum of 4 pieces (4\*5MB=20MB). Like the other examples long1 fields longer than 20MB will throw an error. - -### Binding for Updates and Inserts for CLOBs and BLOBs - -To bind for updates and inserts all that is required to use this interface is to set the statement handle's prepare method -'ora\_type' attribute to 'SQLT\_CHR' in the case of CLOBs and NCLOBs or 'SQLT\_BIN' in the case of BLOBs as in this example for an insert; - - my $in_clob = "<document>\n"; - $in_clob .= " <value>$_</value>\n" for 1 .. 10_000; - $in_clob .= "</document>\n"; - my $in_blob ="0101" for 1 .. 10_000; - - $SQL='insert into test_lob3@tpgtest (id,clob1,clob2, blob1,blob2) values(?,?,?,?,?)'; - $sth=$dbh->prepare($SQL ); - $sth->bind_param(1,3); - $sth->bind_param(2,$in_clob,{ora_type=>SQLT_CHR}); - $sth->bind_param(3,$in_clob,{ora_type=>SQLT_CHR}); - $sth->bind_param(4,$in_blob,{ora_type=>SQLT_BIN}); - $sth->bind_param(5,$in_blob,{ora_type=>SQLT_BIN}); - $sth->execute(); - -So far the only limit reached with this form of insert is the LOBs must be under 2GB in size. - -### Support for Remote LOBs; - -Starting with Oracle 10gR2 the interface for Persistent LOBs was expanded to support remote LOBs (access over a dblink). Given a database called 'lob\_test' that has a 'LINK' defined like this; - - CREATE DATABASE LINK link_test CONNECT TO test_lobs IDENTIFIED BY tester USING 'lob_test'; - -to a remote database called 'test\_lobs', the following code will work; - - $dbh = DBI->connect('dbi:Oracle:','test@lob_test','test'); - $dbh->{LongReadLen} = 2*1024*1024; #2 meg - $SQL='select p_id,lob_1,lob_2,blob_2 from test_lobs@link_test'; - $sth=$dbh->prepare($SQL,{ora_pers_lob=>1}); - $sth->execute(); - while (my ( $p_id,$log,$log2,$log3,$log4 )=$sth->fetchrow()){ - print "p_id=".$p_id."\n"; - print "clob1=".$clob1."\n"; - print "clob2=".$clob2."\n"; - print "blob1=".$blob2."\n"; - print "blob2=".$blob2."\n"; - } - -Below are the limitations of Remote LOBs; - -- Queries involving more than one database are not supported; - - so the following returns an error: - - SELECT t1.lobcol, - a2.lobcol - FROM t1, - t2.lobcol@dbs2 a2 W - WHERE LENGTH(t1.lobcol) = LENGTH(a2.lobcol); - - as does: - - SELECT t1.lobcol - FROM t1@dbs1 - UNION ALL - SELECT t2.lobcol - FROM t2@dbs2; - -- DDL commands are not supported; - - so the following returns an error: - - CREATE VIEW v AS SELECT lob_col FROM tab@dbs; - -- Only binds and defines for data going into remote persistent LOBs are supported. - - so that parameter passing in PL/SQL where CHAR data is bound or defined for remote LOBs is not allowed . - - These statements all produce errors: - - SELECT foo() FROM table1@dbs2; - - SELECT foo()@dbs INTO char_val FROM DUAL; - - SELECT XMLType().getclobval FROM table1@dbs2; - -- If the remote object is a view such as - - CREATE VIEW v AS SELECT foo() FROM ... - - the following would not work: - - SELECT * FROM v@dbs2; - -- Limited PL/SQL parameter passing - - PL/SQL parameter passing is not allowed where the actual argument is a LOB type - and the remote argument is one of VARCHAR2, NVARCHAR2, CHAR, NCHAR, or RAW. - -- RETURNING INTO does not support implicit conversions between CHAR and CLOB. - - so the following returns an error: - - SELECT t1.lobcol as test, a2.lobcol FROM t1, t2.lobcol@dbs2 a2 RETURNING test - -## Locator Data Interface - -### Simple Usage - -When fetching LOBs with this interface a 'LOB Locator' is created then used to get the lob with the LongReadLen and LongTruncOk attributes. -The value for 'LongReadLen' is dependent on the version and settings of the Oracle DB you are using. In theory it ranges from 8GBs -in 9iR1 up to 128 terabytes with 11g but you will also be limited by the physical memory of your PERL instance. - -When inserting or updating LOBs some _major_ magic has to be performed -behind the scenes to make it transparent. Basically the driver has to -insert a 'LOB Locator' and then refetch the newly inserted LOB -Locator before being able to write the data into it. However, it works -well most of the time, and I've made it as fast as possible, just one -extra server-round-trip per insert or update after the first. For the -time being, only single-row LOB updates are supported. - -To insert or update a large LOB using a placeholder, DBD::Oracle has to -know in advance that it is a LOB type. So you need to say: - - $sth->bind_param($field_num, $lob_value, { ora_type => ORA_CLOB }); - -The ORA\_CLOB and ORA\_BLOB constants can be imported using - - use DBD::Oracle qw(:ora_types); - -or use the corresponding integer values (112 and 113). - -One further wrinkle: for inserts and updates of LOBs, DBD::Oracle has -to be able to tell which parameters relate to which table fields. -In all cases where it can possibly work it out for itself, it does, -however, if there are multiple LOB fields of the same type in the table -then you need to tell it which field each LOB param relates to: - - $sth->bind_param($idx, $value, { ora_type=>ORA_CLOB, ora_field=>'foo' }); - -There are some limitations inherent in the way DBD::Oracle makes typical -LOB operations simple by hiding the LOB Locator processing: - - - Can't read/write LOBs in chunks (except via DBMS_LOB.WRITEAPPEND in PL/SQL) - - To INSERT a LOB, you need UPDATE privilege. - -The alternative is to disable the automatic LOB Locator processing. -If ["ora\_auto\_lob"](#ora_auto_lob) is 0 in prepare(), you can fetch the LOB Locators and -do all the work yourself using the ora\_lob\_\*() methods. -See the ["Data Interface for LOB Locators"](#data-interface-for-lob-locators) section below. - -### LOB support in PL/SQL - -LOB Locators can be passed to PL/SQL calls by binding them to placeholders -with the proper `ora_type`. If ["ora\_auto\_lob"](#ora_auto_lob) is true, output LOB -parameters will be automatically returned as strings. - -If the Oracle driver has support for temporary LOBs (Oracle 9i and higher), -strings can be bound to input LOB placeholders and will be automatically -converted to LOBs. - -Example: - # Build a large XML document, bind it as a CLOB, - # extract elements through PL/SQL and return as a CLOB - - # $dbh is a connected database handle - # output will be large - - local $dbh->{LongReadLen} = 1_000_000; - - my $in_clob = "<document>\n"; - $in_clob .= " <value>$_</value>\n" for 1 .. 10_000; - $in_clob .= "</document>\n"; - - my $out_clob; - - - my $sth = $dbh->prepare(<<PLSQL_END); - -- extract 'value' nodes - DECLARE - x XMLTYPE := XMLTYPE(:in); - BEGIN - :out := x.extract('/document/value').getClobVal(); - END; - - PLSQL_END - - # :in param will be converted to a temp lob - # :out parameter will be returned as a string. - - $sth->bind_param( ':in', $in_clob, { ora_type => ORA_CLOB } ); - $sth->bind_param_inout( ':out', \$out_clob, 0, { ora_type => ORA_CLOB } ); - $sth->execute; - -If you ever get an - - ORA-01691 unable to extend lob segment sss.ggg by nnn in tablespace ttt - -error, while attempting to insert a LOB, this means the Oracle user has insufficient space for LOB you are trying to insert. -One solution it to use "alter database datafile 'sss.ggg' resize Mnnn" to increase the available memory for LOBs. - -## Persistent & Locator Interface Caveats - -Now that one has the option of using the Persistent or the Locator interface for LOBs the questions arises -which one to use. For starters, if you want to access LOBs over a dblink you will have to use the Persistent -interface so that choice is simple. The question of which one to use after that is a little more tricky. -It basically boils down to a choice between LOB size and speed. - -The Callback and Polling piecewise fetches are very very slow -when compared to the Simple and the Locator fetches but they can handle very large blocks of data. Given a situation where a -large LOB is to be read the Locator fetch may time out while either of the piecewise fetches may not. - -With the Simple fetch you are limited by physical memory of your server but it runs a little faster than the Locator, as there are fewer round trips -to the server. So if you have small LOBs and need to save a little bandwidth this is the one to use. It you are going after large LOBs then the Locator interface is the one to use. - -If you need to update more than a single row of with LOB data then the Persistent interface can do it while the Locator can't. - -If you encounter a situation where you have to access the legacy LOBs (LONG, LONG RAW) and the values are to large for you system then you can use -the Callback or Polling piecewise fetches to get all of the data. - -Not all of the Persistent interface has been implemented yet, the following are not supported; - - 1) Piecewise, polling and callback binds for INSERT and UPDATE operations. - 2) Piecewise array binds for SELECT, INSERT and UPDATE operations. - -Most of the time you should just use the ["Locator Data Interface"](#locator-data-interface) as this is in one that has the best combination of speed and size. - -All this being said if you are doing some critical programming I would use the ["Data Interface for LOB Locators"](#data-interface-for-lob-locators) as this gives you very -fine grain control of your LOBs, of course the code for this will be somewhat more involved. - -## Data Interface for LOB Locators - -The following driver-specific methods let you manipulate "LOB Locators" directly. -To select a LOB locator directly set the if the `ora_auto_lob` -attribute to false, or alternatively they can be returned via PL/SQL procedure calls. - -(If using a DBI version earlier than 1.36 they must be called via the -func() method. Note that methods called via func() don't honour -RaiseError etc, and so it's important to check $dbh->err after each call. -It's recommended that you upgrade to DBI 1.38 or later.) - -Note that LOB locators are only valid while the statement handle that -created them is valid. When all references to the original statement -handle are lost, the handle is destroyed and the locators are freed. - -- ora\_lob\_read - - $data = $dbh->ora_lob_read($lob_locator, $offset, $length); - - Read a portion of the LOB. $offset starts at 1. - Uses the Oracle OCILobRead function. - - NOTE: DBD::Oracle post 1.46 will return undef for any read lob if the - length specified in the ora\_lob\_read is 0. See RT 55028. This avoids - the potential problem with empty lobs (created with empty\_clob) which - return a length of 0 from ora\_lob\_length and prior to 1.46 a call to - ora\_lob\_read with a 0 length would segfault. - -- ora\_lob\_write - - $rc = $dbh->ora_lob_write($lob_locator, $offset, $data); - - Write/overwrite a portion of the LOB. $offset starts at 1. - Uses the Oracle OCILobWrite function. - -- ora\_lob\_append - - $rc = $dbh->ora_lob_append($lob_locator, $data); - - Append $data to the LOB. Uses the Oracle OCILobWriteAppend function. - -- ora\_lob\_trim - - $rc = $dbh->ora_lob_trim($lob_locator, $length); - - Trims the length of the LOB to $length. - Uses the Oracle OCILobTrim function. - -- ora\_lob\_length - - $length = $dbh->ora_lob_length($lob_locator); - - Returns the length of the LOB. - Uses the Oracle OCILobGetLength function. - -- ora\_lob\_is\_init - - $is_init = $dbh->ora_lob_is_init($lob_locator); - - Returns true(1) if the Lob Locator is initialized false(0) if it is not, or 'undef' - if there is an error. - Uses the Oracle OCILobLocatorIsInit function. - -- ora\_lob\_chunk\_size - - $chunk_size = $dbh->ora_lob_chunk_size($lob_locator); - - Returns the chunk size of the LOB. - Uses the Oracle OCILobGetChunkSize function. - - For optimal performance, Oracle recommends reading from and - writing to a LOB in batches using a multiple of the LOB chunk size. - In Oracle 10g and before, when all defaults are in place, this - chunk size defaults to 8k (8192). - -### LOB Locator Method Examples - -_Note:_ Make sure you first read the note in the section above about -multi-byte character set issues with these methods. - -The following examples demonstrate the usage of LOB Locators -to read, write, and append data, and to query the size of -large data. - -The following examples assume a table containing two large -object columns, one binary and one character, with a primary -key column, defined as follows: - - CREATE TABLE lob_example ( - lob_id INTEGER PRIMARY KEY, - bindata BLOB, - chardata CLOB - ) - -It also assumes a sequence for use in generating unique -lob\_id field values, defined as follows: - - CREATE SEQUENCE lob_example_seq - -### Example: Inserting a new row with large data - -Unless enough memory is available to store and bind the -entire LOB data for insert all at once, the LOB columns must -be written interactively, piece by piece. In the case of a new row, -this is performed by first inserting a row, with empty values in -the LOB columns, then modifying the row by writing the large data -interactively to the LOB columns using their LOB locators as handles. - -The insert statement must create token values in the LOB -columns. Here, we use the empty string for both the binary -and character large object columns 'bindata' and 'chardata'. - -After the INSERT statement, a SELECT statement is used to -acquire LOB locators to the 'bindata' and 'chardata' fields -of the newly inserted row. Because these LOB locators are -subsequently written, they must be acquired from a select -statement containing the clause 'FOR UPDATE' (LOB locators -are only valid within the transaction that fetched them, so -can't be used effectively if AutoCommit is enabled). - - my $lob_id = $dbh->selectrow_array( <<" SQL" ); - SELECT lob_example_seq.nextval FROM DUAL - SQL - - my $sth = $dbh->prepare( <<" SQL" ); - INSERT INTO lob_example - ( lob_id, bindata, chardata ) - VALUES ( ?, EMPTY_BLOB(),EMPTY_CLOB() ) - SQL - $sth->execute( $lob_id ); - - $sth = $dbh->prepare( <<" SQL", { ora_auto_lob => 0 } ); - SELECT bindata, chardata - FROM lob_example - WHERE lob_id = ? - FOR UPDATE - SQL - $sth->execute( $lob_id ); - my ( $bin_locator, $char_locator ) = $sth->fetchrow_array(); - $sth->finish(); - - open BIN_FH, "/binary/data/source" or die; - open CHAR_FH, "/character/data/source" or die; - my $chunk_size = $dbh->ora_lob_chunk_size( $bin_locator ); - - # BEGIN WRITING BIN_DATA COLUMN - my $offset = 1; # Offsets start at 1, not 0 - my $length = 0; - my $buffer = ''; - while( $length = read( BIN_FH, $buffer, $chunk_size ) ) { - $dbh->ora_lob_write( $bin_locator, $offset, $buffer ); - $offset += $length; - } - - # BEGIN WRITING CHAR_DATA COLUMN - $chunk_size = $dbh->ora_lob_chunk_size( $char_locator ); - $offset = 1; # Offsets start at 1, not 0 - $length = 0; - $buffer = ''; - while( $length = read( CHAR_FH, $buffer, $chunk_size ) ) { - $dbh->ora_lob_write( $char_locator, $offset, $buffer ); - $offset += $length; - } - -In this example we demonstrate the use of ora\_lob\_write() -interactively to append data to the columns 'bin\_data' and -'char\_data'. Had we used ora\_lob\_append(), we could have -saved ourselves the trouble of keeping track of the offset -into the lobs. The snippet of code beneath the comment -'BEGIN WRITING BIN\_DATA COLUMN' could look as follows: - - my $buffer = ''; - while ( read( BIN_FH, $buffer, $chunk_size ) ) { - $dbh->ora_lob_append( $bin_locator, $buffer ); - } - -The scalar variables $offset and $length are no longer -needed, because ora\_lob\_append() keeps track of the offset -for us. - -### Example: Updating an existing row with large data - -In this example, we demonstrate a technique for overwriting -a portion of a blob field with new binary data. The blob -data before and after the section overwritten remains -unchanged. Hence, this technique could be used for updating -fixed length subfields embedded in a binary field. - - my $lob_id = 5; # Arbitrary row identifier, for example - - $sth = $dbh->prepare( <<" SQL", { ora_auto_lob => 0 } ); - SELECT bindata - FROM lob_example - WHERE lob_id = ? - FOR UPDATE - SQL - $sth->execute( $lob_id ); - my ( $bin_locator ) = $sth->fetchrow_array(); - - my $offset = 100234; - my $data = "This string will overwrite a portion of the blob"; - $dbh->ora_lob_write( $bin_locator, $offset, $data ); - -After running this code, the row where lob\_id = 5 will -contain, starting at position 100234 in the bin\_data column, -the string "This string will overwrite a portion of the blob". - -### Example: Streaming character data from the database - -In this example, we demonstrate a technique for streaming -data from the database to a file handle, in this case -STDOUT. This allows more data to be read in and written out -than could be stored in memory at a given time. - - my $lob_id = 17; # Arbitrary row identifier, for example - - $sth = $dbh->prepare( <<" SQL", { ora_auto_lob => 0 } ); - SELECT chardata - FROM lob_example - WHERE lob_id = ? - SQL - $sth->execute( $lob_id ); - my ( $char_locator ) = $sth->fetchrow_array(); - - my $chunk_size = 1034; # Arbitrary chunk size, for example - my $offset = 1; # Offsets start at 1, not 0 - while(1) { - my $data = $dbh->ora_lob_read( $char_locator, $offset, $chunk_size ); - last unless length $data; - print STDOUT $data; - $offset += $chunk_size; - } - -Notice that the select statement does not contain the phrase -"FOR UPDATE". Because we are only reading from the LOB -Locator returned, and not modifying the LOB it refers to, -the select statement does not require the "FOR UPDATE" -clause. - -A word of caution when using the data returned from an ora\_lob\_read in a conditional statement. -for example if the code below; - - while( my $data = $dbh->ora_lob_read( $char_locator, $offset, $chunk_size ) ) { - print STDOUT $data; - $offset += $chunk_size; - } - -was used with a chunk size of 4096 against a blob that requires more than 1 chunk to return -the data and the last chunk is one byte long and contains a zero (ASCII 48) you will miss this last byte -as $data will contain 0 which PERL will see as false and not print it out. - -### Example: Truncating existing large data - -In this example, we truncate the data already present in a -large object column in the database. Specifically, for each -row in the table, we truncate the 'bindata' value to half -its previous length. - -After acquiring a LOB Locator for the column, we query its -length, then we trim the length by half. Because we modify -the large objects with the call to ora\_lob\_trim(), we must -select the LOB locators 'FOR UPDATE'. - - my $sth = $dbh->prepare( <<" SQL", { ora_auto_lob => 0 } ); - SELECT bindata - FROM lob_example - FOR UPATE - SQL - $sth->execute(); - while( my ( $bin_locator ) = $sth->fetchrow_array() ) { - my $binlength = $dbh->ora_lob_length( $bin_locator ); - if( $binlength > 0 ) { - $dbh->ora_lob_trim( $bin_locator, $binlength/2 ); - } - } - -# SPACES AND PADDING - -## Trailing Spaces - -Only the Oracle OCI 8 strips trailing spaces from VARCHAR placeholder -values and uses Nonpadded Comparison Semantics with the result. -This causes trouble if the spaces are needed for -comparison with a CHAR value or to prevent the value from -becoming '' which Oracle treats as NULL. -Look for Blank-padded Comparison Semantics and Nonpadded -Comparison Semantics in Oracle's SQL Reference or Server -SQL Reference for more details. - -To preserve trailing spaces in placeholder values for Oracle clients that use OCI 8, -either change the default placeholder type with ["ora\_ph\_type"](#ora_ph_type) or the placeholder -type for a particular call to ["bind" in DBI](https://metacpan.org/pod/DBI#bind) or ["bind\_param\_inout" in DBI](https://metacpan.org/pod/DBI#bind_param_inout) -with ["ora\_type"](#ora_type) or `TYPE`. -Using [ORA\_CHAR](https://metacpan.org/pod/ORA_CHAR) with [ora\_type](https://metacpan.org/pod/ora_type) or `SQL_CHAR` with `TYPE` -allows the placeholder to be used with Padded Comparison Semantics -if the value it is being compared to is a CHAR, NCHAR, or literal. - -Please remember that using spaces as a value or at the end of -a value makes visually distinguishing values with different -numbers of spaces difficult and should be avoided. - -Oracle Clients that use OCI 9.2 do not strip trailing spaces. - -## Padded Char Fields - -Oracle Clients after OCI 9.2 will automatically pad CHAR placeholder values to the size of the CHAR. -As the default placeholder type value in DBD::Oracle is ORA\_VARCHAR2 to access this behaviour you will -have to change the default placeholder type with ["ora\_ph\_type"](#ora_ph_type) or placeholder -type for a particular call with ["bind" in DBI](https://metacpan.org/pod/DBI#bind) or ["bind\_param\_inout" in DBI](https://metacpan.org/pod/DBI#bind_param_inout) -with ["ORA\_CHAR"](#ora_char). - -# UNICODE - -DBD::Oracle now supports Unicode UTF-8. There are, however, a number -of issues you should be aware of, so please read all this section -carefully. - -In this section we'll discuss "Perl and Unicode", then "Oracle and -Unicode", and finally "DBD::Oracle and Unicode". - -Information about Unicode in general can be found at: -[http://www.unicode.org/](http://www.unicode.org/). It is well worth reading because there are -many misconceptions about Unicode and you may be holding some of them. - -## Perl and Unicode - -Perl began implementing Unicode with version 5.6, but the implementation -did not mature until version 5.8 and later. If you plan to use Unicode -you are _strongly_ urged to use Perl 5.8.2 or later and to _carefully_ read -the Perl documentation on Unicode: - - perldoc perluniintro # in Perl 5.8 or later - perldoc perlunicode - -And then read it again. - -Perl's internal Unicode format is UTF-8 -which corresponds to the Oracle character set called AL32UTF8. - -## Oracle and Unicode - -Oracle supports many characters sets, including several different forms -of Unicode. These include: - - AL16UTF16 => valid for NCHAR columns (CSID=2000) - UTF8 => valid for NCHAR columns (CSID=871), deprecated - AL32UTF8 => valid for NCHAR and CHAR columns (CSID=873) - -When you create an Oracle database, you must specify the DATABASE -character set (used for DDL, DML and CHAR datatypes) and the NATIONAL -character set (used for NCHAR and NCLOB types). -The character sets used in your database can be found using: - - $hash_ref = $dbh->ora_nls_parameters() - $database_charset = $hash_ref->{NLS_CHARACTERSET}; - $national_charset = $hash_ref->{NLS_NCHAR_CHARACTERSET}; - -The Oracle 9.2 and later default for the national character set is AL16UTF16. -The default for the database character set is often US7ASCII. -Although many experienced DBAs will consider an 8bit character set like -WE8ISO8859P1 or WE8MSWIN1252. To use any character set with Oracle -other than US7ASCII, requires that the NLS\_LANG environment variable be set. -See the ["Oracle UTF8 is not UTF-8"](#oracle-utf8-is-not-utf-8) section below. - -You are strongly urged to read the Oracle Internationalization documentation -specifically with respect the choices and trade offs for creating -a databases for use with international character sets. - -Oracle uses the NLS\_LANG environment variable to indicate what -character set is being used on the client. When fetching data Oracle -will convert from whatever the database character set is to the client -character set specified by NLS\_LANG. Similarly, when sending data to -the database Oracle will convert from the character set specified by -NLS\_LANG to the database character set. - -The NLS\_NCHAR environment variable can be used to define a different -character set for 'national' (NCHAR) character types. - -Both UTF8 and AL32UTF8 can be used in NLS\_LANG and NLS\_NCHAR. -For example: - - NLS_LANG=AMERICAN_AMERICA.UTF8 - NLS_LANG=AMERICAN_AMERICA.AL32UTF8 - NLS_NCHAR=UTF8 - NLS_NCHAR=AL32UTF8 - -## Oracle UTF8 is not UTF-8 - -AL32UTF8 should be used in preference to UTF8 if it works for you, -which it should for Oracle 9.2 or later. If you're using an old -version of Oracle that doesn't support AL32UTF8 then you should -avoid using any Unicode characters that require surrogates, in other -words characters beyond the Unicode BMP (Basic Multilingual Plane). - -That's because the character set that Oracle calls "UTF8" doesn't -conform to the UTF-8 standard in its handling of surrogate characters. -Technically the encoding that Oracle calls "UTF8" is known as "CESU-8". -Here are a couple of extracts from [http://www.unicode.org/reports/tr26/](http://www.unicode.org/reports/tr26/): - - CESU-8 is useful in 8-bit processing environments where binary - collation with UTF-16 is required. It is designed and recommended - for use only within products requiring this UTF-16 binary collation - equivalence. It is not intended nor recommended for open interchange. - - As a very small percentage of characters in a typical data stream - are expected to be supplementary characters, there is a strong - possibility that CESU-8 data may be misinterpreted as UTF-8. - Therefore, all use of CESU-8 outside closed implementations is - strongly discouraged, such as the emittance of CESU-8 in output - files, markup language or other open transmission forms. - -Oracle uses this internally because it collates (sorts) in the same order -as UTF16, which is the basis of Oracle's internal collation definitions. - -Rather than change UTF8 for clients Oracle chose to define a new character -set called "AL32UTF8" which does conform to the UTF-8 standard. -(The AL32UTF8 character set can't be used on the server because it -would break collation.) - -Because of that, for the rest of this document we'll use "AL32UTF8". -If you're using an Oracle version below 9.2 you'll need to use "UTF8" -until you upgrade. - -## DBD::Oracle and Unicode - -DBD::Oracle Unicode support has been implemented for Oracle versions 9 -or greater, and Perl version 5.6 or greater (though we _strongly_ -suggest that you use Perl 5.8.2 or later). - -You can check which Oracle version your DBD::Oracle was built with by -importing the `ORA_OCI` constant from DBD::Oracle. - -**Fetching Data** - -Any data returned from Oracle to DBD::Oracle in the AL32UTF8 -character set will be marked as UTF-8 to ensure correct handling by Perl. - -For Oracle to return data in the AL32UTF8 character set the -NLS\_LANG or NLS\_NCHAR environment variable _must_ be set as described -in the previous section. - -When fetching NCHAR, NVARCHAR, or NCLOB data from Oracle, DBD::Oracle -will set the Perl UTF-8 flag on the returned data if either NLS\_NCHAR -is AL32UTF8, or NLS\_NCHAR is not set and NLS\_LANG is AL32UTF8. - -When fetching other character data from Oracle, DBD::Oracle -will set the Perl UTF-8 flag on the returned data if NLS\_LANG is AL32UTF8. - -**Sending Data using Placeholders** - -Data bound to a placeholder is assumed to be in the default client -character set (specified by NLS\_LANG) except for a few special -cases. These are listed here with the highest precedence first: - -If the `ora_csid` attribute is given to bind\_param() then that -is passed to Oracle and takes precedence. - -If the value is a Perl Unicode string (UTF-8) then DBD::Oracle -ensures that Oracle uses the Unicode character set, regardless of -the NLS\_LANG and NLS\_NCHAR settings. - -If the placeholder is for inserting an NCLOB then the client NLS\_NCHAR -character set is used. (That's useful but inconsistent with the other behaviour -so may change. Best to be explicit by using the `ora_csform` -attribute.) - -If the `ora_csform` attribute is given to bind\_param() then that -determines if the value should be assumed to be in the default -(NLS\_LANG) or NCHAR (NLS\_NCHAR) client character set. - - use DBD::Oracle qw( SQLCS_IMPLICIT SQLCS_NCHAR ); - ... - $sth->bind_param(1, $value, { ora_csform => SQLCS_NCHAR }); - -or - - $dbh->{ora_ph_csform} = SQLCS_NCHAR; # default for all future placeholders - -Binding with bind\_param\_array and execute\_array is also UTF-8 compatible in the same way. If you attempt to -insert UTF-8 data into a non UTF-8 Oracle instance or with an non UTF-8 NCHAR or NVARCHAR the insert -will still happen but a error code of 0 will be returned with the following warning; - - DBD Oracle Warning: You have mixed utf8 and non-utf8 in an array bind in parameter#1. This may result in corrupt data. - The Query charset id=1, name=US7ASCII - -The warning will report the parameter number and the NCHAR setting that the query is running. - -**Sending Data using SQL** - -Oracle assumes the SQL statement is in the default client character -set (as specified by NLS\_LANG). So Unicode strings containing -non-ASCII characters should not be used unless the default client -character set is AL32UTF8. - -## DBD::Oracle and Other Character Sets and Encodings - -The only multi-byte Oracle character set supported by DBD::Oracle is -"AL32UTF8" (and "UTF8"). Single-byte character sets should work well. - -# OBJECT & COLLECTION DATA TYPES - -Oracle databases allow for the creation of object oriented like user-defined types. -There are two types of objects, Embedded--an object stored in a column of a regular table -and REF--an object that uses the REF retrieval mechanism. - -DBD::Oracle supports only the 'selection' of embedded objects of the following types OBJECT, VARRAY -and TABLE in any combination. Support is seamless and recursive, meaning you -need only supply a simple SQL statement to get all the values in an embedded object. -You can either get the values as an array of scalars or they can be returned into a DBD::Oracle::Object. - -Array example, given this type and table; - - CREATE OR REPLACE TYPE "PHONE_NUMBERS" as varray(10) of varchar(30); - - CREATE TABLE "CONTACT" - ( "COMPANYNAME" VARCHAR2(40), - "ADDRESS" VARCHAR2(100), - "PHONE_NUMBERS" "PHONE_NUMBERS" - ) - -The code to access all the data in the table could be something like this; - - my $sth = $dbh->prepare('SELECT * FROM CONTACT'); - $sth->execute; - while ( my ($company, $address, $phone) = $sth->fetchrow()) { - print "Company: ".$company."\n"; - print "Address: ".$address."\n"; - print "Phone #: "; - - foreach my $items (@$phone){ - print $items.", "; - } - print "\n"; - } - -Note that values in PHONE\_NUMBERS are returned as an array reference '@$phone'. - -As stated before DBD::Oracle will automatically drill into the embedded object and extract -all of the data as reference arrays of scalars. The example below has OBJECT type embedded in a TABLE type embedded in an -SQL TABLE; - - CREATE OR REPLACE TYPE GRADELIST AS TABLE OF NUMBER; - - CREATE OR REPLACE TYPE STUDENT AS OBJECT( - NAME VARCHAR2(60), - SOME_GRADES GRADELIST); - - CREATE OR REPLACE TYPE STUDENTS_T AS TABLE OF STUDENT; - - CREATE TABLE GROUPS( - GRP_ID NUMBER(4), - GRP_NAME VARCHAR2(10), - STUDENTS STUDENTS_T) - NESTED TABLE STUDENTS STORE AS GROUP_STUDENTS_TAB - (NESTED TABLE SOME_GRADES STORE AS GROUP_STUDENT_GRADES_TAB); - -The following code will access all of the embedded data; - - $SQL='select grp_id,grp_name,students as my_students_test from groups'; - $sth=$dbh->prepare($SQL); - $sth->execute(); - while (my ($grp_id,$grp_name,$students)=$sth->fetchrow()){ - print "Group ID#".$grp_id." Group Name =".$grp_name."\n"; - foreach my $student (@$students){ - print "Name:".$student->[0]."\n"; - print "Marks:"; - foreach my $grades (@$student->[1]){ - foreach my $marks (@$grades){ - print $marks.","; - } - } - print "\n"; - } - print "\n"; - } - -Object example, given this object and table; - - CREATE OR REPLACE TYPE Person AS OBJECT ( - name VARCHAR2(20), - age INTEGER) - ) NOT FINAL; - - CREATE TYPE Employee UNDER Person ( - salary NUMERIC(8,2) - ); - - CREATE TABLE people (id INTEGER, obj Person); - - INSERT INTO people VALUES (1, Person('Black', 25)); - INSERT INTO people VALUES (2, Employee('Smith', 44, 5000)); - -The following code will access the data; - - $dbh{'ora_objects'} =>1; - - $sth = $dbh->prepare("select * from people order by id"); - $sth->execute(); - - # object are fetched as instance of DBD::Oracle::Object - my ($id1, $obj1) = $sth->fetchrow(); - my ($id2, $obj2) = $sth->fetchrow(); - - # get full type-name of object - print $obj1->type_name."44\n"; # 'TEST.PERSON' is printed - print $obj2->type_name."4\n"; # 'TEST.EMPLOYEE' is printed - - # get attribute NAME from object - print $obj1->attr('NAME')."3\n"; # 'Black' is printed - print $obj2->attr('NAME')."3\n"; # 'Smith' is printed - - # get all attributes as hash reference - my $h1 = $obj1->attr; # returns {'NAME' => 'Black', 'AGE' => 25} - my $h2 = $obj2->attr; # returns {'NAME' => 'Smith', 'AGE' => 44, - # 'SALARY' => 5000 } - - # get all attributes (names and values) as array - my @a1 = $obj1->attributes; # returns ('NAME', 'Black', 'AGE', 25) - my @a2 = $obj2->attributes; # returns ('NAME', 'Smith', 'AGE', 44, - # 'SALARY', 5000 ) - -So far DBD::Oracle has been tested on a table with 20 embedded Objects, Varrays and Tables -nested to 10 levels. - -Any NULL values found in the embedded object will be returned as 'undef'. - -# OTHER DATA TYPES - -DBD::Oracle does not _explicitly_ support most Oracle datatypes. -It simply asks Oracle to return them as strings and Oracle does so. -Mostly. Similarly when binding placeholder values DBD::Oracle binds -them as strings and Oracle converts them to the appropriate type, -such as DATE, when used. - -Some of these automatic conversions to and from strings use NLS -settings to control the formatting for output and the parsing for -input. The most common example is the DATE type. The default NLS -format for DATE might be DD-MON-YYYY and so when a DATE type is -fetched that's how Oracle will format the date. NLS settings also -control the default parsing of strings into DATE values. An error -will be generated if the contents of the string don't match the -NLS format. If you're dealing in dates which don't match the default -NLS format then you can either change the default NLS format or, more -commonly, use TO\_CHAR(field, "format") and TO\_DATE(?, "format") -to explicitly specify formats for converting to and from strings. - -A slightly more subtle problem can occur with NUMBER types. The -default NLS settings might format numbers with a fullstop ("`.`") -to separate thousands and a comma ("`,`") as the decimal point. -Perl will generate warnings and use incorrect values when numbers, -returned and formatted as strings in this way by Oracle, are used -in a numeric context. You could explicitly convert each numeric -value using the TO\_CHAR(...) function but that gets tedious very -quickly. The best fix is to change the NLS settings. That can be -done for an individual connection by doing: - - $dbh->do("ALTER SESSION SET NLS_NUMERIC_CHARACTERS = '.,'"); - -There are some types, like BOOLEAN, that Oracle does not automatically -convert to or from strings (pity). These need to be converted -explicitly using SQL or PL/SQL functions. - -Examples: - - # DATE values - my $sth0 = $dbh->prepare( <<SQL_END ); - SELECT username, TO_CHAR( created, ? ) - FROM all_users - WHERE created >= TO_DATE( ?, ? ) - SQL_END - $sth0->execute( 'YYYY-MM-DD HH24:MI:SS', "2003", 'YYYY' ); - - # BOOLEAN values - my $sth2 = $dbh->prepare( <<PLSQL_END ); - DECLARE - b0 BOOLEAN; - b1 BOOLEAN; - o0 VARCHAR2(32); - o1 VARCHAR2(32); - - FUNCTION to_bool( i VARCHAR2 ) RETURN BOOLEAN IS - BEGIN - IF i IS NULL THEN RETURN NULL; - ELSIF i = 'F' OR i = '0' THEN RETURN FALSE; - ELSE RETURN TRUE; - END IF; - END; - FUNCTION from_bool( i BOOLEAN ) RETURN NUMBER IS - BEGIN - IF i IS NULL THEN RETURN NULL; - ELSIF i THEN RETURN 1; - ELSE RETURN 0; - END IF; - END; - BEGIN - -- Converting values to BOOLEAN - b0 := to_bool( :i0 ); - b1 := to_bool( :i1 ); - - -- Converting values from BOOLEAN - :o0 := from_bool( b0 ); - :o1 := from_bool( b1 ); - END; - PLSQL_END - my ( $i0, $i1, $o0, $o1 ) = ( "", "Something else" ); - $sth2->bind_param( ":i0", $i0 ); - $sth2->bind_param( ":i1", $i1 ); - $sth2->bind_param_inout( ":o0", \$o0, 32 ); - $sth2->bind_param_inout( ":o1", \$o1, 32 ); - $sth2->execute(); - foreach ( $i0, $b0, $o0, $i1, $b1, $o1 ) { - $_ = "(undef)" if ! defined $_; - } - print "$i0 to $o0, $i1 to $o1\n"; - # Result is : "'' to '(undef)', 'Something else' to '1'" - -## Support for Insert of XMLType (ORA\_XMLTYPE) - -Inserting large XML data sets into tables with XMLType fields is now supported by DBD::Oracle. The only special -requirement is the use of bind\_param() with an attribute hash parameter that specifies ora\_type as ORA\_XMLTYPE. For -example with a table like this; - - create table books (book_id number, book_xml XMLType); - -one can insert data using this code - - $SQL='insert into books values (1,:p_xml)'; - $xml= '<Books> - <Book id=1> - <Title>Programming the Perl DBI</Title> - <Subtitle>The Cheetah Book</Subtitle> - <Authors> - <Author>T. Bunce</Author> - <Author>Alligator Descartes</Author> - </Authors> - - </Book> - <Book id=10000>... - </Books>'; - my $sth =$dbh-> prepare($SQL); - $sth-> bind_param("p_xml", $xml, { ora_type => ORA_XMLTYPE }); - $sth-> execute(); - -In the above case we will assume that $xml has 10000 Book nodes and is over 32k in size and is well formed XML. -This will also work for XML that is smaller than 32k as well. Attempting to insert malformed XML will cause an error. - -## Binding Cursors - -Cursors can be returned from PL/SQL blocks, either from stored -functions (or procedures with OUT parameters) or -from direct `OPEN` statements, as shown below: - - use DBI; - use DBD::Oracle qw(:ora_types); - my $dbh = DBI->connect(...); - my $sth1 = $dbh->prepare(q{ - BEGIN OPEN :cursor FOR - SELECT table_name, tablespace_name - FROM user_tables WHERE tablespace_name = :space; - END; - }); - $sth1->bind_param(":space", "USERS"); - my $sth2; - $sth1->bind_param_inout(":cursor", \$sth2, 0, { ora_type => ORA_RSET } ); - $sth1->execute; - # $sth2 is now a valid DBI statement handle for the cursor - while ( my @row = $sth2->fetchrow_array ) { ... } - -The only special requirement is the use of `bind_param_inout()` with an -attribute hash parameter that specifies `ora_type` as `ORA_RSET`. -If you don't do that you'll get an error from the `execute()` like: -"ORA-06550: line X, column Y: PLS-00306: wrong number or types of -arguments in call to ...". - -Here's an alternative form using a function that returns a cursor. -This example uses the pre-defined weak (or generic) REF CURSOR type -SYS\_REFCURSOR. This is an Oracle 9 feature. - - # Create the function that returns a cursor - $dbh->do(q{ - CREATE OR REPLACE FUNCTION sp_ListEmp RETURN SYS_REFCURSOR - AS l_cursor SYS_REFCURSOR; - BEGIN - OPEN l_cursor FOR select ename, empno from emp - ORDER BY ename; - RETURN l_cursor; - END; - }); - - # Use the function that returns a cursor - my $sth1 = $dbh->prepare(q{BEGIN :cursor := sp_ListEmp; END;}); - my $sth2; - $sth1->bind_param_inout(":cursor", \$sth2, 0, { ora_type => ORA_RSET } ); - $sth1->execute; - # $sth2 is now a valid DBI statement handle for the cursor - while ( my @row = $sth2->fetchrow_array ) { ... } - -A cursor obtained from PL/SQL as above may be passed back to PL/SQL -by binding for input, as shown in this example, which explicitly -closes a cursor: - - my $sth3 = $dbh->prepare("BEGIN CLOSE :cursor; END;"); - $sth3->bind_param(":cursor", $sth2, { ora_type => ORA_RSET } ); - $sth3->execute; - -It is not normally necessary to close a cursor explicitly in this -way. Oracle will close the cursor automatically at the first -client-server interaction after the cursor statement handle is -destroyed. An explicit close may be desirable if the reference to the -cursor handle from the PL/SQL statement handle delays the destruction -of the cursor handle for too long. This reference remains until the -PL/SQL handle is re-bound, re-executed or destroyed. - -NOTE: From DBD::Oracle 1.57 functions or procedures returning -SYS\_REFCURSORs which have not been opened (are still in the -initialised state) will return undef for the cursor statement handle -e.g., in the example above if the sp\_ListEmp function simply returned l\_cursor -instead of opening it. This means you can have a function/procedure -which can elect to open the cursor or not, Before this change if you called -a function/procedure which returned a SYS\_REFCURSOR which was not opened -DBD::Oracle would error in the execute for a OCIAttrGet on the uninitialised -cursor. - -See the `curref.pl` script in the Oracle.ex directory in the DBD::Oracle -source distribution for a complete working example. - -## Fetching Nested Cursors - -Oracle supports the use of select list expressions of type REF CURSOR. -These may be explicit cursor expressions - `CURSOR(SELECT ...)`, or -calls to PL/SQL functions which return REF CURSOR values. The values -of these expressions are known as nested cursors. - -The value returned to a Perl program when a nested cursor is fetched -is a statement handle. This statement handle is ready to be fetched from. -It should not (indeed, must not) be executed. - -Oracle imposes a restriction on the order of fetching when nested -cursors are used. Suppose `$sth1` is a handle for a select statement -involving nested cursors, and `$sth2` is a nested cursor handle fetched -from `$sth1`. `$sth2` can only be fetched from while `$sth1` is -still active, and the row containing `$sth2` is still current in `$sth1`. -Any attempt to fetch another row from `$sth1` renders all nested cursor -handles previously fetched from `$sth1` defunct. - -Fetching from such a defunct handle results in an error with the message -`ERROR nested cursor is defunct (parent row is no longer current)`. - -This means that the `fetchall...` or `selectall...` methods are not useful -for queries returning nested cursors. By the time such a method returns, -all the nested cursor handles it has fetched will be defunct. - -It is necessary to use an explicit fetch loop, and to do all the -fetching of nested cursors within the loop, as the following example -shows: - - use DBI; - my $dbh = DBI->connect(...); - my $sth = $dbh->prepare(q{ - SELECT dname, CURSOR( - SELECT ename FROM emp - WHERE emp.deptno = dept.deptno - ORDER BY ename - ) FROM dept ORDER BY dname - }); - $sth->execute; - while ( my ($dname, $nested) = $sth->fetchrow_array ) { - print "$dname\n"; - while ( my ($ename) = $nested->fetchrow_array ) { - print " $ename\n"; - } - } - -The cursor returned by the function `sp_ListEmp` defined in the -previous section can be fetched as a nested cursor as follows: - - my $sth = $dbh->prepare(q{SELECT sp_ListEmp FROM dual}); - $sth->execute; - my ($nested) = $sth->fetchrow_array; - while ( my @row = $nested->fetchrow_array ) { ... } - -## Pre-fetching Nested Cursors - -By default, DBD::Oracle pre-fetches rows in order to reduce the number of -round trips to the server. For queries which do not involve nested cursors, -the number of pre-fetched rows is controlled by the DBI database handle -attribute `RowCacheSize` (q.v.). - -In Oracle, server side open cursors are a controlled resource, limited in -number, on a per session basis, to the value of the initialization -parameter `OPEN_CURSORS`. Nested cursors count towards this limit. -Each nested cursor in the current row counts 1, as does -each nested cursor in a pre-fetched row. Defunct nested cursors do not count. - -An Oracle specific database handle attribute, `ora_max_nested_cursors`, -further controls pre-fetching for queries involving nested cursors. For -each statement handle, the total number of nested cursors in pre-fetched -rows is limited to the value of this parameter. The default value -is 0, which disables pre-fetching for queries involving nested cursors. - -# PL/SQL Examples - -Most of these PL/SQL examples come from: Eric Bartley <bartley@cc.purdue.edu>. - - /* - * PL/SQL to create package with stored procedures invoked by - * Perl examples. Execute using sqlplus. - * - * Use of "... OR REPLACE" prevents failure in the event that the - * package already exists. - */ - - CREATE OR REPLACE PACKAGE plsql_example - IS - PROCEDURE proc_np; - - PROCEDURE proc_in ( - err_code IN NUMBER - ); - - PROCEDURE proc_in_inout ( - test_num IN NUMBER, - is_odd IN OUT NUMBER - ); - - FUNCTION func_np - RETURN VARCHAR2; - - END plsql_example; - / - - CREATE OR REPLACE PACKAGE BODY plsql_example - IS - PROCEDURE proc_np - IS - whoami VARCHAR2(20) := NULL; - BEGIN - SELECT USER INTO whoami FROM DUAL; - END; - - PROCEDURE proc_in ( - err_code IN NUMBER - ) - IS - BEGIN - RAISE_APPLICATION_ERROR(err_code, 'This is a test.'); - END; - - PROCEDURE proc_in_inout ( - test_num IN NUMBER, - is_odd IN OUT NUMBER - ) - IS - BEGIN - is_odd := MOD(test_num, 2); - END; - - FUNCTION func_np - RETURN VARCHAR2 - IS - ret_val VARCHAR2(20); - BEGIN - SELECT USER INTO ret_val FROM DUAL; - RETURN ret_val; - END; - - END plsql_example; - / - /* End PL/SQL for example package creation. */ - - use DBI; - - my($db, $csr, $ret_val); - - $db = DBI->connect('dbi:Oracle:database','user','password') - or die "Unable to connect: $DBI::errstr"; - - # So we don't have to check every DBI call we set RaiseError. - # See the DBI docs now if you're not familiar with RaiseError. - $db->{RaiseError} = 1; - - # Example 1 Eric Bartley <bartley@cc.purdue.edu> - # - # Calling a PLSQL procedure that takes no parameters. This shows you the - # basic's of what you need to execute a PLSQL procedure. Just wrap your - # procedure call in a BEGIN END; block just like you'd do in SQL*Plus. - # - # p.s. If you've used SQL*Plus's exec command all it does is wrap the - # command in a BEGIN END; block for you. - - $csr = $db->prepare(q{ - BEGIN - PLSQL_EXAMPLE.PROC_NP; - END; - }); - $csr->execute; - - - # Example 2 Eric Bartley <bartley@cc.purdue.edu> - # - # Now we call a procedure that has 1 IN parameter. Here we use bind_param - # to bind out parameter to the prepared statement just like you might - # do for an INSERT, UPDATE, DELETE, or SELECT statement. - # - # I could have used positional placeholders (e.g. :1, :2, etc.) or - # ODBC style placeholders (e.g. ?), but I prefer Oracle's named - # placeholders (but few DBI drivers support them so they're not portable). - - my $err_code = -20001; - - $csr = $db->prepare(q{ - BEGIN - PLSQL_EXAMPLE.PROC_IN(:err_code); - END; - }); - - $csr->bind_param(":err_code", $err_code); - - # PROC_IN will RAISE_APPLICATION_ERROR which will cause the execute to 'fail'. - # Because we set RaiseError, the DBI will croak (die) so we catch that with eval. - eval { - $csr->execute; - }; - print 'After proc_in: $@=',"'$@', errstr=$DBI::errstr, ret_val=$ret_val\n"; - - - # Example 3 Eric Bartley <bartley@cc.purdue.edu> - # - # Building on the last example, I've added 1 IN OUT parameter. We still - # use a placeholders in the call to prepare, the difference is that - # we now call bind_param_inout to bind the value to the place holder. - # - # Note that the third parameter to bind_param_inout is the maximum size - # of the variable. You normally make this slightly larger than necessary. - # But note that the Perl variable will have that much memory assigned to - # it even if the actual value returned is shorter. - - my $test_num = 5; - my $is_odd; - - $csr = $db->prepare(q{ - BEGIN - PLSQL_EXAMPLE.PROC_IN_INOUT(:test_num, :is_odd); - END; - }); - - # The value of $test_num is _copied_ here - $csr->bind_param(":test_num", $test_num); - - $csr->bind_param_inout(":is_odd", \$is_odd, 1); - - # The execute will automagically update the value of $is_odd - $csr->execute; - - print "$test_num is ", ($is_odd) ? "odd - ok" : "even - error!", "\n"; - - - # Example 4 Eric Bartley <bartley@cc.purdue.edu> - # - # What about the return value of a PLSQL function? Well treat it the same - # as you would a call to a function from SQL*Plus. We add a placeholder - # for the return value and bind it with a call to bind_param_inout so - # we can access its value after execute. - - my $whoami = ""; - - $csr = $db->prepare(q{ - BEGIN - :whoami := PLSQL_EXAMPLE.FUNC_NP; - END; - }); - - $csr->bind_param_inout(":whoami", \$whoami, 20); - $csr->execute; - print "Your database user name is $whoami\n"; - - $db->disconnect; - -You can find more examples in the t/plsql.t file in the DBD::Oracle -source directory. - -Oracle 9.2 appears to have a bug where a variable bound -with bind\_param\_inout() that isn't assigned to by the executed -PL/SQL block may contain garbage. -See [http://www.mail-archive.com/dbi-users@perl.org/msg18835.html](http://www.mail-archive.com/dbi-users@perl.org/msg18835.html) - -## Avoid Using "SQL Call" - -Avoid using the "SQL Call" statement with DBD:Oracle as you might find that -DBD::Oracle will not raise an exception in some case. Specifically if you use -"SQL Call" to run a procedure all "No data found" exceptions will be quietly -ignored and returned as null. According to Oracle support this is part of the same -mechanism where; - - select (select * from dual where 0=1) from dual - -returns a null value rather than an exception. - -# CONTRIBUTING - -If you'd like DBD::Oracle to do something new or different the best way -to make that happen is to do it yourself and email to dbi-dev@perl.org a -patch of the source code (using 'diff' - see below) that shows the changes. - -## Speak before you patch - -For anything non-trivial or possibly controversial it's a good idea -to discuss (on dbi-dev@perl.org) the changes you propose before -actually spending time working on them. Otherwise you run the risk -of them being rejected because they don't fit into some larger plans -you may not be aware of. - -# WHICH VERSION OF DBD::ORACLE IS FOR ME? - -From version 1.25 onwards DBD::Oracle only support Oracle clients -9.2 or greater. Support for ProC connections was dropped in 1.29. - -If you are still stuck with an older version of Oracle or its client you might want to look at the table below. - - +---------------------+-----------------------------------------------------+ - | | Oracle Version | - +---------------------+----+-------------+---------+------+--------+--------+ - | DBD::Oracle Version | <8 | 8.0.3~8.0.6 | 8iR1~R2 | 8iR3 | 9i | 9.2~11 | - +---------------------+----+-------------+---------+------+--------+--------+ - | 0.1~16 | Y | Y | Y | Y | Y | Y | - +---------------------+----+-------------+---------+------+--------+--------+ - | 1.17 | Y | Y | Y | Y | Y | Y | - +---------------------+----+-------------+---------+------+--------+--------+ - | 1.18 | N | N | N | Y | Y | Y | - +---------------------+----+-------------+---------+------+--------+--------+ - | 1.19 | N | N | N | Y | Y | Y | - +---------------------+----+-------------+---------+------+--------+--------+ - | 1.20 | N | N | N | Y | Y | Y | - +---------------------+----+-------------+---------+------+--------+--------+ - | 1.21~1.24 | N | N | N | N | Y | Y | - +---------------------+----+-------------+---------+------+--------+--------+ - | 1.25+ | N | N | N | N | N | Y | - +---------------------+----+-------------+---------+------+--------+--------+ - -As there are dozens of different versions of Oracle's clients this -list does not include all of them, just the major released versions of -Oracle. - -Note that one can still connect to any Oracle version with the older -DBD::Oracle versions the only problem you will have is that some of -the newer OCI and Oracle features available in later DBD::Oracle -releases will not be available to you. - -So to make a short story a little longer: - -1. If you are using Oracle 7 or early 8 DB and you can manage to get a 9 client and you can use -any DBD::Oracle version. -2. If you have to use an Oracle 7 client then DBD::Oracle 1.17 should work -3. Same thing for 8 up to R2, use 1.17, if you are lucky and have the right patch-set you might -go with 1.18. -4. For 8iR3 you can use any of the DBD::Oracle versions up to 1.21. Again this depends on your -patch-set, If you run into trouble go with 1.19 -5. After 9.2 you can use any version you want. -6. It seems that the 10g client can only connect to 9 and 11 DBs while the 9 can go back to 7 -and even get to 10. I am not sure what the 11g client can connect to. - -# SEE ALSO - -- [DBI](https://metacpan.org/pod/DBI) - - http://search.cpan.org/~timb/DBD-Oracle/MANIFEST for all files in - the DBD::Oracle source distribution including the examples in the - Oracle.ex directory - -- DBD::Oracle Tutorial - - http://www.pythian.com/blogs/wp-content/uploads/introduction-dbd-oracle.html - -- Oracle Instant Client - - http://www.oracle.com/technology/tech/oci/instantclient/index.html - -- Oracle on Linux - - http://www.ixora.com.au/ - -- Free Oracle Tools and Links - - ora\_explain supplied and installed with DBD::Oracle. - - http://www.orafaq.com/ - - http://vonnieda.org/oracletool/ - -- Commercial Oracle Tools and Links - - Assorted tools and references for general information. - No recommendation implied. - - http://www.platinum.com - - http://www.SoftTreeTech.com - - Also PL/Vision from RevealNet and Steven Feuerstein, and - "Q" from Savant Corporation. - -# AUTHORS - -DBI by Tim Bunce [http://www.tim.bunce.name](http://www.tim.bunce.name). - -The original `DBD::Oracle` was by Tim Bunce. -Maintained as of release 1.17 (February 2006) by John Scoles, then Yanick Champoux, under the -auspice of the Pythian Group ([http://www.pythian.com](http://www.pythian.com)). - -# ACKNOWLEDGEMENTS - -A great many people have helped with DBD::Oracle over the 17 years -between 1994 and 2011. Far too many to name, but we thank them all. -Many are named in the Changes file. - -# COPYRIGHT - -The DBD::Oracle module is Copyright (c) 1994-2006 Tim Bunce. Ireland. -The DBD::Oracle module is Copyright (c) 2006-2011 John Scoles (The Pythian Group). Canada. -The DBD::Oracle module is Copyright (c) 2011 John Scoles. Canada. - -The DBD::Oracle module is free open source software; you can -redistribute it and/or modify it under the same terms as Perl 5. - -# AUTHORS - -- Tim Bunce <timb@cpan.org> -- John Scoles <byterock@cpan.org> -- Yanick Champoux <yanick@cpan.org> -- Martin J. Evans <mjevans@cpan.org> - -# COPYRIGHT AND LICENSE - -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. - -This is free software; you can redistribute it and/or modify it under -the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/TESTING.md libdbd-oracle-perl-1.83/TESTING.md --- libdbd-oracle-perl-1.80/TESTING.md 1970-01-01 00:00:00.000000000 +0000 +++ libdbd-oracle-perl-1.83/TESTING.md 2022-01-17 02:06:35.000000000 +0000 @@ -0,0 +1,64 @@ +# Variables used in tests + +**Connecting to Oracle** + +`ORACLE_USERID` - important + +Which user & password to use when running tests against a real Oracle database + +Should be 'user/password' or a longer string with connection details. + +``` bash +$ export ORACLE_USERID='scott/tiger' +``` + +`ORACLE_USERID_2` + +Provides a second set of user credentials when needed + +`ORACLE_DSN` + +DSN details when connecting to real Oracle for tests + +``` bash +$ export ORACLE_DSN='dbi:Oracle:testdb' +``` + +`DBI_DSN` + +If `ORACLE_DSN` is not provided, this will be used. Otherwise falls back to internal default. + +**Creation of tables, views, functions etc** + +`DBD_ORACLE_SEQ` - important + +Appended to table, view, function (etc) that are created during testing to help +prevent collisions + +`DBD_SKIP_TABLE_DROP` + +Skips dropping temporary tables when tests complete. Use to examine the mess after failed tests. + +**Other** + +`NLS_DATE_FORMAT` + +Sets the date format as normal + +# Test all script + +The mkta.pl script might be useful as for testing against multiple DB's quickly + +# Vars that need more detail + +`NLS_NCHAR` + +`NLS_LANG` + +??? + +`DBI_USER` + +`DBI_PASS` + +`DBD_ALL_TESTS` - Forces some tests to run, that otherwise wouldn't diff -Nru libdbd-oracle-perl-1.80/cpanfile libdbd-oracle-perl-1.83/cpanfile --- libdbd-oracle-perl-1.80/cpanfile 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/cpanfile 2022-01-17 02:06:35.000000000 +0000 @@ -1,10 +1,18 @@ -requires "DBI" => "0"; +# This file is generated by Dist::Zilla::Plugin::CPANFile v6.024 +# Do not edit this file directly. To change prereqs, edit the `dist.ini` file. + +requires "DBI" => "1.623"; +requires "Data::Dumper" => "0"; requires "DynaLoader" => "0"; requires "Exporter" => "0"; -requires "perl" => "5.006"; +requires "perl" => "5.008"; requires "strict" => "0"; requires "warnings" => "0"; +on 'build' => sub { + requires "Config" => "0"; +}; + on 'test' => sub { requires "B" => "0"; requires "Carp" => "0"; @@ -21,8 +29,11 @@ requires "Test::NoWarnings" => "0"; requires "Thread::Semaphore" => "0"; requires "lib" => "0"; + requires "perl" => "5.008"; + requires "strict" => "0"; requires "utf8" => "0"; requires "vars" => "0"; + requires "warnings" => "0"; }; on 'test' => sub { @@ -30,18 +41,16 @@ }; on 'configure' => sub { - requires "Config" => "0"; - requires "DBI" => "1.623"; - requires "Data::Dumper" => "0"; - requires "Devel::Peek" => "0"; - requires "Encode" => "0"; requires "ExtUtils::MakeMaker" => "0"; - requires "Math::BigInt" => "0"; - requires "Test::More" => "0"; - requires "Test::NoWarnings" => "0"; + requires "perl" => "5.006"; +}; + +on 'configure' => sub { + suggests "JSON::PP" => "2.27300"; }; on 'develop' => sub { + requires "DBI" => "1.623"; requires "Pod::Coverage::TrustPod" => "0"; requires "Test::CPAN::Meta" => "0"; requires "Test::EOF" => "0"; @@ -50,6 +59,7 @@ requires "Test::More" => "0.88"; requires "Test::NoBreakpoints" => "0.15"; requires "Test::NoTabs" => "0"; + requires "Test::NoWarnings" => "0"; requires "Test::Pod" => "1.41"; requires "Test::Pod::Coverage" => "1.08"; requires "Test::Portability::Files" => "0"; diff -Nru libdbd-oracle-perl-1.80/dbdimp.c libdbd-oracle-perl-1.83/dbdimp.c --- libdbd-oracle-perl-1.80/dbdimp.c 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/dbdimp.c 2022-01-17 02:06:35.000000000 +0000 @@ -210,8 +210,8 @@ /* We rely on the DBI dispatcher to destroy all child handles before we get here (DBI >= 1.623). */ - if (imp_drh->leak_state) { - /* With ithreads, we can't tell when the last dr handle is destroyed. */ + if (imp_drh->leak_handles) { + /* By using ithread, handles will leak in dbd_dr_destroy() */ return; } @@ -568,8 +568,8 @@ shared_dbh = NULL ; } - /* With ithreads, we can't tell when the last dr handle is destroyed. */ - imp_drh->leak_state = 1; + /* By using ithread, handles will leak in dbd_dr_destroy() */ + imp_drh->leak_handles = 1; } #endif @@ -583,7 +583,7 @@ imp_dbh->envhp = NULL; /* force new environment */ } } - /* RT46739 */ + /* Test if a cached environment handle it still usable (see RT46739) */ if (imp_dbh->envhp) { OCIHandleAlloc_ok(imp_dbh, imp_dbh->envhp, &imp_dbh->errhp, OCI_HTYPE_ERROR, status); if (status != OCI_SUCCESS) { @@ -1287,8 +1287,8 @@ D_imp_dbh(dbh); D_imp_drh_from_dbh; - /* With ithreads, we can't tell when the last dr handle is destroyed. */ - imp_drh->leak_state = 1; + /* By using ithread, handles will leak in dbd_dr_destroy() */ + imp_drh->leak_handles = 1; /* Indicate that SUPER::take_imp_data should be called. */ return &PL_sv_no; diff -Nru libdbd-oracle-perl-1.80/dbdimp.h libdbd-oracle-perl-1.83/dbdimp.h --- libdbd-oracle-perl-1.80/dbdimp.h 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/dbdimp.h 2022-01-17 02:06:35.000000000 +0000 @@ -11,17 +11,21 @@ typedef struct taf_callback_st taf_callback_t; struct taf_callback_st { - SV *function; /*User supplied TAF functiomn*/ - SV *dbh_ref; + SV *function; /*User supplied TAF function*/ + SV *dbh_ref; }; typedef struct imp_fbh_st imp_fbh_t; +/* Define implementation specific driver handle data structure */ struct imp_drh_st { dbih_drc_t com; /* MUST be first element in structure */ - OCIEnv *envhp; - bool leak_state; + OCIEnv *envhp; /* global environment handler, see also */ + /* connect attr ora_envhp */ + bool leak_handles; /* shared dbh's will leak handles in */ + /* dbd_dr_destroy(), see connect attr */ + /* ora_dbh_share for more information */ #ifdef ORA_OCI_112 HV *charset_hv; HV *pool_hv; @@ -44,7 +48,7 @@ }; #endif -/* Define dbh implementor data structure */ +/* Define implementation specific database handle data structure */ struct imp_dbh_st { dbih_dbc_t com; /* MUST be first element in structure */ @@ -55,7 +59,9 @@ #endif void *(*get_oci_handle) _((imp_dbh_t *imp_dbh, int handle_type, int flags)); - OCIEnv *envhp; /* copy of drh pointer */ + OCIEnv *envhp; /* session environment handler, this is mostly */ + /* a copy of imp_drh->envhp, see also connect */ + /* attr ora_envhp */ OCIError *errhp; OCIServer *srvhp; OCISvcCtx *svchp; @@ -101,7 +107,7 @@ typedef struct lob_refetch_st lob_refetch_t; /* Define sth implementor data structure */ -/*statement structure */ +/* Define implementation specific statement data structure */ struct imp_sth_st { dbih_stc_t com; /* MUST be first element in structure */ diff -Nru libdbd-oracle-perl-1.80/debian/README.Debian libdbd-oracle-perl-1.83/debian/README.Debian --- libdbd-oracle-perl-1.80/debian/README.Debian 2019-10-06 17:21:27.000000000 +0000 +++ libdbd-oracle-perl-1.83/debian/README.Debian 2023-02-26 23:34:45.000000000 +0000 @@ -2,19 +2,20 @@ ----------------------------- To install this package, you need to install the Oracle Instant Client. -This can be downloaded free of cost but an "Oracle Account" is required: +This can be downloaded free of cost (an "Oracle Account" is no longer +required): -<http://www.oracle.com/technetwork/database/database-technologies/instant-client/downloads/index.html> +<https://www.oracle.com/database/technologies/instant-client/downloads.html> Click to "Instant Client for Linux x86-64" (amd64) or -"Instant Client for Linux x86" (i386), accept the license -agreement for Instant Client and get the RPM package (no other -architectures are supported): +"Instant Client for Linux x86" (i386), and get the RPM package (please, +note that Instant Client packages no longer include the release number +as part of the RPM name since release 21): -- Basic (oracle-instantclient12.1-basic-*.rpm) +- Basic (oracle-instantclient-basic-*.rpm) Optional: You can use Basic-Lite instead of Basic - (oracle-instantclient12.1-basiclite-*.rpm) + (oracle-instantclient-basiclite-*.rpm) Make sure you have these packages installed to convert the RPM files to Debian: @@ -24,12 +25,13 @@ Convert them to Debian packages: -$ fakeroot alien oracle-instantclient12.1-*.rpm +$ fakeroot alien --scripts oracle-instantclient-*.rpm Install them as root: -# dpkg -i oracle-instantclient12.1-*.deb +# dpkg -i oracle-instantclient-*.deb and then you are ready to install this package. -- Julián Moreno Patiño <darkjunix@gmail.com> Mon, 07 Jun 2010 01:17:27 -0500 + -- Alex Muntada <alexm@debian.org> Sun, 26 Feb 2023 18:16:49 +0100 diff -Nru libdbd-oracle-perl-1.80/debian/README.source libdbd-oracle-perl-1.83/debian/README.source --- libdbd-oracle-perl-1.80/debian/README.source 2020-11-10 00:12:16.000000000 +0000 +++ libdbd-oracle-perl-1.83/debian/README.source 2023-02-26 23:34:45.000000000 +0000 @@ -4,7 +4,7 @@ To build this package, you need to install the Oracle Instant Client Basic (or Basic-Lite) and SDK: -- SDK (oracle-instantclient12.1-devel-*.rpm) +- SDK (oracle-instantclient-devel-*.rpm) and then you are ready to build this package. @@ -12,7 +12,7 @@ -- Peter Eisentraut, Feb. 2008 -- Julián Moreno Patiño, Jun. 2010-2012 --- Alex Muntada, Nov 2018, 2019 +-- Alex Muntada, Nov 2018, 2019, 2023 If and only if you are uploading this package as Debian Maintainer (DM, not DD), you will need to upload all architectures in one upload, diff -Nru libdbd-oracle-perl-1.80/debian/changelog libdbd-oracle-perl-1.83/debian/changelog --- libdbd-oracle-perl-1.80/debian/changelog 2022-10-24 15:17:33.000000000 +0000 +++ libdbd-oracle-perl-1.83/debian/changelog 2023-02-26 23:34:45.000000000 +0000 @@ -1,3 +1,13 @@ +libdbd-oracle-perl (1.83-1) unstable; urgency=medium + + * Import upstream version 1.83 + * Remove patch already applied upstream: + + build-without-ld-libray-path.patch + * Update Oracle Instant Client dependencies (Closes: 1016992) + * Declare compliance with Debian Policy 4.6.2.0 + + -- Alex Muntada <alexm@debian.org> Sun, 26 Feb 2023 23:34:45 +0000 + libdbd-oracle-perl (1.80-4) unstable; urgency=medium * Declare compliance with Debian Policy 4.6.1.0 diff -Nru libdbd-oracle-perl-1.80/debian/control libdbd-oracle-perl-1.83/debian/control --- libdbd-oracle-perl-1.80/debian/control 2022-10-24 15:17:33.000000000 +0000 +++ libdbd-oracle-perl-1.83/debian/control 2023-02-26 23:34:45.000000000 +0000 @@ -6,11 +6,11 @@ Build-Depends: debhelper-compat (= 13), dh-sequence-perl-dbi, libdbi-perl, - oracle-instantclient12.1-basic, - oracle-instantclient12.1-devel, + oracle-instantclient-basic, + oracle-instantclient-devel, perl-xs-dev, perl:native -Standards-Version: 4.6.1.0 +Standards-Version: 4.6.2.0 Vcs-Browser: https://salsa.debian.org/perl-team/modules/packages/libdbd-oracle-perl Vcs-Git: https://salsa.debian.org/perl-team/modules/packages/libdbd-oracle-perl.git Homepage: https://metacpan.org/release/DBD-Oracle @@ -20,7 +20,7 @@ Architecture: any Depends: libaio1, libdbi-perl, - oracle-instantclient12.1-basic | oracle-instantclient12.1-basiclite, + oracle-instantclient-basic | oracle-instantclient-basiclite, ${misc:Depends}, ${perl:Depends}, ${shlibs:Depends} diff -Nru libdbd-oracle-perl-1.80/debian/copyright libdbd-oracle-perl-1.83/debian/copyright --- libdbd-oracle-perl-1.80/debian/copyright 2022-02-08 14:50:59.000000000 +0000 +++ libdbd-oracle-perl-1.83/debian/copyright 2023-02-26 23:34:45.000000000 +0000 @@ -5,7 +5,7 @@ Comment: The upstream Perl distribution is freely licensed by the copyright holders but depends on Oracle Instant Client software, that is not free. Therefore, it belongs to Debian contrib section - according to DFSG. + according to Debian Policy §2.2.2. Files: * Copyright: 1994-2006, Tim Bunce. Ireland. @@ -21,7 +21,7 @@ Copyright: 2007, 2008, Peter Eisentraut <petere@debian.org> 2010-2012, Julián Moreno Patiño <darkjunix@gmail.com> 2010-2013, gregor herrmann <gregoa@debian.org> - 2016-2022, Alex Muntada <alexm@debian.org> + 2016-2023, Alex Muntada <alexm@debian.org> License: Artistic or GPL-1+ License: Artistic diff -Nru libdbd-oracle-perl-1.80/debian/patches/build-without-ld-libray-path.patch libdbd-oracle-perl-1.83/debian/patches/build-without-ld-libray-path.patch --- libdbd-oracle-perl-1.80/debian/patches/build-without-ld-libray-path.patch 2020-11-12 17:46:08.000000000 +0000 +++ libdbd-oracle-perl-1.83/debian/patches/build-without-ld-libray-path.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -Description: Build DBD::Oracle on Debian systems without LD_LIBRARY_PATH -Author: Slaven Rezić <eserte> -Author: Wesley Hinds <whindsx> -Origin: upstream -Bug: https://github.com/perl5-dbi/DBD-Oracle/issues/72 - ---- a/Makefile.PL -+++ b/Makefile.PL -@@ -1114,6 +1114,9 @@ - $linkwith =~ m/-lcl\b/ or - $syslibs =~ s/\s*-lcl\b//g; - } -+ if (lc(@Config{qw(myuname)}) =~ /debian/) { -+ $syslibs .= " -Wl,--no-as-needed -lnnz12 -lons -lclntshcore -lipc1 -lmql1"; -+ } - return $syslibs; - } - diff -Nru libdbd-oracle-perl-1.80/debian/patches/series libdbd-oracle-perl-1.83/debian/patches/series --- libdbd-oracle-perl-1.80/debian/patches/series 2022-02-08 14:03:03.000000000 +0000 +++ libdbd-oracle-perl-1.83/debian/patches/series 2023-02-26 23:34:45.000000000 +0000 @@ -1,2 +1 @@ fix-spelling-errors.patch -build-without-ld-libray-path.patch diff -Nru libdbd-oracle-perl-1.80/debian/rules libdbd-oracle-perl-1.83/debian/rules --- libdbd-oracle-perl-1.80/debian/rules 2022-02-08 14:03:03.000000000 +0000 +++ libdbd-oracle-perl-1.83/debian/rules 2023-02-26 23:34:45.000000000 +0000 @@ -11,6 +11,7 @@ PKG=$(shell dh_listpackages) TMP=$(CURDIR)/debian/$(PKG) +VERSION = $(shell dpkg-query -Wf '$${source:Upstream-Version}' oracle-instantclient-devel) ORACLE_HEADERS = $(wildcard /usr/include/oracle/*/client*) @@ -18,7 +19,7 @@ override_dh_auto_test: override_dh_auto_configure: - dh_auto_configure -- -h $(ORACLE_HEADERS) -V 12.1.0.1.0 + dh_auto_configure -- -h $(ORACLE_HEADERS) -V $(VERSION) override_dh_installexamples: dh_installexamples @@ -27,5 +28,5 @@ override_dh_shlibdeps: dh_shlibdeps - sed -i -e 's/oracle-instantclient12.1-basic/oracle-instantclient12.1-basic | oracle-instantclient12.1-basiclite/' \ + sed -i -e 's/oracle-instantclient-basic/oracle-instantclient-basic | oracle-instantclient-basiclite/' \ $(CURDIR)/debian/libdbd-oracle-perl.substvars diff -Nru libdbd-oracle-perl-1.80/doap.xml libdbd-oracle-perl-1.83/doap.xml --- libdbd-oracle-perl-1.80/doap.xml 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/doap.xml 1970-01-01 00:00:00.000000000 +0000 @@ -1,442 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<Project - xmlns="http://usefulinc.com/ns/doap#" - xmlns:dc="http://purl.org/dc/terms/" - xmlns:foaf="http://xmlns.com/foaf/0.1/" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" - > - <name>DBD-Oracle</name> - <shortdesc>Oracle database driver for the DBI module</shortdesc> - <developer> - <foaf:Person> - <foaf:name>Tim Bunce</foaf:name> - <foaf:mbox rdf:resource="mailto:timb@cpan.org" /> - </foaf:Person> - </developer> - <developer> - <foaf:Person> - <foaf:name>John Scoles</foaf:name> - <foaf:mbox rdf:resource="mailto:byterock@cpan.org" /> - </foaf:Person> - </developer> - <developer> - <foaf:Person> - <foaf:name>Yanick Champoux</foaf:name> - <foaf:mbox rdf:resource="mailto:yanick@cpan.org" /> - </foaf:Person> - </developer> - <developer> - <foaf:Person> - <foaf:name>Martin J. Evans</foaf:name> - <foaf:mbox rdf:resource="mailto:mjevans@cpan.org" /> - </foaf:Person> - </developer> - <helper> - <foaf:Person> - <foaf:name>Aaron Crane</foaf:name> - <foaf:mbox rdf:resource="mailto:arc@cpan.org" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Alice Maz</foaf:name> - <foaf:mbox rdf:resource="mailto:alice@alicemaz.com" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Carsten Grohmann</foaf:name> - <foaf:mbox rdf:resource="mailto:mail@carstengrohmann.de" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>cjardine</foaf:name> - <foaf:mbox rdf:resource="mailto:cjardine@50811bd7-b8ce-0310-adc1-d9db26280581" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Dag Lem</foaf:name> - <foaf:mbox rdf:resource="mailto:dag@nimrod.no" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>David E. Wheeler</foaf:name> - <foaf:mbox rdf:resource="mailto:david@justatheory.com" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>David Perry</foaf:name> - <foaf:mbox rdf:resource="mailto:perry@pythian.com" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>David Steinbrunner</foaf:name> - <foaf:mbox rdf:resource="mailto:dsteinbrunner@pobox.com" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Dean Hamstead</foaf:name> - <foaf:mbox rdf:resource="mailto:djzort@cpan.org" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Dean Pearce</foaf:name> - <foaf:mbox rdf:resource="mailto:deanpearce@gmail.com" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>gregor herrmann</foaf:name> - <foaf:mbox rdf:resource="mailto:gregoa@debian.org" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Gwen Shapira</foaf:name> - <foaf:mbox rdf:resource="mailto:shapira@pythian.com" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>H.Merijn Brand - Tux</foaf:name> - <foaf:mbox rdf:resource="mailto:h.m.brand@xs4all.nl" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Jochen Hayek</foaf:name> - <foaf:mbox rdf:resource="mailto:jochen.hayek@ext.eex.com" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Joe Crotty</foaf:name> - <foaf:mbox rdf:resource="mailto:joe.crotty@returnpath.net" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>jurl</foaf:name> - <foaf:mbox rdf:resource="mailto:jurl@50811bd7-b8ce-0310-adc1-d9db26280581" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>lbaxter</foaf:name> - <foaf:mbox rdf:resource="mailto:lbaxter@50811bd7-b8ce-0310-adc1-d9db26280581" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Michael Portnoy</foaf:name> - <foaf:mbox rdf:resource="mailto:portnoy@pythian.com" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Mike O'Regan</foaf:name> - <foaf:mbox rdf:resource="mailto:moregan@stresscafe.com" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>robert</foaf:name> - <foaf:mbox rdf:resource="mailto:robert@50811bd7-b8ce-0310-adc1-d9db26280581" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>StephenCIQG</foaf:name> - <foaf:mbox rdf:resource="mailto:StephenCIQG@50811bd7-b8ce-0310-adc1-d9db26280581" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Tony Cook</foaf:name> - <foaf:mbox rdf:resource="mailto:tony@develop-help.com" /> - </foaf:Person> - </helper> - <helper> - <foaf:Person> - <foaf:name>Wesley Hinds</foaf:name> - <foaf:mbox rdf:resource="mailto:wesley.hinds@swri.org" /> - </foaf:Person> - </helper> - <license rdf:resource="http://dev.perl.org/licenses/" /> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">12th</revision> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">29th</revision> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">19th</revision> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.37_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2011-12-30</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.38</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-01-13</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.39_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-02-24</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.40</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-03-08</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.42</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-03-13</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.43_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-03-30</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.44</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-04-23</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.45_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-06-21</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.46</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-07-11</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.47_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-07-11</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.48</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-08-09</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.50</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-08-15</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.51_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-09-28</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.52</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-10-19</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.53_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2012-12-18</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.54</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-01-03</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.56</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-01-08</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.57_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-02-07</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.58</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-03-05</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.60</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-04-01</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.61_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-04-15</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.62</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-04-30</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.63_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-05-03</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.64</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-05-22</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.65_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-07-29</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.66</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-08-23</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.67_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-11-05</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.68</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2013-11-25</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.69_01</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2014-01-14</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.69_02</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2014-01-19</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.70</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2014-02-12</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.71_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2014-03-31</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.72</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2014-04-14</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.73_00</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2014-04-23</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.73_01</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2014-04-23</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.74</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2014-04-24</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.75</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2018-11-22</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.75_1</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2014-11-17</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.75_2</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2014-11-19</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.75_42</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2018-08-22</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.76</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2018-11-22</dc:issued> - </Version> - </release> - <release> - <Version> - <revision rdf:datatype="http://www.w3.org/2001/XMLSchema#string">1.791</revision> - <dc:issued rdf:datatype="http://www.w3.org/2001/XMLSchema#date">2019-07-22</dc:issued> - </Version> - </release> - <programming-language>Perl</programming-language> -</Project> diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/GetInfo.pm libdbd-oracle-perl-1.83/lib/DBD/Oracle/GetInfo.pm --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/GetInfo.pm 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/GetInfo.pm 2022-01-17 02:06:35.000000000 +0000 @@ -4,7 +4,7 @@ use warnings; package DBD::Oracle::GetInfo; -our $VERSION = '1.80'; # VERSION +our $VERSION = '1.83'; # VERSION use DBD::Oracle (); @@ -295,7 +295,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 AUTHORS @@ -321,7 +321,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/Object.pm libdbd-oracle-perl-1.83/lib/DBD/Oracle/Object.pm --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/Object.pm 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/Object.pm 2022-01-17 02:06:35.000000000 +0000 @@ -4,7 +4,7 @@ use warnings; package DBD::Oracle::Object; -our $VERSION = '1.80'; # VERSION +our $VERSION = '1.83'; # VERSION sub type_name { shift->{type_name} } @@ -38,7 +38,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 AUTHORS @@ -64,7 +64,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Aix.pod libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Aix.pod --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Aix.pod 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Aix.pod 2022-01-17 02:06:35.000000000 +0000 @@ -13,7 +13,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 Using Visual Age 7 C Compiler @@ -283,7 +283,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Cygwin.pod libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Cygwin.pod --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Cygwin.pod 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Cygwin.pod 2022-01-17 02:06:35.000000000 +0000 @@ -13,7 +13,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 General Info @@ -104,7 +104,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Hpux.pod libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Hpux.pod --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Hpux.pod 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Hpux.pod 2022-01-17 02:06:35.000000000 +0000 @@ -13,7 +13,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 INTRODUCTION @@ -946,7 +946,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Linux.pod libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Linux.pod --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Linux.pod 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Linux.pod 2022-01-17 02:06:35.000000000 +0000 @@ -13,7 +13,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 SELinux and httpd @@ -158,7 +158,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Macos.pod libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Macos.pod --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Macos.pod 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Macos.pod 2022-01-17 02:06:35.000000000 +0000 @@ -13,7 +13,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 General Info @@ -593,7 +593,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Sun.pod libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Sun.pod --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Sun.pod 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Sun.pod 2022-01-17 02:06:35.000000000 +0000 @@ -13,7 +13,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 General Info @@ -68,7 +68,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Vms.pod libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Vms.pod --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Vms.pod 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Vms.pod 2022-01-17 02:06:35.000000000 +0000 @@ -13,7 +13,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 General Info @@ -122,7 +122,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Win32.pod libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Win32.pod --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Win32.pod 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Win32.pod 2022-01-17 02:06:35.000000000 +0000 @@ -13,7 +13,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 GENERAL INFO @@ -270,7 +270,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Win64.pod libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Win64.pod --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting/Win64.pod 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting/Win64.pod 2022-01-17 02:06:35.000000000 +0000 @@ -13,7 +13,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 DBD::Oracle and Windows 64bit @@ -188,7 +188,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting.pod libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting.pod --- libdbd-oracle-perl-1.80/lib/DBD/Oracle/Troubleshooting.pod 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle/Troubleshooting.pod 2022-01-17 02:06:35.000000000 +0000 @@ -13,7 +13,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 CONNECTING TO ORACLE @@ -160,7 +160,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/lib/DBD/Oracle.pm libdbd-oracle-perl-1.83/lib/DBD/Oracle.pm --- libdbd-oracle-perl-1.80/lib/DBD/Oracle.pm 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/lib/DBD/Oracle.pm 2022-01-17 02:06:35.000000000 +0000 @@ -11,7 +11,7 @@ { package DBD::Oracle; - our $VERSION = '1.80'; # VERSION + our $VERSION = '1.83'; # VERSION # ABSTRACT: Oracle database driver for the DBI module use DBI (); @@ -487,24 +487,23 @@ } else { $SQL = <<'SQL'; -SELECT * - FROM -( - SELECT /*+ CHOOSE */ - NULL TABLE_CAT - , t.OWNER TABLE_SCHEM - , t.TABLE_NAME TABLE_NAME - , decode(t.OWNER - , 'SYS' , 'SYSTEM ' - , 'SYSTEM' , 'SYSTEM ' - , '' ) || t.TABLE_TYPE TABLE_TYPE - , c.COMMENTS REMARKS - FROM ALL_TAB_COMMENTS c - , ALL_CATALOG t - WHERE c.OWNER (+) = t.OWNER - AND c.TABLE_NAME (+) = t.TABLE_NAME - AND c.TABLE_TYPE (+) = t.TABLE_TYPE -) + select * FROM ( + select /*+ CHOOSE */ + NULL TABLE_CAT + , t.OWNER TABLE_SCHEM + , t.TABLE_NAME TABLE_NAME + , decode(t.OWNER + , 'SYS' , 'SYSTEM ' + , 'SYSTEM' , 'SYSTEM ' + , '' ) || DECODE(mv.MVIEW_NAME, NULL, t.TABLE_TYPE, 'VIEW' ) TABLE_TYPE + , c.COMMENTS REMARKS + FROM ALL_TAB_COMMENTS c + RIGHT JOIN ALL_CATALOG t on t.OWNER = c.OWNER + and t.TABLE_NAME = c.TABLE_NAME + and t.TABLE_TYPE = c.TABLE_TYPE + LEFT JOIN ALL_MVIEWS mv on mv.OWNER = t.OWNER + and mv.MVIEW_NAME = t.TABLE_NAME + ) SQL if ( defined $SchVal ) { push @Where, "TABLE_SCHEM LIKE '$SchVal' ESCAPE '\\'"; @@ -1249,7 +1248,7 @@ =head1 VERSION -version 1.80 +version 1.83 =head1 SYNOPSIS @@ -1788,19 +1787,24 @@ =head4 ora_dbh_share -Requires at least Perl 5.8.0 compiled with ithreads. +Requires at least Perl 5.8.0 compiled with ithreads (interpreter-based +threads). -Allows you to share -database connections between threads. The first connect will make the -connection, all following calls to connect with the same ora_dbh_share -attribute will use the same database connection. The value must be a -reference to a already shared scalar which is initialized to an empty -string. +Allows you to share database connections between threads. The first +connect will make the connection, all following calls to connect with +the same ora_dbh_share attribute will use the same database connection. +The value must be a reference to a already shared scalar which is +initialized to an empty string. our $orashr : shared = '' ; $dbh = DBI->connect ($dsn, $user, $passwd, {ora_dbh_share => \$orashr}) ; +With ithreads DBD::Oracle will leak handles, because it can't tell +when the last driver handle is destroyed. + +Please keep in mind, that ithreads are officially discouraged. + =head4 ora_events Set this attribute to C<1> to enable Oracle Fast Application Notification @@ -5566,29 +5570,12 @@ =back -=head1 AUTHORS - -DBI by Tim Bunce L<http://www.tim.bunce.name>. - -The original C<DBD::Oracle> was by Tim Bunce. -Maintained as of release 1.17 (February 2006) by John Scoles, then Yanick Champoux, under the -auspice of the Pythian Group (L<http://www.pythian.com>). - =head1 ACKNOWLEDGEMENTS A great many people have helped with DBD::Oracle over the 17 years between 1994 and 2011. Far too many to name, but we thank them all. Many are named in the Changes file. -=head1 COPYRIGHT - -The DBD::Oracle module is Copyright (c) 1994-2006 Tim Bunce. Ireland. -The DBD::Oracle module is Copyright (c) 2006-2011 John Scoles (The Pythian Group). Canada. -The DBD::Oracle module is Copyright (c) 2011 John Scoles. Canada. - -The DBD::Oracle module is free open source software; you can -redistribute it and/or modify it under the same terms as Perl 5. - =head1 AUTHORS =over 4 @@ -5613,7 +5600,7 @@ =head1 COPYRIGHT AND LICENSE -This software is copyright (c) 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. +This software is copyright (c) 2022, 2021, 2019, 2014, 2013, 2012, 2011, 2010 by Tim Bunce. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. diff -Nru libdbd-oracle-perl-1.80/t/00-report-prereqs.dd libdbd-oracle-perl-1.83/t/00-report-prereqs.dd --- libdbd-oracle-perl-1.80/t/00-report-prereqs.dd 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/t/00-report-prereqs.dd 2022-01-17 02:06:35.000000000 +0000 @@ -1,19 +1,21 @@ do { my $x = { + 'build' => { + 'requires' => { + 'Config' => '0' + } + }, 'configure' => { 'requires' => { - 'Config' => '0', - 'DBI' => '1.623', - 'Data::Dumper' => '0', - 'Devel::Peek' => '0', - 'Encode' => '0', 'ExtUtils::MakeMaker' => '0', - 'Math::BigInt' => '0', - 'Test::More' => '0', - 'Test::NoWarnings' => '0' + 'perl' => '5.006' + }, + 'suggests' => { + 'JSON::PP' => '2.27300' } }, 'develop' => { 'requires' => { + 'DBI' => '1.623', 'Pod::Coverage::TrustPod' => '0', 'Test::CPAN::Meta' => '0', 'Test::EOF' => '0', @@ -22,6 +24,7 @@ 'Test::More' => '0.88', 'Test::NoBreakpoints' => '0.15', 'Test::NoTabs' => '0', + 'Test::NoWarnings' => '0', 'Test::Pod' => '1.41', 'Test::Pod::Coverage' => '1.08', 'Test::Portability::Files' => '0' @@ -29,10 +32,11 @@ }, 'runtime' => { 'requires' => { - 'DBI' => '0', + 'DBI' => '1.623', + 'Data::Dumper' => '0', 'DynaLoader' => '0', 'Exporter' => '0', - 'perl' => '5.006', + 'perl' => '5.008', 'strict' => '0', 'warnings' => '0' } @@ -57,8 +61,11 @@ 'Test::NoWarnings' => '0', 'Thread::Semaphore' => '0', 'lib' => '0', + 'perl' => '5.008', + 'strict' => '0', 'utf8' => '0', - 'vars' => '0' + 'vars' => '0', + 'warnings' => '0' } } }; diff -Nru libdbd-oracle-perl-1.80/t/00-report-prereqs.t libdbd-oracle-perl-1.83/t/00-report-prereqs.t --- libdbd-oracle-perl-1.80/t/00-report-prereqs.t 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/t/00-report-prereqs.t 2022-01-17 02:06:35.000000000 +0000 @@ -3,7 +3,7 @@ use strict; use warnings; -# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.027 +# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.028 use Test::More tests => 1; @@ -188,6 +188,6 @@ ); } -pass; +pass('Reported prereqs'); # vim: ts=4 sts=4 sw=4 et: diff -Nru libdbd-oracle-perl-1.80/t/14threads.t libdbd-oracle-perl-1.83/t/14threads.t --- libdbd-oracle-perl-1.80/t/14threads.t 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/t/14threads.t 2022-01-17 02:06:35.000000000 +0000 @@ -1,5 +1,8 @@ #!perl +use strict; +use warnings; + $| = 1; ## ---------------------------------------------------------------------------- @@ -9,8 +12,6 @@ # This needs to be the very very first thing BEGIN { eval 'use threads; use threads::shared;' } -use strict; -use warnings; use lib 't/lib'; use DBDOracleTestLib qw/ oracle_test_dsn db_handle /; diff -Nru libdbd-oracle-perl-1.80/t/25plsql.t libdbd-oracle-perl-1.83/t/25plsql.t --- libdbd-oracle-perl-1.80/t/25plsql.t 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/t/25plsql.t 2022-01-17 02:06:35.000000000 +0000 @@ -30,7 +30,7 @@ plan skip_all => 'Oracle server either does not support pl/sql or it is not properly installed'; } - plan tests => 82; + plan tests => 86; } else { plan skip_all => "Unable to connect to Oracle \n"; @@ -325,13 +325,47 @@ is( "@r", "@s2", 'ref = sql' ); } -# test bind_param_inout of param that's not assigned to in executed statement -# See http://www.mail-archive.com/dbi-users@perl.org/msg18835.html +SKIP: { + # test bind_param_inout of param that's not assigned to in executed statement + # Github Issue #70 + # Also see http://www.mail-archive.com/dbi-users@perl.org/msg18835.html + + # Known bad OCI versions + my @bad_oci_vers = (9.2,18.3,18.5,19.6); + + skip 'Client version is known to have issue', 4 + if grep { $_ == DBD::Oracle::ORA_OCI() } @bad_oci_vers; + + my $sth = $dbh->prepare( + q( + BEGIN + -- :p1 := :p1 ; + -- :p2 := :p2 ; + IF :p2 != :p3 THEN + :p1 := 'AAA' ; + :p2 := 'Z' ; + END IF ; + END ;) + ); + + my ( $p1, $p2, $p3 ) = ( 'Hello', 'Y', 'Y' ); + $sth->bind_param_inout( ':p1', \$p1, 30 ); + $sth->bind_param_inout( ':p2', \$p2, 1 ); + $sth->bind_param_inout( ':p3', \$p3, 1 ); + note("Before p1=[$p1] p2=[$p2] p3=[$p3]\n"); + ok( $sth->execute, 'test bind_param_inout for non assigned' ); + is( $p1, 'Hello', 'p1 ok' ); + is( $p2, 'Y', 'p2 ok' ); + is( $p3, 'Y', 'p3 ok' ); + note("After p1=[$p1] p2=[$p2] p3=[$p3]\n"); +} + +# test bind_paraminout the correct way (avoids the above issue if present) my $sth = $dbh->prepare( q( BEGIN - -- :p1 := :p1 ; - -- :p2 := :p2 ; + :p1 := :p1 ; + :p2 := :p2 ; IF :p2 != :p3 THEN :p1 := 'AAA' ; :p2 := 'Z' ; @@ -345,7 +379,7 @@ $sth->bind_param_inout( ':p2', \$p2, 1 ); $sth->bind_param_inout( ':p3', \$p3, 1 ); note("Before p1=[$p1] p2=[$p2] p3=[$p3]\n"); - ok( $sth->execute, 'test bind_param_inout for non assigned' ); + ok( $sth->execute, 'test bind_param_inout for properly assigned' ); is( $p1, 'Hello', 'p1 ok' ); is( $p2, 'Y', 'p2 ok' ); is( $p3, 'Y', 'p3 ok' ); diff -Nru libdbd-oracle-perl-1.80/t/README libdbd-oracle-perl-1.83/t/README --- libdbd-oracle-perl-1.80/t/README 2019-07-25 14:15:30.000000000 +0000 +++ libdbd-oracle-perl-1.83/t/README 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -Variables used in tests ------------------------ - -** Connecting to Oracle ** - -ORACLE_USERID - important - -Which user & password to use when running tests against a real Oracle database - -Should be 'user/password' or a longer string with connection details. - - $ export ORACLE_USERID='scott/tiger' - -ORACLE_USERID_2 - -Provides a second set of user credentials when needed - -ORACLE_DSN - -DSN details when connecting to real Oracle for tests - - $ export ORACLE_DSN='dbi:Oracle:testdb' - -DBI_DSN - -If ORACLE_DSN is not provided, this will be used. Otherwise falls back to internal default. - -** Creation of tables, views, functions etc ** - -DBD_ORACLE_SEQ - important - -Appended to table, view, function (etc) that are created during testing to help -prevent collisions - -DBD_SKIP_TABLE_DROP - -Skips dropping temporary tables when tests complete. Use to examine the mess. - -** Other ** - -NLS_DATE_FORMAT - -Sets the date format as normal - -Need more details ------------------ - -NLS_NCHAR - -NLS_LANG - - -??? - -DBI_USER - -DBI_PASS - -DBD_ALL_TESTS - -Forces some tests to run, that otherwise wouldn't -
Attachment:
signature.asc
Description: PGP signature