<LI><A HREF="#2.1. compilation problems or it fails the test!">2.1. Compilation problems or ``It fails the test!''</A></LI>
</UL>
<LI><A HREF="#platform and driver issues">Platform and Driver Issues</A></LI>
<UL>
<LI><A HREF="#3.1 what's the difference between odbc and dbi">3.1 What's the difference between ODBC and DBI?</A></LI>
<LI><A HREF="#3.2 what's the difference between win32::odbc and dbd::odbc">3.2 What's the difference between Win32::ODBC and DBD::ODBC?</A></LI>
<LI><A HREF="#3.3 is dbi supported under windows 95 / nt platforms">3.3 Is DBI supported under Windows 95 / NT platforms?</A></LI>
<LI><A HREF="#3.4 can i access microsoft access or sqlserver databases with dbi">3.4 Can I access Microsoft Access or SQL-Server databases with DBI?</A></LI>
<LI><A HREF="#3.5 is the a dbd for <insert favourite database here>">3.5 Is the a DBD for <<EM>insert favourite database here</EM>>?</A></LI>
<LI><A HREF="#3.6 what's dbm and why should i use dbi instead">3.6 What's DBM? And why should I use DBI instead?</A></LI>
<LI><A HREF="#3.7 what database do you recommend me using">3.7 What database do you recommend me using?</A></LI>
<LI><A HREF="#3.8 is <insert feature here> supported in dbi">3.8 Is <<EM>insert feature here</EM>> supported in DBI?</A></LI>
<LI><A HREF="#4.1 is dbi any use for cgi programming">4.1 Is DBI any use for CGI programming?</A></LI>
<LI><A HREF="#4.2 how do i get faster connection times with dbd::oracle and cgi">4.2 How do I get faster connection times with DBD::Oracle and CGI?</A></LI>
<LI><A HREF="#4.3 how do i get persistent connections with dbi and cgi">4.3 How do I get persistent connections with DBI and CGI?</A></LI>
<LI><A HREF="#4.4 ``when i run a perl script from the command line, it works, but, when i run it under the httpd, it fails!'' why">4.4 ``When I run a perl script from the command line, it works, but, when I run it under the <CODE>httpd</CODE>, it fails!'' Why?</A></LI>
<LI><A HREF="#4.5 how do i get the number of rows returned from a select statement">4.5 How do I get the number of rows returned from a <CODE>SELECT</CODE> statement?</A></LI>
<LI><A HREF="#5.1 can i do multithreading with dbi">5.1 Can I do multi-threading with DBI?</A></LI>
<LI><A HREF="#5.2 how do i handle blob data with dbi">5.2 How do I handle BLOB data with DBI?</A></LI>
<LI><A HREF="#5.3 how can i invoke stored procedures with dbi">5.3 How can I invoke stored procedures with DBI?</A></LI>
<LI><A HREF="#5.4 how can i get return values from stored procedures with dbi">5.4 How can I get return values from stored procedures with DBI?</A></LI>
<LI><A HREF="#5.5 how can i create or drop a database with dbi">5.5 How can I create or drop a database with DBI?</A></LI>
<LI><A HREF="#5.6 how can i commit or rollback a statement with dbi">5.6 How can I <CODE>commit</CODE> or <CODE>rollback</CODE> a statement with DBI?</A></LI>
<LI><A HREF="#5.7 how are null values handled by dbi">5.7 How are <CODE>NULL</CODE> values handled by DBI?</A></LI>
<LI><A HREF="#5.8 what are these func() methods all about">5.8 What are these <CODE>func()</CODE> methods all about?</A></LI>
<LI><A HREF="#5.9 is dbi year 2000 compliant">5.9 Is DBI Year 2000 Compliant?</A></LI>
</UL>
<LI><A HREF="#support and training">Support and Training</A></LI>
Module versions, perl version, test cases, operating system versions
and <EM>any other pertinent information</EM>.
<P></P></UL>
<P>Remember, the more information you send us, the quicker we can track
problems down. If you send us no useful information, expect nothing back.</P>
<P>Finally, please be aware that some authors, including Tim Bunce, specifically
request that you do <EM>not</EM> mail them directly. Please respect their wishes and
use the email addresses listed in the appropriate module <CODE>README</CODE> file.</P>
<DT><STRONG><A NAME="item_Email_the_dbi%2Dusers_Mailing_List"><EM>Email the dbi-users Mailing List</EM></A></STRONG><BR>
<DD>
It's usually a fairly intelligent idea to <EM>cc</EM> the mailing list
anyway with problems. The authors all read the lists, so you lose nothing
by mailing there.
<P></P></DL>
<P>
<HR>
<H1><A NAME="platform and driver issues">Platform and Driver Issues</A></H1>
<P>
<H2><A NAME="3.1 what's the difference between odbc and dbi">3.1 What's the difference between ODBC and DBI?</A></H2>
<P>In terms of architecture - not much: Both define programming
interfaces. Both allow multiple drivers to be loaded to do the
actual work.</P>
<P>In terms of easy of use - much: The DBI is a 'high level' interface
that, like Perl itself, strives to make the simple things easy while
still making the hard things possible. The ODBC is a 'low level'
interface. All nuts-bolts-knobs-and-dials.</P>
<P>Now there's an ODBC driver for the DBI (DBD::ODBC) the ``What's the
difference'' question is more usefully rephrased as:</P>
<P>
<H2><A NAME="3.2 what's the difference between win32::odbc and dbd::odbc">3.2 What's the difference between Win32::ODBC and DBD::ODBC?</A></H2>
<P>The DBI, and thus DBD::ODBC, has a different philosophy from the
Win32::ODBC module:</P>
<P>The Win32::ODBC module is a 'thin' layer over the low-level ODBC API.
The DBI defines a simpler 'higher level' interface.</P>
<P>The Win32::ODBC module gives you access to more of the ODBC API.
The DBI and DBD::ODBC give you access to only the essentials.
(But, unlike Win32::ODBC, the DBI and DBD::ODBC do support parameter
binding and multiple prepared statements which reduces the load on
the database server and can dramatically increase performance.)</P>
<P>The Win32::ODBC module only works on Win32 systems.
The DBI and DBD::ODBC are very portable and work on Win32 and Unix.</P>
<P>The DBI and DBD::ODBC modules are supplied as a standard part of the
Perl 5.004 binary distribution for Win32 (they don't work with the
older, non-standard, ActiveState port).</P>
<P>Scripts written with the DBI and DBD::ODBC are faster than Win32::ODBC
on Win32 and are trivially portable to other supported database types.
</P>
<PRE>
The DBI offers optional automatic printing or die()ing on errors which
makes applications simpler and more robust.</PRE>
<PRE>
The current DBD::ODBC driver version 0.16 is new and not yet fully stable.
A new release is due soon [relative to the date of the next TPJ issue :-]
and will be much improved and offer more ODBC functionality.</PRE>
<P>To summarise: The Win32::ODBC module is your best choice if you need
access to more of the ODBC API than the DBI gives you. Otherwise, the
DBI and DBD::ODBC combination may be your best bet.</P>
<P>
<H2><A NAME="3.3 is dbi supported under windows 95 / nt platforms">3.3 Is DBI supported under Windows 95 / NT platforms?</A></H2>
<P>Finally, yes! Jeff Urlwin has been working diligently on building
<EM>DBI</EM> and <EM>DBD::ODBC</EM> under these platforms, and, with the
advent of a stabler perl and a port of <EM>MakeMaker</EM>, the project has
come on by great leaps and bounds.</P>
<P>The <EM>DBI</EM> and <EM>DBD::Oracle</EM> Win32 ports are now a standard part of DBI,
so, downloading <EM>DBI</EM> of version higher than <EM>0.81</EM> should work fine as
should using the most recent <EM>DBD::Oracle</EM> version.</P>
<P>
<H2><A NAME="3.4 can i access microsoft access or sqlserver databases with dbi">3.4 Can I access Microsoft Access or SQL-Server databases with DBI?</A></H2>
<P>Yes, use the <EM>DBD::ODBC</EM> driver.</P>
<P>
<H2><A NAME="3.5 is the a dbd for <insert favourite database here>">3.5 Is the a DBD for <<EM>insert favourite database here</EM>>?</A></H2>
<H2><A NAME="4.1 is dbi any use for cgi programming">4.1 Is DBI any use for CGI programming?</A></H2>
<P>In a word, yes! DBI is hugely useful for CGI programming! In fact, I would
tentatively say that CGI programming is one of two top uses for DBI.</P>
<P>DBI confers the ability to CGI programmers to power WWW-fronted databases
to their users, which provides users with vast quantities of ordered
data to play with. DBI also provides the possibility that, if a site is
receiving far too much traffic than their database server can cope with, they
can upgrade the database server behind the scenes with no alterations to
the CGI scripts.</P>
<P>
<H2><A NAME="4.2 how do i get faster connection times with dbd::oracle and cgi">4.2 How do I get faster connection times with DBD::Oracle and CGI?</A></H2>
<PRE>
Contributed by John D. Groenveld</PRE>
<P>The Apache <CODE>httpd</CODE> maintains a pool of <CODE>httpd</CODE> children to service client
requests.</P>
<P>Using the Apache <EM>mod_perl</EM> module by <EM>Doug MacEachern</EM>, the perl
interpreter is embedded with the <CODE>httpd</CODE> children. The CGI, DBI, and your
other favorite modules can be loaded at the startup of each child. These
modules will not be reloaded unless changed on disk.</P>
<P>For more information on Apache, see the Apache Project's WWW site:</P>
<H2><A NAME="4.4 ``when i run a perl script from the command line, it works, but, when i run it under the httpd, it fails!'' why">4.4 ``When I run a perl script from the command line, it works, but, when I run it under the <CODE>httpd</CODE>, it fails!'' Why?</A></H2>
<P>Basically, a good chance this is occurring is due to the fact that the user
that you ran it from the command line as has a correctly configured set of
environment variables, in the case of <EM>DBD::Oracle</EM>, variables like
<CODE>ORACLE_HOME</CODE>, <CODE>ORACLE_SID</CODE> or <CODE>TWO_TASK</CODE>.</P>
<P>The <CODE>httpd</CODE> process usually runs under the user id of <CODE>nobody</CODE>,
which implies there is no configured environment. Any scripts attempting to
execute in this situation will correctly fail.</P>
<P>One way to solve this problem is to set the environment for your database in a
<CODE>BEGIN { }</CODE> block at the top of your script. Another technique is to configure
your WWW server to pass-through certain environment variables to your CGI
scripts.</P>
<P>Similarly, you should check your <CODE>httpd</CODE> error logfile for any clues,
as well as the ``Idiot's Guide To Solving Perl / CGI Problems'' and
``Perl CGI Programming FAQ'' for further information. It is
unlikely the problem is DBI-related.</P>
<P>The ``Idiot's Guide To Solving Perl / CGI Problems'' can be located at:</P>
<P>as can the ``Perl CGI Programming FAQ''. Read <EM>BOTH</EM> these documents
carefully!</P>
<P>
<H2><A NAME="4.5 how do i get the number of rows returned from a select statement">4.5 How do I get the number of rows returned from a <CODE>SELECT</CODE> statement?</A></H2>
<P>Count them. Read the DBI docs for the <CODE>rows()</CODE> method.</P>
<P>You should also be able to <CODE>prepare</CODE> and <CODE>execute</CODE>, which is
the recommended way if you'll be calling the procedure often.</P>
<P>
<H2><A NAME="5.4 how can i get return values from stored procedures with dbi">5.4 How can I get return values from stored procedures with DBI?</A></H2>
<P>Remember to perform error checking, though! ( Or use the <CODE>RaiseError</CODE>
attribute ).</P>
<P>
<H2><A NAME="5.5 how can i create or drop a database with dbi">5.5 How can I create or drop a database with DBI?</A></H2>
<P>Database creation and deletion are concepts that are entirely too abstract
to be adequately supported by DBI. For example, Oracle does not support the
concept of dropping a database at all! Also, in Oracle, the database
<EM>server</EM> essentially <EM>is</EM> the database, whereas in mSQL, the
server process runs happily without any databases created in it. The
problem is too disparate to attack in a worthwhile way.</P>
<P>Some drivers, therefore, support database creation and deletion through
the private <CODE>func()</CODE> methods. You should check the documentation for
the drivers you are using to see if they support this mechanism.</P>
<P>
<H2><A NAME="5.6 how can i commit or rollback a statement with dbi">5.6 How can I <CODE>commit</CODE> or <CODE>rollback</CODE> a statement with DBI?</A></H2>
<P>See the <CODE>commit()</CODE> and <CODE>rollback()</CODE> methods in the DBI docs.</P>
<P>
<H2><A NAME="5.7 how are null values handled by dbi">5.7 How are <CODE>NULL</CODE> values handled by DBI?</A></H2>
<P><CODE>NULL</CODE> values in DBI are specified to be treated as the value <A HREF="../../../lib/Pod/perlfunc.html#item_undef"><CODE>undef</CODE></A>.
<CODE>NULL</CODE>s can be inserted into databases as <CODE>NULL</CODE>, for example:</P>
<PRE>
$rv = $dbh->do( "INSERT INTO table VALUES( NULL )" );</PRE>
<P>but when queried back, the <CODE>NULL</CODE>s should be tested against <A HREF="../../../lib/Pod/perlfunc.html#item_undef"><CODE>undef</CODE></A>.
This is standard across all drivers.</P>
<P>
<H2><A NAME="5.8 what are these func() methods all about">5.8 What are these <CODE>func()</CODE> methods all about?</A></H2>
<P>The <CODE>func()</CODE> method is defined within DBI as being an entry point
for database-specific functionality, <EM>eg</EM>, the ability to create or
drop databases. Invoking these driver-specific methods is simple, for example,
to invoke a <CODE>createDatabase</CODE> method that has one argument, we would