This is the Easysoft ODBC-ODBC Bridge FAQ.

List of Questions
-----------------

1. General Questions
 1.1 What is the Easysoft ODBC-ODBC Bridge?
 1.2 What does it do?
 1.3 What versions of ODBC are supported?
 1.4 Where can I get it?
 1.5 What else do I need?
 1.6 Do I need a Driver Manager?
 1.7 How much disk space do I need?
 1.8 What is a DSN?
 1.9 Where do I get information about the ODBC API?
 1.10 What platforms/OS is OOB available for?
 1.11 Where is the latest version of this FAQ?

2. OOB Specific.
 2.1 How do I build my ODBC application with the OOB?
 2.2 How to I set up a DSN?
 2.3 What attributes may be specified in a DSN?
 2.4 How does the OOB locate DSNs.
 2.5 I only want to retrieve data from the server, are there any tricks
     to speed it up in read-only mode?
 2.6 How can I get help on using the OOB?
 2.7 Where do I report bugs in the OOB?
 2.8 How much does a license for OOB cost?
 2.9 When was the first official release of OOB made available?
 2.10 When did the beta version expire?
 2.11 What do I do when my beta version of the OOB expires?
 2.12 How do I license OOB?
 2.13 Are there any configurable options for the OOB?
 2.14 How much memory do I need for the OOB Server on NT?
 2.15 Why does it take so long to connect to the server?
 2.16 Why can I see more tables in MS SQL Server than normal?
 2.17 Are any usernames/passwords transmitted as plain text over the network
      connection?
 2.18 Can I strip(1) the shared objects and executables?
 2.19 Can I run the OOB Server on UNIX without the inetd SuperServer?
 2.20 Can I make the OOB statistics web page refresh more/less frequently?
 2.21 Why does the OOB HTTP Server statistics page show active threads
      when there are no connections?
 2.22 Why cannot I login to the HTTP Administrator when running the OOB
      server as a named user instead of in the system account?
 2.23 Is there any tracing in OOB I can use for debugging my application?
 2.24 How do I specify connection attributes for my DSN that are not
      configurable in the odbc.ini?
 2.25 Why does SQLDataSources list a data source which returns the
      Datasource not found message when I connect to it?
 2.26 How can I encrypt the network connection between the client and server?
 2.27 Does the OOB install for UNIX support xinetd?
 2.28 Do you have to have DNS working for correct operation of OOB?
 2.29 Can multiple machines running the OOB client simultaneously use the
      same OOB Server?
 2.30 How does the OOB client handle refused connections?
 2.31 How does the OOB client support connection timeouts?
 2.32 What does the OOB do if an application terminates abnormally?
 2.33 I have no root access. How do I tell OOB/unixODBC to use odbc.ini
      and odbcinst.ini files not in /etc?
 2.34 Why do I get the error "Not enough attributes for connection" since
      upgrading OOB from a pre 1.0.0.27 release?
 2.35 How can I tell what version of OOB I am running?
 2.36 Do you have to install the OOB Server on the same machine as your
      Database?
 2.37 Why do I get "[unixODBC][Easysoft ODBC (Server)]Memory allocation error"?
 2.38 How do I use oobping?
 2.39 How do I reset the OOB web administrator username?
 2.40 Why does the OOB Server Windows Service terminate unexpectedly?
 2.41 How do I run an OOB Server on UNIX at reduced priority?
 2.42 What does "Communication link failure" mean?
 2.43 What is the OOB demo server and how do I use it?
 2.44 How do I upgrade to a newer version of OOB?
 
3. Trouble Shooting
 3.1 Why do I get connection refused errors from the client?
 3.2 Why do I get connection closed by foreign host messages when I try
     to telnet to the port the server is listening on?
 3.3 Why do my connections to the OOB server seem to be dropped after a while?
 3.4 Why do I get "Data source not found and no default driver" message when
     I am sure I have defined the DSN in my odbc.ini file?
 3.5 Why do I get authorization failures from the client?
 3.6 How do I find out why an ODBC call is failing?
 3.7 Why can't I connect to the data source?

4. Application/Driver-specific
 4.1 Perl Related
  4.1.1 How do I use Perl with OOB?
  4.1.2 What versions of Perl modules can I use with OOB?
  4.1.3 Where can I find more information about Perl DBI and DBD:ODBC?
  4.1.4 Do I have to set DBI_DSN, DBI_USER and DBI_PASS  environment variables
        before running my Perl script?
  4.1.5 How can I put attributes other than the DSN in my Perl
        DBI->connect call?
  4.1.6 How can I debug my Perl DBI, DBD::ODBC?
  4.1.7 Why do I keep getting data truncated errors in my Perl?
  4.1.8 Why does Perl DBD::ODBC appear to open the DEFAULT data source with OOB?
  4.1.9 Why do I get undefined symbols when running the Perl DBD::ODBC test?
  4.1.10 Why does test 13 of the simple test in Perl DBD::ODBC fail?
  4.1.11 Why do I get compile errors building Perl DBD::ODBC on AIX?
  4.1.12 Why do I get "undefined symbol: SQLParamData" when testing DBD::ODBC?
  4.1.13 Why does make test for Perl DBD::ODBC fail with
         "invalid object name" errors?
  4.1.14 Why does make test in DBD::ODBC return 09multi errors containing
         "Data mismatch, result set 1"?
  4.1.15 Why do I get "String data, right truncation" retrieving result-sets
         from MS SQL Server?
  4.1.16 Why does a query on columns containing colons in the name fail from
         DBD::ODBC?
  4.1.17 Why do my Perl scripts complete but end in a segmentation violation?
  4.1.18 Why do I get "SQLSetConnectOption err=-2" errors in my Perl scripts
  4.1.19 Why cannot I insert timestamps with DBD::ODBC 0.32 - it worked with
         previous versions of DBD::ODBC?
  4.1.20 Why does test 1 and 2 or 20Sqlserver test in DBD::ODBC fail to
         MS SQL Server?
  4.1.21 Why do I get "Makefile:311: *** missing separator.  Stop." when
         building DBD::ODBC 1.06?
  4.1.22 Why do I get "Can't change param 1 maxlen (51->50) after first bind"
         error when running make test in DBD::ODBC?
  4.1.23 Why does make test in DBD::ODBC to SQL Server 2005 and SQL Server
         Express fail?
 4.2 PHP/Apache Related
  4.2.1 How do I use Apache/PHP with OOB?
  4.2.2 What versions of PHP (and Apache) can I use with OOB?
  4.2.3 Why do I get parse errors when compiling PHP with OOB?
  4.2.4 Why do I get undefined reference to xyz when making Apache/PHP
  4.2.5 Why does a build of PHP4 RC1 and OOB fail?
  4.2.6 Why do I get compile warnings in php_odbc.c with OOB 1.0.0.15
  4.2.7 I don't want to rebuild Apache for PHP/ODBC support, what can I do?
  4.2.8 How do I tell Apache to pass PHP scripts to the PHP interpreter?
  4.2.9 Apache/PHP can't seem to find my odbc.ini file or
        Datasource not found and no default driver error.
  4.2.10 Why don't my PHP scripts appear to run on the web server?
  4.2.11 How can I find out why my PHP script is not working?
  4.2.12 Can I use PHP with OOB and driver X?
  4.2.13 In PHP, why can I only use/get column names up to 30 characters when
         my database supports much longer column names?
  4.2.14 Why is my column data truncated at 4096 bytes from PHP?
  4.2.15 Why does phpinfo() display "Active Persistent Links" of 0/1 when I
         know there are more open connections to my database?
  4.2.16 Why don't my changes to PHP odbc settings in php.ini file get
         picked up?
  4.2.17 Why doesn't PHP's max_persistent setting limit the total number of
         ODBC connections to my database?
  4.2.18 What is this problem I'm seeing when using PHP persistent connections?
 4.3 MS SQL Server / Access
  4.3.1 Why can't I use bound parameters with MS Access
  4.3.2 Why does my second connection to MS Access hang?
  4.3.3 Why do I get corrupted text columns back from MS SQL Server
  4.3.4 Why are my connections to MS SQL Server so slow?
  4.3.5 Why is my NT OOB Server using a lot of CPU, my ODBC connections go to
       MS SQL Server?
  4.3.6 Why cannot I insert timestamps with sub-millisecond fractions in to
       MS SQL Server datetime field?
  4.3.7 Why have connection times to MS SQL Server slowed down since upgrading
        to Windows 2000 Server?
  4.3.8 Why are my output bound parameters from a MS SQL Server procedure
        not retrieved?
  4.3.9 Why do I get "Could not find file '(unknown)'" errors using MS Access
        ODBC driver?
  4.3.10 Why do I get "Incorrect Syntax near the Keyword 'by'" error message
         when calling SQLDescribeParam in the MS SQL Server ODBC driver?
  4.3.11 Why do I get "[Microsoft][ODBC SQL Server Driver][Named Pipes]
         ConnectionOpen (CreateFile())"?
  4.3.12 Why do parameterised inserts appear to hang and my OOB Server is
         using over 90% of cpu?
  4.3.13 Why do I get an Access Violation in MS SQL Server ODBC Driver?
  4.3.14 Why are my numeric and currency values returned too long with
         an additional random character from MS SQL Server?
 4.4 Other applications/interfaces/drivers
  4.4.1 ld: cannot open -lesoobclient: No such file or directory when
        attempting to link an application with the OOB.
  4.4.2 Why do I get Driver's SQLAllocHandle on SQL_HANDLE_ENV failed with the
        Microsoft Oracle ODBC driver?
  4.4.3 Why do I get "IM004, Driver's SQLAllocHandle on SQL_HANDLE_HENV failed"
        connecting to DB2?
  4.4.4 Why am I having intermittent problems with a particular ODBC driver?
  4.4.5 Why doesn't a query return recently inserted data?
  4.4.6 I don't like my odbc.ini in the same directory as my PHP/Perl script
        as people browsing my web site may see it and it contains passwords.
        What do I do?
  4.4.7 Why cannot I use multiple active statements?
  4.4.8 Why can't I run CGI programs using OOB under
       Netscape Enterprise Server?
  4.4.9 Why do I not get a list of all the tables and columns in a database?
  4.4.10 Why do I get a transaction already started error calling a procedure?
  4.4.11 Why do I get ODBC driver authentication denied when using  unixODBC's
         isql and DataManager?
  4.4.12 How do I pass LD_LIBRARY_PATH down to CGI programs from Apache?
  4.4.13 Does OOB work with OpenOffice.org?
  4.4.14 What does "[Easysoft ODBC][unixODBC][Driver Manager]Can't initiate
         unicode conversion" mean?
  4.4.15 Why does SQLDriverConnect return "The driver doesn't support the
         version of ODBC behavior that the application requested"?
  4.4.16 How can I avoid setting shell environment variables required by
         a driver?
  4.4.17 Why do I get the error "Initialization function SQLAllocConnect
         not found" when attempting to use Oracle's heterogenous services
         (hsODBC) on AIX?
  4.4.18 Why cannot I see my tables in Excel/Query for MAC OS X?
  4.4.19 Does OOB work with Lotus Domino?
  4.4.20 Can I access Foxpro databases with OOB?
  4.4.21 Can I use OOB with Actuate Reporting Applications?
  4.4.22 Can I use the OOB with Oracle heterogeneous services (hsodbc)?
  4.4.23 Why do I get "table of view does not exist" when selecting from a
         table using Oracle hsODBC connected to MS SQL Server with OOB?
  4.4.24 Can I use OOB to access my remote database?
  4.4.25 Why do I get "libodbc.a(odbc.so) could not be loaded" using
         Informatica with unixODBC and OOB?
  4.4.26 Why do I receive the error "No ODBC driver is installed" when
         I try to retrieve data in Microsoft Excel for MAC?

5. Operating System Specific - Linux
 5.1 Which version of OOB should I be using?
 5.2 What Linux kernels can I run?
 5.3 Linker errors building Apache/PHP with OOB
 5.4 Which is best, inetd or standalone startup for the OOB Server?
 5.5 Can I use a multi-threaded application with OOB on Linux and if so how?
 5.6 Why is inetd terminating the OOB Server service?
 5.7 Why are second and subsequent connections to the OOB Server under inetd
     so slow?
 5.8 Why do I get the error "libqt.so.3: symbol _res, version GLIBC_2.0
     not defined"?

6. Operating System Specific - Windows
 6.1 What username/password do I need to specify for LogonUser
     and LogonAuth?
 6.2 What do I do if I get an Access Violation or Fault popup window?
 6.3 Does the OOB client support file DSNs?
 6.4 Why does the install hang?
 6.5 Why do I get "Invalid authorization specification" and/or
     "authentication error number nnnn" when the LogonUser
     and LogonAuth are set to a valid username and password?
 6.6 Why do I get connection refused/reset under heavy loads
     (Windows OOB server)?
 6.7 How can I check which version of MS MDAC I have?
 6.8 What version of MS MDAC do I need?
 6.9 Where do I get WinSock 2 for Windows 95?
 6.10 Why does OOB install fail with "Setup is unable to locate the layout file"?
 6.11 Why do I get "Initialization of the dynamic link library xxx failed"
      dialogues on my server desktop when running in MultiProcess mode?
 6.12 Why cannot I connect to an OOB Server running on a clustered windows
      server using virtual IP addressing?
 6.13 What can't I connect to my OOB Server since installing Windows XP
      Service Pack 2?
 6.14 How do I restart the OOB Server?

7. Operating System Specific - Solaris
 7.1 Why do I get undefined symbol for h_errno?

8. Operating System Specific - OpenBSD
 8.1 Can I use the ODBC-ODBC Bridge for FreeBSD on OpenBSD?

9. Operating System Specific - FreeBSD
 9.1 When linking Perl DBD::ODBC with the OOB on FreeBSD I get errors
     regarding wchar.h what should I do?

10. Operating System Specific - OpenVMS
 10.1 What VMS float types are SQL_C_REAL, SQL_C_DOUBLE and SQL_C_FLOAT?

11. Programming
 11.1 Can I fork child processes after SQLDriverConnect and use the connection
     handle in each one?
 11.2 Can I use a multi-threaded application with the OOB client?
 11.3 I am trying to compile/link my C code and it fails with undefined
      symbol errors?
 11.4 Where can I get help with developing C applications using ODBC?

1. General Questions
--------------------
1.1 What is the Easysoft ODBC-ODBC Bridge
-----------------------------------------

The Easysoft ODBC-ODBC Bridge is database middleware providing access
to a database driver on one machine from another machine on the same
network; e.g. access to MS SQL Server on NT from an application running
on Linux.

1.2 What does it do?
--------------------

The Easysoft ODBC-ODBC comes in two parts, a client and a server.  The
client is a shared object, archive, DLL or shared image containing the
full ODBC 3.5 API. You link your application to the ODBC-ODBC Bridge
client directly or through a driver manager and make ODBC calls. The
ODBC-ODBC Bridge server is installed on a remote machine where you
have a database and an ODBC driver. The ODBC-ODBC Bridge server makes
ODBC calls to the driver e.g. when your application calls
SQLDriverConnect(), the client contacts the server and instructs it to
call SQLDriverConnect() in the ODBC driver for your database (this is
a simplistic view). As far as your application is concerned it is
talking directly to the ODBC driver on the remote machine.

1.3 What versions of ODBC are supported?
----------------------------------------

ODBC 2.0, ODBC 2.5, ODBC 3.0 and ODBC 3.5.

The ODBC-ODBC Bridge has the full ODBC 3.5 API and most of the ODBC
2.0/2.5 API. All the ODBC 2.0 and 2.5 API required to run Perl
DBD:ODBC, PHP and mxODBC is present. However, Easysoft expects new
applications to be written using the ODBC 3.0/3.5 API so this is covered
100%.

1.4 Where can I get it?
-----------------------

http://www.easysoft.com
ftp://ftp.easysoft.com/pub/odbc-odbc-bridge

Beta and pre-release versions of the OOB can be found at:
ftp://ftp.easysoft.com/pub/beta/odbc-odbc-bridge

Please note http://beta.easysoft.com is no longer actively maintained.

1.5 What else do I need?
------------------------

Presuming you already have a database set up and working on a machine
on your network all you need is an ODBC Driver for that database and
the Easysoft ODBC-ODBC Bridge.

The Windows distributions of OOB contain the Microsoft ODBC driver
manager and ODBC administration interface.

The UNIX distributions of OOB contain the unixODBC driver manager.

If you are using Windows 9x you will need to ensure you have WinSock 2
installed (see "Where do I get WinSock 2 for Windows 95?").

1.6 Do I need a Driver Manager?
-------------------------------

Strictly speaking the answer to this question is no. However, if you
are accessing MS SQL Server, MS Access etc on a Windows machine the
server side of the ODBC-ODBC Bridge installs the Microsoft Driver
Manager. In part this is to make the configuration of data sources
easier and to allow the ODBC-ODBC Bridge server to pass concern for
which ODBC driver to load on to the driver manager.

The client side of the ODBC-ODBC does not need a driver manager as you
can link your application directly to it. The client contains much of
the driver manager functionality and this is how the ODBC-ODBC Bridge
can support multiple versions of the ODBC API. Typical
applications/interfaces which are already available on non-Windows
platforms are PHP, Perl DBI, DBD:ODBC, mxODBC and Rexx/SQL. When
building the ODBC-ODBC Bridge with any of these you do not need a
driver manager. A similar situation exists if you write your own
application.

Some applications come with a driver manager e.g. Applixware comes
with iODBC.  The ODBC-ODBC Bridge will work just as well with a driver
manager and it is only required if the application is written to
expect and need a driver manager.

If you have multiple ODBC drivers and you want to pick which one you
use at run time then you need a driver manager. Easysoft recommend the
driver manager incorporated in the unixODBC project which can be found
at http://www.unixodbc.org. The OOB distributions for UNIX contain the
unixODBC driver manager. Generally speaking it is a more flexible
configuration if you use a driver manager.

1.7 How much disk space do I need?
---------------------------------

The OOB requires a different amount of disk space for each platform.
As a rough guide:

Windows (Vista, 2003, XP, 2000, NT, 95/98):

  The Microsoft Installer (MSI) package is 6.5 Mb. The fully installed
  OOB client, server, documentation and examples requires about 7.1 Mb.

Unix 
  
  Four formats of the distribution are available, tar, gzipped tar,
  bzipped tar and compressed tar. These vary in size between 400K and
  8Mb. The fully installed client, server, documentation and examples
  requires about 1.5Mb and an additional 2Mb for unixODBC.

1.8 What is a DSN?
------------------

A data source name is a logical name for a data repository or
database.  Any attributes that define a data source are stored under
the DSN for retrieval by the driver.

In the case of the OOB, the data source name is the key to a set of
attributes in the odbc.ini or the system information (in
Windows). When the application calls SQLDriverConnect or SQLConnect
with a DSN, the OOB client can look up other attributes it needs for
the connection in the odbc.ini or system information.

1.9 Where do I get information about the ODBC API?
--------------------------------------------------

[1] The Microsoft Press (www.microsoft.com/mspress) books and CD
    Microsoft ODBC 3.0 Software Development Kit and Programmer's Reference.
[2] The Microsoft ODBC 3.0 Programmers Reference Volume 1 and 2
    ISBN 1-57231-516-4.
[3] http://www.microsoft.com/odbc - the Microsoft ODBC SDK.
[4] The ODBC SDK documentation can also be found online at
    http://msdn.microsoft.com

1.10 What platforms/OS is OOB available for?
--------------------------------------------

OOB is currently available for the following operating systems and
architectures:

OS Name        Architecture OS Versions    Variations Notes
-------        ------------ -----------    ---------- -----
Linux          X86          1.2.n -  2.6.n mt/non-mt  -
Windows NT     X86          3.51 +         -          -
Windows 95     X86          -              -          WinSock 2 required
                                                      client-only
Windows 98     X86          -              -          client-only
Windows 2000   X86          -              -          -
Windows XP     X86          -              -          -
Windows 2003   X86          -              -          -
Windows Vista  X86          -              -          -
Solaris        Sparc        2.6 - 2.10      mt         -
                                           non-mt     -
Solaris        Sparc V9     2.8 - 2.10     -          64 bit
Solaris        X86          2.8 - 2.10     -          -
FreeBSD        X86          4.2 +          mt/non-mt  -
AIX            RS6000       4.3 +          -          -
SCO OpenServer X86          5 +            -          -
SCO Unixware   X86          7 +            -          -
HP-UX          PA-RISC      10.10 +        -          -
HP-UX          PA-RISC2     11             -          64 bit
Tru64          Alpha        5.0 +          mt/non-mt  -
Sinix          MIPS         5.43 +         -          -
OpenVMS        Alpha        7.1 +          -          Requires UCX 5.0/5.0A
                                                      or above
QNX            X86          6.1            -          -
QNX            X86          4              -          -
Irix           Mips         6.5            mt/non-mt
                                           32/64 bit
Interix        X86          3.5            -          SFU
MAC OSX        PPC          10.2.6-10.3.2  -          -

mt = multi-thread (i.e. built with thread support, thread-safe)

1.11 Where is the latest version of this FAQ?
---------------------------------------------

The most up to date copy of this FAQ is always held on the Easysoft
web site. There are links to a plain text and database driven version
of this FAQ on the OOB product page at http://www.easysoft.com.

Occasionally this FAQ may also be posted to the OOB news group at
news://news.easysoft.com/easysoft.public.odbc-odbc-bridge.

2. OOB Specific
---------------
2.1 How do I build my ODBC application with the OOB?
----------------------------------------------------

If you are using a Driver Manager then consult questions on driver
managers first as generally speaking if a driver manager is installed
your applications should build against the driver manager and the ODBC
driver is just installed. Otherwise, you must compile your ODBC
application (or interface) with the OOB client header files and link
with the OOB client shared object, image or DLL. There are examples
included with the OOB of applications building with the OOB
client. Other documentation is available on building Perl, PHP,
mxODBC, Rexx/SQL etc with the OOB.

2.2 How do I set up a DSN?
--------------------------

In Windows, you use the ODBC Data Source Administrator in the control
panel to define a new data source. Click on add, select the driver for
your database and fill in any dialogues presented to you. If you want
access to a DSN on a Windows machine through the OOB from another
machine you must define a System DSN for the ODBC driver you want
access to and not a User DSN as the latter can only be seen by the
user logged in to Windows.

On non-Windows platforms a DSN is defined in the odbc.ini (or
.odbc.ini) file in the current directory, your home directory or a
system directory like /etc/odbc.ini or SYS$ROOT:odbc.ini.  This file
is a simple text file of the form:

[DSN_name1]
attribute1 = value
attribute2 = value

attributeN = value

[DSN_name2]
attribute1 = value
attribute2 = value

attributeN = value

For a description of the attributes and values see " What attributes
may be specified in a DSN?".  For a description of how the OOB locates
DSNs see "How does the OOB client locate DSNs?"

2.3 What attributes may be specified in a DSN?
----------------------------------------------

There are a number of attributes which may be specified in a DSN.
Here is a list with brief descriptions:

Attribute      Description
---------      -----------

Description    A description of this data source. Note that this is
               restricted to the text on a single line.

Driver         The name of the ODBC driver to use with this DSN.
               If your application is linked with a driver manager you
               will need a Driver attribute, generally set to the
               value OOB (but this will depend on what name the OOB
               was installed as).

ServerPort     The name (or IP address) of the remote machine where
               the OOB server and ODBC driver for your database are
               located and the port where the OOB server is listening for
               incoming OOB client connections. In the ServerPort value,
               separate the OOB server from the port with a colon (:).
               For example, demo.easysoft.com:8888. Note that if you
               specify a server name rather than an IP address, your
               machine must be able to resolve this into the IP address
               via your resolver libraries (e.g. DNS or hosts). The port
               may be either the port number or on UNIX, the name of the
               service (which will be looked up with getservbyname() in
               the /etc/services file).

LogonUser      The name of a user who exists on the Server
               machine. The OOB Server changes to this user when an
               incoming connection is made. This will be a user
               specified in your /etc/passwd file, a NT/Windows
               username or a user in your UAF (VMS).

LogonAuth      The password for the LogonUser.

TargetDSN      The name of the DSN to connect to on the remote
               machine.

TargetUser     The username used to identify the connector to the
               database engine. This is added to the connection string
               as UID=username by the OOB client. This may not be
               required by your database engine.

TargetAuth     The password/authentication_string for the user in
               TargetUser.

BlockFetchSize A flag and a value indicating whether the OOB client
               should do block fetches. A value of 0 indicates block
               fetches should not be performed by the OOB client. A
               value between 1 and 100 specifies the OOB client should
               attempt to use block-fetch-mode.  See question on
               speeding up the database reads.

MetaDataBlockFetch
               Takes a value of 0 (off) or 1 (on) and defaults to 1.
               This is used to enable/disable OOB's MetaData block fetch
               mode which speeds up the retrieval of columns in a meta
               data result set (e.g. SQLTables, SQLColumns etc). Some ODBC
               drivers do not have the necessary functionality to support
               MetaDataBlockFetch and need to have this facility turned
               off. Currently, only one private ODBC driver has been found
               to need MetaDataBlockFetch turning off.
               Introduced version 1.0.0.13.

Unquote_Catalog_Fns
               Applixware has the annoying habit of quoting strings in
               the calls to catalogue functions which can cause a
               failure to match. Specifying this attribute makes the
               OOB remove the quoting.

MetaData_ID_Identifier
               When set causes the OOB client to call SQLSetStmtAttr
               to set the SQL_ATTR_METADATA_ID attribute to
               SQL_TRUE. This means strings used in catalog functions
               are treated as literals.  This is sometimes required by
               old applications which do not realise that ODBC treats
               some characters as wildcards.

DisguiseWide   Takes a value of 0 (off) and 1 (on), default is off.
               When set disguises the column types described by the ODBC
               driver as SQL_Wxyz for applications that do not understand
               wide characters.
               Introduced version 1.0.0.13.

UseOOBDBAuth   Takes a value of 0 (off) and 1 (on), default is off.
               Setting this value to on causes the OOB client to
               ignore the UID/PWD values passed to it via
               SQLDriverConnect in the connection string and use the
               TargetUser/TargetAuth in the registry/odbc.ini DSN
               instead. When UseOOBDBAuth is off the UID and PWD in the
               connection string always overrides
               TargetUser/TargetAuth.

GetInfoPassThru
               OOB by default captures calls to SQLGetInfo for
               driver name, driver version and driver ODBC version
               and returns values relevant to OOB. If you want to
               see the values from the driver at the server end
               set this to 1.

2.4 How does the OOB locate DSNs?
---------------------------------

In Windows, the OOB client uses the {Get|Set}PrivateProfileString
interface to save and retrieve DSN attributes. Therefore, all data
sources should be set up with the ODBC Data Source Administrator.

In non-Windows platforms the data sources are stored in a text file.
The OOB client searches for this text file using the following order:

ODBCINI (environment variable)
<cwd>odbc.ini
<cwd>.odbc.ini (UNIX only, not VMS)
<home>odbc.ini
<home>.odbc.ini (UNIX only, not VMS)
/etc/odbc.ini (SYS$ROOT:odbc.ini for VMS) - system DSNs only
<wherever unixODBC stores DSNs>

Where <cwd> is the current working directory and <home> is the current
users home directory (the HOME environment variable or /etc/passwd
entry in UNIX or SYS$LOGIN in OpenVMS).

If the OOB client cannot find the DSN in the fixed locations it will
attempt to load the unixODBC libodbcinst shared object and use
SQLGetPrivateProfileString(). In this way, if you built unixODBC
yourself with a different --sysconfdir, OOB can still find your DSNs.

The OOB server has no need to lookup DSNs or DSN attributes as it is
acting as an application talking to either a driver manager or an ODBC
driver directly (of course this changes when you are running the OOB
Server on non-Windows machines).

If you are running Apache/PHP built with the OOB, Easysoft recommend
you use /etc/odbc.ini because [1] this is more secure as it is out of
your htdocs directory [2] it avoids possible problems when starting
Apache in a directory other than where your odbc.ini file is located.
See question "Apache/PHP can't seem to find my odbc.ini file or
Datasource not found and no default driver error".

2.5 I only want to retrieve data from the server, are there any tricks
----------------------------------------------------------------------
    to speed it up in read-only mode?
    ---------------------------------

If you have written the application yourselves then using bound
columns and large Array sizes is a great deal more efficient over a
network. The OOB client pulls all the bound columns over in one go
which is a lot quicker than using repeated SQLFetchs and multiple
SQLGetData calls, one per column.

If you do not want to change your application (or cannot) and you are
only reading data from the database (and not using positioned updates,
deletes etc) then the OOB has a built in block-fetch-mode which may be
enabled with the DSN attribute, BlockFetchSize. Add "BlockFetchSize =
n" to the DSN entry you are using where (0 <= n < 100) n is the number
of rows to retrieve in one go. This shows significant speed increases
for the reasons in the paragraph above but may not be used with
certain types of cursors and when doing positioned updates/deletes.

Note that a value of 0 means block-fetch-mode is turned off and the
OOB works as a normal ODBC driver.

A value of 1 is safe to use even if you are doing positioned updates
and deletes and is often faster than with block-fetch-mode turned off.

The OOB performs the following tests to decide whether BlockFetchMode
is possible:

[1] Cursor type must be FORWARD_ONLY
[2] RowArraySize must be 1
[3] there mustn't be any bound columns
[4] if the driver is MS SQL Server then the application must be
    ODBC 3.
    The MS SQL Server driver will not return RowsProcessedPtr to an
    ODBC 2.0 app.
[5] the row bind offset must not have been set.
[6] you must not be using SQLExtendedFetch.

Note from the above checks, BlockFetchSize has no effect when the
application or interface is using bound columns itself to retrieve
data (e.g. Perl's DBD::ODBC).

2.6 How can I get help on using the OOB?
----------------------------------------

[1] Post a message to the
    news://news.easysoft.com/easysoft.public.odbc-odbc-bridge
    news group.
[2] Mail support@easysoft.com.
[3] Consult the http://www.easysoft.com web pages.

Please see the Easysoft Data Access support posting in the
news://news.easysoft.com/easysoft.public.da2k.odbc-odbc-bridge news
group and http://www.easysoft.com/support/main.phtml.

2.7 Where do I report bugs in the OOB?
--------------------------------------

You can report bugs by:

[1] mailing support@easysoft.com
[2] Post a message to the
    news://news.easysoft.com/easysoft.public.odbc-odbc-bridge
    news group.
[3] if you have a support contract you can contact Easysoft support.
    Contact information is available on our web site at
    http://www.easysoft.com.

If you just have a a query then see "How can I get help on using
OOB?".

2.8 How much does a license for OOB cost?
-----------------------------------------

The costs for the ODBC-ODBC Bridge may be found at:

http://www.easysoft.com/sales/pricing.phtml

2.9 When was the first official release of OOB made available?
--------------------------------------------------------------

The final release date for OOB 1.0.0 was 1st December 1999.

2.10 When did the beta versions expire?
---------------------------------------

The first two beta versions (0.2.0.0 and 0.2.2.0) expired 1st July
1999. The third beta (0.2.4.0) expired 1st October 1999.  The third
and fourth betas, 0.4.0.0 and 0.6.0.0 expired 1st December 1999.  Beta
versions generally expire within three months to ensure that beta
testers are using the latest version.

2.11 What do I do now my beta version of the OOB has expired?
-------------------------------------------------------------

Whilst the OOB was still undergoing beta testing then all you had to
do is visit our web site or FTP site and download a newer beta
version. Now that the OOB has completed beta testing and moved into
final release you need to contact sales at sales@easysoft.com for
purchasing information.

2.12 How do I license OOB?
--------------------------

You only need to obtain a license key for the OOB Server although both
client and server sides of the OOB are purchased and licensed
separately.

The OOB Install for Windows includes a license administrator. A short
cut is added to:

Start Menu > Programs > Easysoft > Easysoft Data Access 2000 Licensing
or
Start Menu > Programs > Easysoft > Easysoft Data Access Licensing

called License Manager. You can use the License Administrator to
obtain new licenses either, automatically over the net via a direct
link or via email. You can also view any existing licenses.

The OOB install for UNIX includes a shell program called licshell
which may be used to obtain licenses.

Please also visit http://www.easysoft.com/support/faq.phtml where you
will find a list of online documents about licensing.

2.13 Are there any configurable options for the OOB?
----------------------------------------------------

There are a number of configurable options that affect the OOB client
or server. For Windows, these are specified in the registry and may be
changed via the HTTP interface. For UNIX, they are specified in the
{Settings} section of your odbc.ini (or its equivalent) or the
/usr/local/easysoft/oob/server/esoobserver.ini.

Port          The port where the OOB server is listening for incoming OOB
              client connections. If the OOB server is running on A Windows
              machine then it will need restarting for the changes to take
              effect.

IPAddress     The IP address the OOB Server listens on. This is only
              relevant if you have multiple NICs and only want the OOB
              server to listen on one. The default is for the server to
              bind to port 8888 on INADDR_ANY which means it is listening
              on all local interfaces.

HTTPPort       This option specifies the port on which the OOB Server will
               listen for HTTP requests (note that in UNIX, the HTTP
               Server is only available if the OOB Server is started
               standalone with the "standalone" command line argument
               and not when started from inetd). The default is port
               8890 but it may be any port not in use on your
               machine. If the Flags configurable option bitmask has
               HTTP_Server set then the OOB Server starts
               listening on the specified port for HTTP requests in
               addition to acting in its normal role serving the OOB
               Client. You may use the URL
               http://machine_name:HTTPPort where machine_name is the
               name (or IP address) of the machine running the OOB
               Server and HTTPPort is the port number to communicate
               with the OOB Server from your browser. It can show
               statistics, DSNs and the current values of configurable
               parameters. You can also change configurable parameters
               and define access control.

Timeout        This defines the inactivity timeout in seconds (the
               default is 7200 - 2 hours). This attribute is currently
               only meaningful for Windows platforms. The OOB server
               starts a new thread for each client that connects. If
               there has been no communication in timeout seconds the
               thread exits.

RetryCount     This is the number of additional attempts the OOB Server
               makes at creating a new thread/process to handle an
               incoming connection or obtain a license slot after the
               first attempt fails.

RetryPause     This is the time in seconds the server pauses between
               RetryCounts.

HTTPAdmin      This is the username of the person allowed to make changes
	       to the OOB server via the HTTP interface. This must be a valid
	       username in the operating system the server is running on.
	       If set to the string "disabled" (omit the quotes) then 
	       HTTP authentication is not required (this does not mean
	       the OOB Server stops authenticating incoming ODBC connections).

HTTPNetworkAccess
               The network or IP address for clients allowed to use
               the HTTP interface e.g. 194.131.236.4 only allows one
               machine but if the netmask was 255.255.255.0 then
               setting 194.131.236 would allow anyone on that network.

	       The default is all browser clients have access to the
	       HTTP interface although they may be required to enter a
	       username/password if HTTPAdmin is set to anything other
	       than "disabled".

MaxBookmarkSize
               This attribute specifies the size of the largest
               bookmark the OOB can handle (it defaults to 32). ODBC
               2.0 uses fixed length bookmarks of 4 bytes. In ODBC 3.0
               bookmarks are all variable in size. If you find an ODBC
               driver that needs more than 32 bytes for a bookmark
               please let us know, otherwise the default should be
               fine.

LogDir         This option specifies the directory where log, audit,
               failing sql and statistics files are created
               (see Logging, LogFailingSQL and AuditODBCAccess).

Logging	       This is a bitmask telling the OOB Client or Server what
               sorts of event to log in the log file. This should only
               be used as directed by Easysoft support and will slow
               the OOB down considerably if set.

MaxThreadCount MaxThreadCount is the maximum number of threads or
	       processes the OOB Server will allow at any time. There will
	       be one thread/process for every ODBC connection. If
	       MaxThreadCount is set to 0, there is no limit. The default
	       is 0. You can use this parameter to prevent too many
	       simultaneous connections swamping your server.

MaxClientConnect
	       MaxClientConnect is the maximum number of concurrent
	       connections from a single client (where a client is
	       defined as the IP address of the machine where the
	       client is running). If MaxClientConnect is set to 0,
	       there is no limit. The default is 0. You can use this
	       parameter to prevent people from swamping your machine
	       with ODBC connections.

NetConnectRetryCount 
	       This is the number of times the OOB client will attempt
	       a connection to an OOB Server. Each time a connection
	       attempt fails the OOB client waits (0.1 * connect
	       attempt) seconds before trying again.

	       Possible values are:

	       -1, set to internal OOB default (the default, which is 5)
	       n (n >= 0), set to this value

	       If you are using Enterprise OOB (or OOB version 2 or
	       later) and multiple server definitions in a single DSN
	       you may find lowering this setting from the default of
	       5 an advantage as it reduces the time from the client
	       failing to connect to the first server and starting a
	       connection attempt to the second and subsequent
	       servers.

ListenBackLog ListenBacklog defines the maximum length the queue of
	      pending connections may grow to. It is a value passed to the BSD
	      sockets call listen(). If a connection request arrives with the
	      queue full the client will probably get an error of 
	      ECONNREFUSED and the OOB Server will be totally unaware of
	      the connection attempt. If this happens the OOB client will
	      use NetConnectRetryCount to make multiple connection attempts.

	      Possible values are:

	      1 <= n <= 100 (the default is 20)

	      You should not usually need to change this value as the
	      default is sufficient for all but the very busiest of
	      OOB Servers and having to set a high value is an
	      indication that the server machine is underpowered. In
	      addition, on Windows operating systems, the backlog
	      queue is in non-pageable system memory. For some
	      versions of the Windows operating system (Win 9x and NT
	      workstation) changing this value has no effect since it
	      is hard-wired at 5.

	      Please also see the NetConnectRetryCount for use with
	      the OOB client and the OOB FAQ. 

Flags	      This is a bitmask of operational flags. The bitmasks are:

               0x1 Authentication_Disabled
                   Disable OOB Server authentication
                   (default is clear, i.e. not set)
                   When set the values of LogonUser/LogonAuth
                   specified in the DSN at the client end are
                   irrelevant and the OOB server will NOT become the
                   LogonUser for the duration of the ODBC
                   connection. As a result, this flag should be used
                   with extreme caution as it means anyone with the
                   OOB client who is not denied access via OOB Server
                   access control can gain access to your SYSTEM data
                   sources.It may also inhibit you from connecting to
		   MS SQL Server DSNs which use trusted connections.

               0x2 HTTP_Server
                   Start listening for HTTP connections when the server starts
	           (default is set, 0x2)

	       0x4 MultiProcess
                   The OOB Server starts a new process for each incoming
		   connection instead of a new thread
		   (default is clear, ie. not set and therefore the Server
		   starts a new thread per connection). You might set this
                   if you had an ODBC driver which you know is not thread-safe.
		   Currently this option is only relevant on Windows
		   as UNIX OOB Servers are always MultiProcess.

	       0x8 MetaDataBlockFetch_Disabled
                   If set prevents the OOB client from automatically starting
                   block-fetch-mode for read-only metadata result-sets.
                   (default is clear, i.e. automatic metadata block-fetch-mode
		    enabled).

               0x10 HideSensitive
                   If set prevents the OOB Server administrators username
                   being displayed on the OOB HTTP Server web page for
                   configurable parameters (default is set i.e. no one browsing
                   the configurable parameters web page will see the name of
                   the administrator). Setting this flag also hides
                   whether you have disabled authentication or not.

               0x20 ReverseLookup
                   If set the OOB Server does a reverse lookup on the
                   client's IP address. Connections may be slightly
                   quicker if you clear this flag. The default is set i.e.
                   reverse lookups are performed).
                   If your machine is not configured to resolve IP
                   addresses in to machine names (i.e. not capable of
                   doing reverse lookups via the API gethostbyaddr()
                   this flag must be clear as it can slow connections
		   down considerably.

               0x40 AuditODBCAccess
                   If set audits connections to the OOB Server in an audit
                   trail file. This file is called esoob.access and will
                   be placed in the LOGDIR (see above) directory.
                   The default is clear, i.e. auditing does not take place.

               0x80 FreeStmstsOnDisconnect
                   If this flag is set then the OOB Server frees all
                   existing statements in the driver before calling
                   SQLDisconnect. By default this flag is clear as the ODBC
                   specification says that applications do not have to do this
                   and the driver should quietly do it for them. However, a
                   customer has seen Navision's ODBC driver crash when
                   SQLDisconnect is called from Perl when there are existing
                   statements so setting this flag works around this problem
                   in Navision's driver. The default is clear.

                0x100 ShowProcessTime
                   If set causes the OOB HTTP Server to display kernel
                   and user time used by the OOB Server. The default is
                   set.

                0x200 AutoUpdateConfiguration (Deprecated)
                   If this flag is set then the OOB Server automatically
                   updates its copy of the configuration settings from the
                   registry or ini file. This affects the access control
                   lists, the flags listed here and MaxClientConnect/
                   MaxThreadCount. The values are only updated when 5 seconds
                   elapses with no incoming connections in that time.
                   Disabling this feature reduces accesses to the registry/ini
                   but means the server has to be restarted to pick up
                   configuration changes. The default is off.

                0x400 HTTPAuthAll
                   If this flag is set then all pages in the OOB server
		   HTTP administration interface are protected by HTTP
                   authentication. i.e. You will be prompted for the
                   HTTPAdmin username and password before any pages are
		   returned to you (the realm is "ESOOBServer").
		   Note that if HttpAdmin is set to the text "disabled"
		   you are never prompted even when HTTPAuthAll is enabled.

                0x800 ConnectionPooling
		   If this flag is set then the OOB Server
		   automatically sets the SQL_ATTR_CONNECTION_POOLING
		   attribute to SQL_CP_ONE_PER_DRIVER to enable
		   connection pooling in the driver manager for the
		   ODBC driver.  Note that ConnectionPooling is
		   meaningless when the OOB Server is running in
		   MultiProcess mode (see above).

                0x1000 LogFailingSQL
                   If this flag is set then when any call to
		   SQLPrepare/SQLExecDirect fails the SQL is logged to
		   the file oob_sql.log in the LogDir. As some DBMS
		   only parse the SQL at SQLPrepare time sometimes you
		   do not find out the SQL is incorrect until
		   SQLExecute is called. To catch these SQL errors too
		   the OOB Server saves the first 1K of any SQL
		   passing SQLPrepare successfully so it may be logged
		   if SQLExecute fails. For this reason turning this
		   flag on will have some impact on the speed of the
		   server and memory use so it should be used
		   sparingly.

                   This is extremely useful when developing
		   applications or web services and can be used to
		   monitor errors.

                0x2000 AllowDBBrowse
		   If this flag is set then the data sources listed on
		   the Data Sources web page may be browsed to get
		   lists of tables, columns in table and even rows of
		   data from tables.

                0x4000 AutoDenyNonOoobClients
		   If this flag is set then any clients connecting to
		   the OOB Server port and sending initial data down
		   the socket which is not the EasyRPC protocol will
		   be added to the internal denied ACL. Clients
		   automatically added in this way are not visible on
		   the security page (although a warning is displayed
		   on the front page of the web administrator) and are
		   removed from the ACL when the OOB Server is
		   restarted or when the ACLs are changed on the security
		   page.

		0x8000 AllowDSNBrowse
		   If AllowDSNBrowse is not enabled then OOB Clients
		   cannot obtain a list of SYSTEM DSNs from the OOB
		   Server. This affects the ODBC API
		   SQLBrowseConnect() and the population of the
		   TargetDSN dropdown in the OOB Client Setup
		   dialogue.

		0x10000 NoStatusArrayResize
                   This is a workaround for an issue in the SQL Server
                   ODBC driver, which can write off the end of the parameter
                   status array (SQL_ATTR_PARAM_STATUS_PTR) when the
                   SQL_ATTR_PARAMSET_SIZE is reduced. For details about
                   when this issue can happen, see question "Why do I get an
                   Access Violation in MS SQL Server ODBC Driver?"

		0x20000 WriteStatsOnExit
                   When the OOB Server service (on Windows) or the Standalone
                   process (UNIX) exits, the contents of the Web Administrator
                   Statistics screen are written to a file called
                   esoob_stats_<dd>_<mm>_<yyyy>_<hhmmss>.stats, where
                   <dd> is the day number, <mm> is the month number, <yyyy> is
                   the year number and <hhmmss> is the time in hours, minutes
                   and seconds.

                   This file will be written into the directory defined by the
                   server configurable parameter LogDir:

                   Note, in OOB versions prior to 2.1 this flag did not exist and
                   the file was always written. In OOB 2.1 the default for this
                   new flag is off. If you would like pre-2.1 behaviour, enable
                   this option.

	The Flags value may be changed using check boxes on the OOB
	HTTP Server configuration page. If you are not running the OOB
	web administrator you add these values together to produce the
	Flags value and change it in the esoobserver.ini file (UNIX)
	or in the registry (Windows).

2.14 How much memory do I need for the OOB Server on NT?
--------------------------------------------------------

How long is a piece of string?

The OOB Server for NT can run in 2 configurations.

The default is to create a new thread for every incoming ODBC
connection. The server under this configuration requires about 2Mb
and approximately 250K per thread but this latter number starts at 250Kb
and rises depending on what you do with the ODBC driver you are
connected to.

An alternative configuration for non-thread-safe ODBC drivers
instructs the OOB Server to start a new process per connection. This
requires approximately, 2Mb for the main server and 2Mb+ for each
connection.

2.15 Why does it take so long to connect to the server?
-------------------------------------------------------

In our experiments it takes less than 1/10 second to connect an
application linked directly with the OOB client on Linux to a data
source on NT over a 100Mb Ethernet link where both machines are on the
same LAN and are mostly idle. This is a small fraction of a second
slower for interpreted languages like Perl or if there is a driver
manager (like unixODBC) between the application and the OOB client.

If you are experiencing connect times much slower than 1 second you
should check the following:

[a] Are the client and server machines on the same Local Area Network
    (LAN)?  Connection times can increase dramatically if they are
    not. Try pinging the server from the client and see what return
    times you get.

    e.g.

    ping www.easysoft.com
    PING pubmail.easysoft.com (194.131.236.4): 56 data bytes
    64 bytes from 194.131.236.4: icmp_seq=0 ttl=255 time=0.6 ms
    64 bytes from 194.131.236.4: icmp_seq=1 ttl=255 time=0.1 ms

    In this case less than 0.6ms - quick. Machines not on the same LAN
    can show a much greater time and this will be reflected in your
    ODBC connect times.

[b] Disable Reverse Lookups in the OOB Server. Performing a reverse
    lookup on an IP address can be quite slow depending on how the
    machine is configured to perform the reverse lookup. You can do
    this from the OOB HTTP Server configuration screen.  See question
    "Are there any configurable options for the OOB".

[c] Check that you do not have any tracing turned on. There are multiple
    places tracing and logging may be turned on:

    [1] Make sure that in your odbc.ini file any lines starting with
        "Logging = number_greater_than_0" are commented out with # or
        just delete them (this is OOB tracing).

    [2] If you are using the unixODBC Driver Manager then remove lines
        that look like "Trace = yes" and "TraceFile = file" or ensure
        Trace is set to no.

    [3] Make sure you have not turned on tracing at the server
        end. You can check this through a web browser to
        http://server_machine:8890 and then Configuration. Logging
        should be set to 0. Alternatively on UNIX examine the server
        odbc.ini/esoobserver.ini file or on Windows examine the
        registry for:

  	HKEY_LOCAL_MACHINE\
  	SOFTWARE\
  	Easysoft ODBC-ODBC Bridge\
  	Configuration\
  	System\
  	Settings\
  	Logging

     [4] If using Windows make sure tracing in the driver manager is
         not turned on. You can check this by going in to the ODBC
         Administrator and clicking on the tracing tab.

     All of the above default to tracing off or require positive
     action to turn tracing on.

[d] You can make the OOB Server start a new thread or a new process
    for each connection. By default, the OOB server starts a new
    thread but if bit 3 (value 0x4) of the configurable parameter
    "Flags" is set the server starts a new process - this is a lot
    slower. You can check Flags as above for Logging.

[e] Obtaining a license slot adds a small amount of time to a
    connection (much less than 1/10s).  However, if you are limited
    through your license to a set number of concurrent connections the
    OOB Server, by default, tries 5 times at 3 second intervals to
    obtain a license slot before giving up. The retry attempts and
    pause between attempts is configurable via the RetryCount and
    RetryPause parameters.


[f] Check your application is not turning ODBC tracing on by calling
    SQLSetConnectAttr(SQL_ATTR_TRACE, SQL_OPT_TRACE_ON).

[g] Check how many DSNs you have in your odbc.ini file or the ODBC
    administrator (Windows). For non-Windows platforms move the DSN
    you are using to the start of the file - does this make a
    difference?  For Windows, re-create your DSN with a name which
    makes it nearer the start of the DSN list (e.g. name it "aaaa" or
    something like that) - does this make a difference?

If after checking the above you are still want faster connections then
try using persistent ODBC connections (e.g. odbc_pconnect in PHP) as
these hold connections open for use by the call to an ODBC connect
function with the same DSN, username and password. If you are making
a lot of repeated connections to the same DSN this can be a lot faster.

Another alternative if you are in control of the ODBC application is
to connect then prepare statements before they are required. Then,
when you need to execute the SQL all you have to do is bind the
parameters in the prepared statement.

NOTE: If you are using persistent connections or connecting a long
time before you use the connection see the question "Why do my
connections to the OOB server seem to be dropped after a while?

NOTE: If you are using MS SQL Server 7.0 then see the question
"Why are my connections to SQL Server so slow?".

NOTE: If you are using Windows 2000 then see the question "Why
have connection times to MS SQL Server slowed down since upgrading to
Windows 2000 Server?"

2.16 Why can I see more tables in MS SQL Server than normal?
------------------------------------------------------------

When running the OOB client connected to the OOB Server and the MS
SQL Server ODBC driver you may find more tables are visible than when
connecting directly to the same MS SQL Server data source with the same
username and password. By default the OOB Server for Windows NT is
installed as a service running with administrator privileges. When the
OOB client connects to the server you pass a login username and
password which the OOB Server uses so it can become the specified
user. For MS SQL Server data sources using trusted connections the MS
SQL Server ODBC driver appears to notice you were an administrative
user and are now someone else (possibly noticing the real and
effective UIDs). Depending on how your database is set up it may then
show you tables you would not have otherwise seen.

If this causes you concern you can change the OOB Server service to
run as someone other than the administrative user. You do this by
starting the service manager administrative program in the control
panel and editing the startup options to specify a username and
password. You should then stop the OOB Server service and restart it.

2.17 Are any usernames/passwords transmitted as plain text over the network
---------------------------------------------------------------------------
     connection?
     -----------

No. Any usernames and passwords supplied in the connection string or
stored in the registry/odbc.ini are encrypted before sending them
across the network connection between the client and server.

In addition, usernames and passwords for OOB data sources in Windows
which are stored in the registry are encrypted.

All information in a connect string is encrypted before passing this
across a network connection.

2.18 Can I strip(1) the shared objects and executables?
-------------------------------------------------------

You can run strip on the shared objects and executables distributed
with the OOB to remove the symbols but this may affect any support
Easysoft can supply. Generally speaking we advise you not to strip the
shared objects and executables as the OOB is not large.

2.19 Can I run the OOB Server on UNIX without the inetd SuperServer?
--------------------------------------------------------------------

Yes. By default the OOB Server for UNIX is installed as a service with
entries in the /etc/services and /etc/inetd.conf files (inetd is
informed of the configuration file changes)(OOB also supports xinetd).
However, the OOB Server for UNIX will run standalone as well. To run the
OOB Server standalone you need to either:

[1] use a different port address from the entry in /etc/services for
    esoobserver. Edit
    <install_path>/easysoft/oob/server/esoobserver.ini and change the
    entry "Port = 8888" to specify a different port.

[2] comment out the esoobserver entries in /etc/services and
    /etc/inetd.conf and send a SIGHUP to inetd.

Once you have done the above you start the server by changing
directory to <install_path>/easysoft/oob/server and issuing the
following command:

./esoobserver standalone

The server will start listening for connections on the Port specified
in the esoobserver.ini file. You should really start the OOB Server as
root or it will be unable to change to the LogonUser specified in the
OOB client DSN. However, if you do not start the OOB Server as root
then no logon authentication will be performed and all clients will
run on the server as the user who started the OOB Server.

You can add a line to start the OOB Server standalone to one of your
rc scripts to have the OOB Server start up every time the machine
boots.  The file you need to change depends on your Operating System
so it is best to consult your system administrator. On RedHat for
Linux a good place is /etc/rc.d/rc.local.

When the OOB server is started standalone it will by default fork a
process to handle HTTP requests on port 8890 (this can be changed in
the esoobserver.ini file). You can then use your browser to contact
the OOB HTTP server using http://machine.domain:8890 and see
connection statistics, configurable parameters and access control.  If
you want to change configurable parameters or access control via the
HTTP interface you must define HTTPAdmin in the esoobserver.ini to an
existing user on your machine and you will need to enter the password
when viewing/making_changes on some protected pages. In this case the
OOB Server must be running as root on some machines to verify the
username/password.

2.20 Can I make the OOB statistics web page refresh more/less frequently?
-------------------------------------------------------------------------

Yes. The OOB HTTP Server uses a set of template files in to which the
dynamic data is inserted before sending it back to your browser. The
template file for the main page (the statistics page) is index.html.
You should find this file in the directory called templates wherever
you installed the OOB Server. Edit the index.html file and near the
top you will see 'meta http-equiv="refresh" content="60;
URL=/index.html'.  Change the 60 (the refresh time in seconds) to
whatever you would like.  You should note that setting this very low
will cause the OOB server thread handling HTTP requests to be kept
busy which might reduce the response time to the OOB ODBC server thread
so times much less than 60 seconds are not recommended.

2.21 Why does the OOB HTTP Server statistics page show active threads
---------------------------------------------------------------------
     when there are no connections?
     ------------------------------

The OOB HTTP Server statistics page is a guide to what is happening
and what has happened in the OOB ODBC server. The OOB Server registers
a new active connection when a client successfully connects and a thread
(or process) is started up to handle the ODBC connection. The server does
not deregister the connection (as far as the statistics are concerned)
immediately the client disconnects. The server looks for disconnected
threads/process when there has been no incoming connection for a period
of 5 seconds. This gives priority to incoming connections. This also
affects the peak concurrent connection count e.g. if you write a program
which connects and disconnects in one second but this is repeated every
3 seconds the active connections and peak concurrent connections will
appear to increase until your program stops.

There is one situation in which is this not the case. If you set
MaxClientConnect or MaxThreadCount to a value other than 0 to limit
the connections, the server checks for terminating threads/processes
every time a connection is made, so the active and concurrent counts
will always be up to date immediately after an ODBC connection from a
client.

This does not affect licensing in any way i.e. if you have a license
limited to N concurrent connections the server does not use the active
connections statistic to decide whether you can connect or not.

2.22 Why cannot I login to the HTTP Administrator when running the OOB
----------------------------------------------------------------------
     server as a named user instead of in the system account?
     --------------------------------------------------------

By default the OOB Server is installed as a service which runs in the
system account - this is usual for NT system services. If you elect to
run the OOB Server under a named account that account may not have
privilege to become another user. Certain pages in the OOB HTTP
administrator are protected using HTTP authentication and when you
login, the HTTP server temporarily becomes the user you log in as.  If
the OOB Server does not have privilege to become that user you will
not be able to login to those pages.  A solution is to disable HTTP
authentication in the OOB HTTP Server by either:

[1] restart the OOB Server service in the system account, go to the
    configuration web page and change the HTTPAdmin username to
    disabled.
[2] Edit the registry key:

     HKEY_LOCAL_MACHINE/
     SOFTWARE/
     EASYSOFT ODBC-ODBC BRIDGE/
     CONFIGURATION/
     SYSTEM/
     SETTINGS/
     HTTPADMIN

    and change it to the text "disabled" (omit the quotes).

One imagines that the reason you want to run the OOB Server under a
named account is for added security but in fact you are opening up
security holes doing this. Firstly, anyone with the OOB client can now
connect to your data and secondly, to administer the OOB Server via
HTTP you will have to disable HTTP authentication. Disabling HTTP
authentication means anyone can change the OOB Server settings.

Easysoft recommend you run the OOB Server in the system account.

2.23 Is there any tracing in OOB I can use for debugging my application?
------------------------------------------------------------------------

The OOB client and server both have a mechanism for creating a trace
file.  How this is turned on depends on the platform and whether it is
the client or server. The types of tracing output may be selected by
use of a bitmask. Please treat this as an undocumented feature as the
mechanism for initiating tracing, the bit mask values and where the
trace file is written may change. Please also remember that the
tracing output was written to help us debug OOB problems so there is
no documentation on the format or contents of the trace file. Having
said this, the information is useful when debugging your application is
fairly obvious.

Some types of tracing generate a tremendous amount of output. Any kind
of tracing will slow the client or server down significantly as the
tracing output is flushed to the file every write.

On non-Windows platforms tracing is turned on by setting the Logging 
value in the Settings section of the odbc.ini file in the CURRENT WORKING
DIRECTORY to a non-zero value. e.g. your odbc.ini in the current working
directory would look something like this:

{Settings}
Logging = 0xnnnnnn

[DSN1]
attribute = value
.
.

with the DSNs are optional, as they may be in another odbc.ini file
(e.g. /etc).  Note, OOB only looks for the Logging value in the
odbc.ini in the current working directory. For UNIX, the output trace
file is normally named esoobclient.log_<PID> or esoobserver.log_<PID>
(where <PID> is the process ID) and will be placed in /tmp UNLESS the
file already exists and is a symbolic link.

In Windows you set the Logging value in the registry key:

HKEY_LOCAL_MACHINE\
SOFTWARE\
EASYSOFT ODBC-ODBC BRIDGE\
CONFIGURATION\
SYSTEM\
SETTINGS\

For Windows, the output files are esoobclient.log or esoobserver.log
and will be placed wherever the LogDir configuration option points.

In both cases the Logging value is a string value representing a bit
mask and may be specified in decimal or in hex (if a 0x is
prefixed). The bitmask values are listed below; you should just add up
all the ones you want.

0x1   Log entry points in to functions e.g. the function called and the
      arguments passed to it. Generally useful for ODBC application
      developers.

0x2   Log exit points from functions e.g. return status and sometimes
      other values returned. Generally useful for ODBC application
      developers.

0x8   Special logging not covered by other bit masks. It is unlikely
      much, if anything, of this will make a great deal of sense to
      anyone but Easysoft as it output OOB internal information.

0x10  OctetLengths, IndicatorPtrs, Row status values etc in bound
      parameters, bound columns or getdata.

0x20  Log internal (non-ODBC-API) OOB function entry/exit points
      depending on whether 0x1 and/or 0x2 set. Generally speaking
      little of this will be useful to anyone who does not know the
      internals of OOB.

0x40  Log calls to the OOB Server (client-side) or ODBC driver
      (server-side).

0x80  Log ODBC diagnostics. This may create an odbc_bridgec_diags.txt
      (client) or odbc_bridges_diags.txt (server) file in the LogDir
      directory.  This may be a useful logging option if the code that
      outputs diagnostics in your application is broken as the
      diagnostic will be logged when SQLError or SQLGetDiagRec is
      called.

0x100 Log query text in SQLPrepare/SQLExecDirect. Another useful one
      if you want to check what your application is asking the driver
      to do.

0x200 Log the connection process. This will show how OOB has retrieved
      the attributes for your DSN and what it is passing to the ODBC
      driver.

0x400 Log attribute retrievals or changes e.g. calls to
      SQLSetConnectAttr etc.

0x800 Start main OOB Server logging. There is no ODBC information in
      this output at all, it simply outputs what the main OOB Server
      is doing before the ODBC connection starts and will generate a
      huge amount of output over time. The log file is esoobstart.log.

0x1000 Log the actual data sent or retrieved.

0x2000 Output timing information e.g. how long an SQLPrepare,
       SQLExecDirect took.

2.24 How do I specify connection attributes for my DSN that are not
-------------------------------------------------------------------
     configurable in the odbc.ini?
     -----------------------------

My ODBC driver requires additional attributes that I have specified in
my odbc.ini file but they do not seem to get through to the driver.
The OOB only picks up from the odbc.ini file the attributes specified
in the answer to "What attributes may be specified in a DSN?". If you
need to specify additional attributes you must pass them in the
connection string to SQLDriverConnect().

For Perl, see the answer to the question "How can I put attributes
other than the DSN in my Perl DBI->connect call?".

For PHP and OOB there is a simple trick you can use.  Add the
attributes to string passed to odbc_connect() as the DSN name,
separating the attributes with semicolons.

e.g. if you were calling odbc_connect with

odbc_connect("mydsn","username", "password") and want to pass the ENG

attribute with a value of engine use:

odbc_connect("mydsn;ENG=engine","username","password")

This only works with OOB because calls made by applications to
SQLConnect in OOB are actually redirected to SQLDriverConnect once
"DSN=" is prefixed to the DSN name in SQLConnect's first argument.
However, the disadvantage of this method is that if you are using a
Driver Manager (e.g. unixODBC) the string passed must be less than 32
(SQL_MAX_DSN_NAME) characters so it is rather limiting (the same does
not apply to Perl as Perl calls SQLConnect and if that fails,
SQLDriverConnect).

For applications that you have the source code for you will need to
edit the code, find the call to SQLDriverConnect and add your
attributes to the string argument 3 (InConnectionString). If the
application uses SQLConnect instead of SQLDriverConnect (e.g. isql
that comes with unixODBC) you will need to change it to use
SQLDriverConnect (see the demo.c program in the OOB examples directory
for code using SQLDriverConnect).

2.25 Why does SQLDataSources list a data source which returns the
-----------------------------------------------------------------
     Datasource not found message when I connect to it?
     --------------------------------------------------

If you are using the unixODBC driver manager (included in the OOB
distribution) then SQLDataSources (or DBI->data_sources if you are
using Perl) will return the data sources found in the odbc.ini file (it
does not check the validity of each data source). However, if any of
these data sources are missing the Driver attribute or have a Driver
attribute for which there is no corresponding driver in the
odbcinst.ini file then unixODBC will return:

IM002, Data source name not found, and no default driver specified.

If your application is linked directly with OOB (no driver manager)
then although the OOB client supports SQLDataSources it is limited
support and you are better using a driver manager.

2.26 How can I encrypt the network connection between the client and server?
----------------------------------------------------------------------------

Easysoft recommend Zebedee (http://www.winton.org.uk/zebedee).

Zebedee is a simple program to establish an encrypted, compressed
"tunnel" for TCP/IP or UDP data transfer between two systems.

zebedee is a neat little program which works on various unixes and
Windows and is distributed in source and binary form. It works with
two compression libraries (zlib and bzip2) and currently one
encryption library, blowfish.

zebedee is easy to build and works quite simply. You run zebedee on
your server where it listens on a predetermined port. You then run
zebedee on the client machine where you specify the server, server
port where zebedee is running and the port for the normal service you
want to use. The zebedee client then returns a port on your local
machine which your client software can use to communicate with the
remote service using encryption and compression. The client and server
application and service code do not need to be changed in any way.

The OOB performs a fair amount of compression of network data itself
so it is normally advisable to omit the compression from the zebedee
connection.

2.27 Does the OOB install for UNIX support xinetd?
--------------------------------------------------

xinetd (http://www.xinetd.org/) is an open source replacement for
inetd which combines inetd, tcpwrappers and a considerable amount of
other functionality. RedHat 7 (and perhaps other distributions) now
appears to use xinetd.

The install scripts for UNIX distributions up to 1.0.0.23 do not
support xinetd although it is relatively trivial to manually add the
OOB Server to the xinetd configuration post install.

To install the OOB Server under xinetd manually:

[1] Locate the xinetd.conf file. It is usually /etc/xinetd/conf.

[2] Examine the xinetd.conf file and look for a an includedir command.
    If you find an includedir command change to that directory and add
    a new file called esoobserver that looks like this:

    service esoobserver
    {
        socket_type             = stream
        protocol                = tcp
        wait                    = no
        user                    = root
        server                  = /bin/bash
        server_args             = /usr/local/easysoft/oob/server/server 
        disable                 = no
    }

    Make sure the server argument is a valid shell on your system.

[3] If in [2] you did not find an includedir command then the above
    entry can be added to the end of your xinetd.conf file.

[4] Once you have made your changes you need to tell xinetd to reread
    its configuration files. You usually do this by sending it a USR1
    signal e.g. kill -USR1 process_id_of_xinetd. However, as xinetd
    can be configured to use different signals you should check the
    signal your xinetd requires.

2.28 Do you have to have DNS working for correct operation of the OOB?
----------------------------------------------------------------------

The OOB Server does not need DNS working on your network. However, if
you enable the OOB configurable parameters "ReverseLookup" then the
OOB server will perform a reverse lookup on the client's IP address to
obtain the client machine name. In this case DNS must be working and
your resolver library must be able to do the reverse lookup or it can
result in long connection times.

The OOB client only needs to resolve a machine name into an IP address
if you set the Server attribute in your odbc.ini/registry to a machine
name. You can avoid this by referring to the server machine's IP
address instead.

2.29 Can multiple machines running the OOB client simultaneously use the
------------------------------------------------------------------------
     same OOB Server?
     ----------------

Yes. The OOB Server does not service one connection at a time. The OOB
server accepts a connection and hands it off to a thread or process to
deal with that connection and immediately goes back to accepting new
connections. As a result an OOB Server can be handling connections
from many different client machines at the same time.

2.30 How does the OOB client handle refused connections?
--------------------------------------------------------

The OOB client will retry connection attempts if the server operating
system returns ECONREFUSED (connection refused). The reason for this
is that on some platforms (notably NT workstation) the listen backlog
can only be set to a low level so if there is a sudden rush of
connections the operating system may turn some down before the OOB
Server sees them. When ECONREFUSED is received by the client it waits
connection_attempt * 0.1 seconds before trying again up to a maximum
of NetConnectRetryCount times.

Here is an example where NetConnectRetryCount is 5 (the default) and
the server always refuses the connection:

connect attempt 1 - refused by server
wait 0.1 seconds
connect attempt 2 - refused by server
wait 0.1*2 seconds
.
.
.
connect attempt 5 - refused by server
client gets error diagnostic:

08001:1:4:[Easysoft ODBC (Client)]
  Client unable to establish connection
HY000:2:4:[Easysoft ODBC (Client)]
  Connection refused, connect(), after 5 attempts

and here is an example where the first few attempts are refused due to
the listen backlog queue being full but by the third attempt the
backlog is cleared and the connection accepted:

connect attempt 1 - refused by server
wait 0.1 seconds
connect attempt 2 - refused by server
wait 0.1 * 2 seconds
connect attempt 3
 connection accepted by server operating system

The NetConnectRetryCount is 5 by default but it may be modified in the
OOB Settings off the DSN dialogue (Windows) or in the {Settings} section
of your odbc.ini file. e.g.

{Settings}
NetConnectRetryCount = 3

Please note NetConnectRetryCount is a global setting for all DSNs.

2.31 How does the OOB client support connection timeouts?
---------------------------------------------------------

Connection timeouts are set by an application calling
SQLSetConnectAttr with the attribute
SQL_ATTR_CONNECTION_TIMEOUT. Currently (OOB 1.0.0.23) only uses the
connection timeout when actually connecting to the server and not for
all ODBC calls. If you set the connection timeout and then the connect
does not succeed in the timeout period you will get a diagnostic like
this:

08001:1:4:[Easysoft ODBC (Client)]Client unable to establish connection
HY000:2:4:[Easysoft ODBC (Client)]Connection attempt timed out

However, there are some important points:

[1] Connection timeouts are not currently supported in Windows or
    multi-threaded versions of the OOB client for UNIX.

[2] OOB classes the connection phase as obtaining the IP address of
    the server machine and connecting to it. This means that if you
    specify the ServerPort attribute as a name rather than an IP address
    your system resolver library will be used (possibly examining
    /etc/hosts or performing a DNS query). On some operating systems,
    gethostbyname(), the call used to resolve a machine name into an
    IP address cannot be interrupted and the connection timeout will
    not work. If this is a problem for you then specify the server
    machine as an IP address or tell your resolver library to
    consult /etc/hosts before DSN and place an entry in /etc/hosts.

[3] Calls to SQLSetConnectAttr/SQLSetConnectOption for the
    SQL_ATTR_CONNECTION_TIMEOUT are passed on to the ODBC driver at
    the server end.

[4] Connection timeouts at the network level are not usable since
    many operating systems hard-wire them.

[5] If you are writing your own application linked with the OOB client
    and are working in an environment where network cables may be
    pulled out (network connections lost) then you can put alarm() and
    SIGALRM handlers (or sigsetjmp) around your ODBC calls to
    implement connection timeouts.

2.32 What does the OOB do if an application terminates abnormally?
------------------------------------------------------------------

If an application using the OOB client terminates abnormally e.g. the
application seg faults or is interrupted with SIGINT, the socket
connection to the OOB server will be closed by the operating system.

The OOB server spots the closed socket connection and attempts to tidy
up the ODBC connection to the ODBC driver. It will loop through all
connections created by that client and call SQLDisconnect for each
one. If any fail to disconnect due to SQLSTATE 25000 (transaction in
progress) the server will call SQLEndTran(SQL_ROLLBACK) i.e. it will
attempt to roll back the transaction so the connection may be closed.
All handles in the ODBC driver are freed with SQLFreeHandle.

As an example, if you had some Perl which ran through OOB to MS
SQL Server and it turned off autocommit, updated a row in a table and
then the perl was stopped (say you hit ctrl/c or whatever your
interrupt key sequence is) before the transaction was committed the
OOB server would roll back the updates so the connection to the ODBC
driver could be closed.

NOTE:
The OOB Server only notices the disconnected client when the ODBC
Driver Manager and ODBC driver return from the last ODBC call. As a
result, if you execute a query which takes a long time and kill your
client application whilst the query is executing, the connection will
not be dropped by the server until the query has completed.

2.33 I have no root access. How do I tell OOB/unixODBC to use odbc.ini
----------------------------------------------------------------------
     and odbcinst.ini files not in /etc?
     -----------------------------------

You do not need to be root to install the OOB client but certain parts
of the installation of the unixODBC driver manager are not usually
possible as a non-root user. Since unixODBC is built with the
sysconfdir configuration option set to /etc, the odbcinst.ini file
containing all the installed ODBC drivers resides in /etc by default
(as does the odbc.ini containing SYSTEM data sources). You can tell
unixODBC to look elsewhere for these files by setting and exporting
the ODBCSYSINI environment variable to point to another directory you
have write access to and creating the odbc.ini and odbcinst.ini files
there instead.

e.g.
Say you have installed OOB and unixODBC in your home account.
Create a etc directory in your home account, create odbcinst.ini and
odbc.ini files as below and set/export ODBCSYSINI.

cd $HOME
mkdir etc
cd etc
echo "[OOB]" > odbcinst.ini
echo "Description = Easysoft ODBC-ODBC Bridge" >> odbcinst.ini
echo "Driver = $HOME/easysoft/oob/client/libesoobclient.so" >> odbcinst.ini
echo "Setup = $HOME/oob/client/libesoobsetup.so >> odbcinst.ini
echo "FileUsage = 1" >> odbcinst.ini
> odbc.ini
ODBCSYSINI=$HOME/etc
export ODBCSYSINI

2.34 Why do I get the error "Not enough attributes for connection" since
------------------------------------------------------------------------
     upgrading OOB from a pre 1.0.0.27 release?
     ------------------------------------------

OOB was changed in version 1.0.0.27 to require the LogonUser and
LogonAuth attributes (see the Changes.txt file entry for
4-Apr-2001). This change was made because a number of new OOB users
were getting confused by the authorisation error 87 (invalid
parameter) when LogonUser was not specified and authentication was
enabled in the OOB Server.

Prior to 1.0.0.27, if you had authentication turned off in the OOB
Server you did not have to specify LogonUser/LogonAuth. From 1.0.0.27,
if you have OOB Server authentication turned off you will have to
specify a value for LogonUser/LogonAuth although the actual value is
meaningless.

2.35 How can I tell what version of OOB I am running?
-----------------------------------------------------

Client:

On Windows, go to control panel -> ODBC or control panel ->
administration -> data sources, select the drivers tab, and scroll
down to Easysoft ODBC-ODBC Bridge. The version is next to the driver
name. In UNIX, look for the file /usr/local/easysoft/oob_install.info,
scroll to the end of it and the last version installed should be
present. Alternatively, you can run the demo program, select option 4
to test a connection, and the OOB client version is output.

Server:

If you are running the OOB Server HTTP administration interface simply
browse http://myservermachine:8890 and the version is displayed at the
top of the page. If you cannot do this, change directory to where the
server is installed (on Windows, <SYSTEMROOT> and in UNIX
/usr/local/easysoft/oob) and run "esoobserver version" or
"./esoobserver version".

2.36 Do you have to install the OOB Server on the same machine as your
----------------------------------------------------------------------
     Database?
     ---------

No. You need to install the OOB Server on a machine where there is an
ODBC driver for your database. In some cases you might not have access
to the database server machine so you can install the OOB Server on
another machine where there is an ODBC driver for your database so
long as that ODBC driver can communicate with the database server.

You may also want to do this if you have a firewall between your client
machines and the database server which only allows connections on the
database server port.

In the case of some database servers, it is sometimes more efficient
to install the OOB Server on another machine. This can sometimes be
the case with MS SQL Server which often runs with higher priority
meaning an OOB Server running on the same machine does not get a fair
share of the CPU.

2.37 Why do I get "[unixODBC][Easysoft ODBC (Server)]Memory allocation error"?
------------------------------------------------------------------------------

There is more than one way of getting this error but the most common
reason is the application calling SQLBindCol with a very large BufferLength
argument. This often arises from the following sequence of events:

SQLPrepare(select bigcol from table)
SQLExecute
SQLDescribeCol(1) - returns bigcol is a big number (e.g. 1073741824) in size
SQLBindCol(1, BufferLength=number_returned_from_SQLDescribeCol)

The OOB Client and OOB Server are running on different machines. If
the application calls SQLBindCol with a very large buffer size it is
saying I have this much memory available for the column data (even if
it doesn't).  The OOB Server needs to allocate this same buffer size
to hold the data returned from the ODBC driver and in the case of very
large buffers that is sometimes not possible. In most cases the
application did not intend to do this or does not have that much
buffer space available. There is one specific example of this with
Perl's DBD::ODBC driver and SQL_WLONGVARCHAR columns:

Support for SQL_WLONGVARCHAR is available in DBD::ODBC only if the
ODBC header files it is built with include sqlucode.h. In some versions
of DBD::ODBC sqlucode.h is not included and so when an SQL_WLONGVARCHAR
column is seen (ntext in SQL Server) DBD::ODBC does not pay attention
to LongReadLen and uses the value from SQLDescribeCol.

When building DBD::ODBC 0.45 or earlier with OOB or unixODBC the
Makefile.PL needs to be altered to include sqlucode.h output to
dbdodbc.h. To do this:

[1] decide if you are building DBD::ODBC against the unixODBC driver
    manager or OOB directly. This affects which section of Makefile.PL
    you need to alter.

[2a] If building DBD::ODBC against OOB directly then look for the
     section of the Makefile.PL starting with

     "elsif ($myodbc eq 'esodbc') {"

     move down the blocks of lines from there until you see print
     commands writing #include lines to SQLH. At the end of the 3
     print commands (but before the end of the block '}') add:

     print SQLH qq{#include <sqlucode.h>\n};

[2b] If building DBD::ODBC against the unixODBC driver manager then
     look for the section of the Makefile.PL starting with

     "elsif ($myodbc eq 'unixodbc') {"

     Now follow the same instructions under [2a].

[3] After setting up all the environment variables DBD::ODBC needs run
    the "perl Makefile.PL" and you should now have a file called
    dbdodbc.h which contains a line like this:

    #include <sqlucode.h>

[4] Continue building, testing and installing DBD::ODBC as usual.

2.38 How do I use oobping?
--------------------------

oobping is a small program distributed with the OOB since version
1.0.0.35. oobping is a valuable tool for checking OOB connectivity and
diagnosing connection problems or connection timing issues.

For Windows distributions you will find oobping.exe in
installdir\Easysoft\Easysoft ODBC-ODBC Bridge.

For UNIX OOB distributions there are two versions of oobping called
oobpings (a statically linked version) and oobpingd (a dynamically
linked version linked against the libesoobclient shared object) which
may be found in /usr/local/easysoft/bin. To use oobpingd you may need
to set and export your LD_LIBRARY_PATH/LD_RUN_PATH/LIBPATH to included
/usr/local/easysoft/oob/client and /usr/local/easysoft/lib.

oobping has the following command line:

oobping [-h host | -d ODBC_connection_string] {-t port}
        {-u osuser} {-p ospassword} {-e}

where:

-h host
   The name or IP address of the machine where the OOB Server is.
-d ODBC_connection_string
   The ODBC connection string is that defined by ODBC.
   i.e. a list of semi-colon separated attribute=value pairs.
   e.g. DSN=test;UID=fred;PWD=bloggs;
   
   If you specify -u and/or -p as well as -d
   "LogonUser=xxx;LogonAuth=yyy;" will be added to the end of the
   connection string where xxx and yyy are the values specified for
   -u and -p.
-t port
   The port on which the OOB Server is listening
-u osuser
   A valid username on the "host" operating system
-p ospassword
   A password for the user specified with -u
-e Show time to complete the requested operation (post OOB 1.1.0.0)

If you believe you have a connection problem from your application
then you can use oobping to help diagnose the problem. Work through
these examples:

[1] Check the OOB Server is running on the correct machine and listening
    on the correct port:

    ==========
    oobping -h myserver -t 8888

    Host: myserver, Port: 8888
    Attempting connection...OK
    Examining Server...
        OOB Server Version: 1.1.0.00
        OOB Server Name: OOB
    ==========
    
    NOTE: oobping defaults the port to 8888 so you can omit -t.

    Here oobping connects to port 8888 on the machine myserver where
    an OOB Server is clearly running as oobping reports it finds OOB
    Server version 1.1.0.00.

    If you specify the wrong port and some other service is listening on
    it you will get a variety or errors like the one below when pointing
    oobping at an SMTP server on port 25.

    ==========
    oobping -h myserver -t 25
    Host: myserver, Port: 25

    Failed to receive data
    Packet (size=842149920) too big for buffer (size=256)
    ==========

    If there is nothing listening on the specified port then you will
    get a connection refused error and you should check the OOB Server
    is configured to use the port you specified and is running.
    e.g.

    ==========
    oobping -h myserver -t 8889
    Host: myserver, Port: 8889

    Connection refused, connect(), after 5 attempts
    ==========

    If you have specified access control rules in the OOB Server then you
    might see an error such as this:

    ==========
    oobping -h myserver -t 8888
    Host: myserver, Port: 8888

    Client denied access due to access control rule.
    ==========

    Here the machine you are running oobping on has been denied access
    to the OOB Server. You should check the OOB Server access control
    rules on the security page of the OOB web administrator.

[2] Once you are sure a connection can be made to the OOB Server with
    oobping (as in [1]) you can check OOB Server authentication.
    The -u and -p arguments to oobping allow you to specify a valid
    operating system username and password.

    NOTE: If you have disabled authentication in the OOB Server then
    whatever username and password you specify should work.

    NOTE: If the usernames or passwords you are using contain spaces
    or characters that the shell might interpret you should enclose
    them in single quotes (UNIX) or double quotes (Windows).

    NOTE: The values specified with -u and -p are equivalent to the
    OOB Client DSN attributes LogonUser and LogonAuth.
    e.g.

    ==========
    oobpings -h myserver -t 8888 -u 'A User' -p 'mypassword'
    Host: myserver, Port: 8888
    Attempting connection...OK
    Examining Server...
        OOB Server Version: 1.1.0.00
        OOB Server Name: OOB
    Trying to authenticate...OK
    ==========

    If there is something wrong with the username or password the output
    will look something like this:

    ==========
    oobpings -h myserver -t 8888 -u 'A User' -p 'mypassword'
    Host: myserver, Port: 8888
    Attempting connection...OK
    Examining Server...
        OOB Server Version: 1.1.0.00
        OOB Server Name: OOB
    Trying to authenticate...Fail
    Authentication failure (error number 1326)
    ==========

    In this case the error returned by the remote username/password
    authentication service is 1326 (as the server was on Windows, this
    is a Windows error code). You can look up all the common error
    codes in the OOB FAQ.

[3] Once you have completed [1] and [2] above you should have the name
    of a server where an OOB Server is running and the port it is
    listening on. You should also have a valid operating system
    username and password and be enabled in the OOB Server access
    control rules. You can now check connectivity to a specified
    remote data source (DSN).

    There are two ways to check the connection to a remote DSN with
    oobping. The simplest way is to add a local DSN to your odbc.ini
    file and then specify the DSN in the -d argument as
    "DSN=dsnname". This method tests you have defined the local OOB
    client DSN correctly and put the definition in the right file. An
    alternative method is to specify all the connection attributes in
    the -d argument, not just the DSN.

    e.g.
    Suppose as a result of checking [1] and [2] above you have the following
    information:

    Server = myserver
    Port = 8888
    LogonUser = me
    LogonAuth = mypassword

    Now you add to that the name of the target DSN on myserver (this
    is the OOB client attribute TargetDSN). Note that the TargetDSN
    MUST be a remote SYSTEM data source, you cannot access USER data
    sources. If the database also needs login information the database
    username and password are specified using the OOB attributes
    TargetUser and TargetAuth.

    If you want to test a DSN in your odbc.ini file then it would look
    something like:

    [mydsn]
    ServerPort = myserver:8888
    LogonUser = me
    LogonAuth = mypassword
    TargetDSN = mysystemdsn
    TargetUser = dbusername
    TargetAuth = dnpassword

    NOTE: Later when using the unixODBC driver manager you will need
    to add "Driver=OOB" to the above DSN but this is not needed when
    using oobping.

    You can run oobping as follows:

    ==========
    oobping -d "DSN=mydsn;"
    Using Connection string :
    DSN=mydsn;
    Connected OK

    01000:1:5701:[NetConn: 032bc620][Microsoft][ODBC SQL Server Driver]
    [SQL Server]Changed database context to 'pubs'.
    01000:2:5703:[NetConn: 032bc620][Microsoft][ODBC SQL Server Driver]
    [SQL Server]Changed language setting to us_english.
    OutConnectionString:
    DSN=mydsn;UID=dbusername;PWD=dbpassword;SERVERPORT=myserver:8888;
    TARGETDSN=mysystemdsn;LOGONUSER=me;LOGONAUTH=mypassword;

    Connected to database:  pubs
    DBMS Name:  Microsoft SQL Server
    Driver Name:  esoobclient
    Driver Version:  01.00.0043
    Disconnecting
    ==========

    Here you passed the ODBC connection string "DSN=mydsn" to the OOB
    client via oobping. The OOB client did not have sufficient
    attributes in the connection string to define what it should do,
    so it looked up the DSN 'mydsn' in the odbc.ini file to get
    additional attributes where it found ServerPort, LogonUser,
    LogonAuth, TargetDSN, TargetUser and TargetAuth. The OOB client
    then connected to the OOB Server on myserver port 8888, logged you
    in with LogonUser/LogonAuth values and finally connected via ODBC
    to the remote data source 'mysystemdsn'. In the above example the
    DSN pointed to MS SQL Server and there were some informational
    diagnostics returned saying the language is "us_english" and the
    database is "pubs" (not all databases will return informational
    messages on the connection). The OutConnectionString is a string
    returned by the OOB client which you can use to connect to this
    data source again (see below). The final messages show the
    database, DBMS Name, Driver name/version (OOB in this case
    obviously).

    Instead of specifying just the name of a DSN to oobping and defining
    the other connection attributes in the odbc.ini file you can specify
    all the connection attributes in one go and not use an odbc.ini file.
    The OutConnectionString above shows you what connection string you
    could have passed to the OOB client to connect without a DSN (if
    you remove the "DSN=mydsn;").

    e.g.

    oobping -d "UID=dbusername;PWD=dbpassword;SERVERPORT=myserver:8888;
    TARGETDSN=mysystemdsn;LOGONUSER=me;LOGONAUTH=mypassword;"

    would produce the same result as above.

    You might be slightly confused why you specify
    TargetUser/TargetAuth in the odbc.ini file but UID/PWD in the
    connection string.  Strictly speaking, the ODBC defined attributes
    are UID/PWD and they are passed to the database for database
    authentication. As far as ODBC connection strings are concerned
    UID/PWD and TargetUser/TargetAuth are synonymous in OOB but if
    specified in the odbc.ini file you should alway use
    TargetUser/TargetAuth.

    Now you know how to use oobping with connection string here are some
    examples of common problems you might see:

    ==========
    oobping -d "UID=dbuser;PWD=dbauth;TargetDSN=test;LogonUser=me;LogonAuth=mypassword"
    Using Connection string :
    UID=dbuser;PWD=dbauth;TargetDSN=test;LogonUser=me;LogonAuth=mypassword

    IM002:1:0:[Easysoft ODBC (Client)]
    Data source not found and no default driver specified
    HY000:2:0:[Easysoft ODBC (Client)]
    general error: Missing attribute(s): SERVERPORT
    ==========

    The initial diagnostic, IM002 is defined by ODBC but as it rather
    vague the OOB client added a secondary more helpful diagnostic.
    Here the OOB connection attribute 'ServerPort' was omitted and so the
    OOB client did not know which server to connect to.

    ==========
    oobping -d "ServerPort=myserver:8888;UID=dbuser;PWD=dbauth;TargetDSN=test;LogonUser=me;LogonAuth=mypassword"
    Using Connection string :
    ServerPort=myserver:8888;UID=dbuser;PWD=dbauth;TargetDSN=test;LogonUser=me;LogonAuth=mypassword

    28000:1:18456:[][Microsoft][ODBC SQL Server Driver][SQL Server]
    Login failed for user 'dbuser'.
    ==========
    
    The above error comes from MS SQL Server and suggests the database
    password 'dbauth' is not correct for the database user 'dbuser'. This
    error illustrates an important point with ODBC errors and that is how
    to identify what component is reporting the error. You should examine
    the components in [], the one furthest right is the reporting component
    and as you move left through the components you are moving closer to
    the OOB client.

    e.g. If you specified a TargetDSN which did not exist on the server
    machine the driver manager on the remote machine would be the component
    reporting the error and so the diagnostic (for Windows) would be:

    IM002:1:0:[][Microsoft][ODBC Driver Manager]
    Data source name not found and no default driver specified

    The other important thing to note here is that oobping outputs any
    ODBC diagnostics as:

    ODBC State : diagnostic sequence : ODBC native error: text

    The native error code is specific to the component reporting the
    error e.g. in the SQL Server login failure above you can look up
    native error code 18456 in the SQL Server documentation which
    should tell you precisely what circumstances this is reported.

[4] Checking connection times.

    From OOB after version 1.1.0.0, oobping has the -e option which
    times the requested operation. This can be invaluable in
    diagnosing a slow connection and determining which phase the
    problem is occurring in.

    Any of the operations mentioned above may also use the -e switch.
    A simple example is:

    ==========
    oobping -e -h myserver -t 8888
    Host: myserver, Port: 8888
    Attempting connection...OK
    Examining Server...
        OOB Server Version: 1.1.0.00
        OOB Server Name: OOB
    Time for execution: 0.16s
    ==========

    If this is repeated with -u and -p you can work out the extra time
    required to perform the operating system logon:

    ==========
    oobping -e -h myserver -u myosuser -p mypassword
    Host: myserver, Port: 8888
    Attempting connection...OK
    Examining Server...
        OOB Server Version: 1.1.0.00
        OOB Server Name: OOB
    Trying to authenticate...OK
    Time for execution: 0.52s
    ==========

    This example clearly demonstrates the extra time required to authenticate
    a user.

2.39 How do I reset the OOB web administrator username?
-------------------------------------------------------

When you install the OOB Server for Windows, the install asks you for
a valid Windows username to use for HTTP authenticated access to the
OOB web administration interface. You need to know that username and
its associated password to make configuration changes to the OOB
Server. If you chose to not enter a username during the installation
the username is set to "disabled" which disables HTTP authentication.

If you know the current username for the OOB HTTP administrator you
can make this change through the web interface.

If you forget the username you entered during the installation then
you need to edit the registry key:

     HKEY_LOCAL_MACHINE/
     SOFTWARE/
     EASYSOFT ODBC-ODBC BRIDGE/
     CONFIGURATION/
     SYSTEM/
     SETTINGS/
     HTTPADMIN

and change HTTPADMIN to either [a] a new valid Windows username or [b]
the string "disabled" (do not enter the quotes) which disables HTTP
authentication. After this change is made you need to restart the OOB
Server service from the service manager.

When prompted by the OOB web administrator for the username and
password you must enter exactly the same string for the username that
is in the above registry key. You may also prefix the username with a
Windows domain using the '/' separator (e.g. mydomain/username) or use
'.' for the domain to signify it is a local user account and not a
domain account.

On UNIX the HTTPAdmin configuration setting can be found in
<install_path>oob/server/esoobserver.ini.

2.40 Why does the OOB Server Windows Service terminate unexpectedly?
--------------------------------------------------------------------

Since OOB 1.2.13 if you are running the OOB Server as a service in
multi-threaded mode (the default) and an exception is caught by the
OOB Server it will shut itself down. The reason for this is that the
exception could have occurred anywhere (including the ODBC driver you
are using) and there is no way for the OOB Server to correct the
problem and no way for it to protect the other threads in the service.
On later versions of Windows it is possible to set the service manager
to monitor services and restart them for you after a specified time.

If you are running in multi-process mode and an exception occurs in
your ODBC driver, only process the OOB Server created to handle that
ODBC connection will exit. However, you should still investigate the
problem.

If the OOB Server catches an exception it will write an entry to the
application event log with details of the exception and will also
write an esoob.exception file into LogDir. If you need help
identifying the issue it is this log or event you need to send to us.

Some exceptions in third party drivers and products we have found are
detailed in this FAQ. A common one in the MS SQL Server ODBC driver is
detailed in "Why do I get an Access Violation in MS SQL Server ODBC
Driver?"

2.41 How do I run an OOB Server on UNIX at reduced priority?
-----------------------------------------------------------

Firstly we should say that this is not a recommendation to run the OOB
Server at a reduced priority but we have been asked this
question. Usually the best course of action is to let the operating
system work out the scheduling.

By default, the OOB Server on UNIX runs under inetd. The inetd
configuration runs the script /usr/local/easysoft/oob/server when a
client connects to the OOB Server port. This script runs the
esoobserver program.

If you want to reduce the priority of the OOB Server you can "nice"
the esoobserver process in this script (see man nice). Priorities on
UNIX usually run from -20 (the highest priority to 19 (the lowest
priorty). By default, most processes will start up with the default
priority of 0. To reduce the priority you set the process priority to
a higher number. e.g. when the default is 0, setting the priority to 5
lowers the process priority.

To do this for all OOB Server processes you need to edit the file
/usr/local/easysoft/oob/server and prefix the last line:

./esoobserver inetd

with a nice command to reduce the priority (see the man page for your
nice command as they are not all the same). An example for Linux is:

nice -n5 ./esoobserver inetd

2.42 What does "Communication link failure" mean?
------------------------------------------------

Generally speaking this means the OOB Client has lost contact with the
OOB Server unexpectedly. This usually only happens if the OOB Server
process handling the client connection has terminated unexpectedly
e.g.  if the server was shut down, if the OOB Server timed out the
client. It can also happen if there was a segmentation fault or bus
error in the OOB Server, unixODBC or the ODBC driver you were
connecting to. You should report this to Easysoft Support at
support@easysoft.com. Please include the versions of all sotware being
used, the platforms involved and the name of the ODBC driver at the
server end you were using.

2.43 What is the OOB demo server and how do I use it?
-----------------------------------------------------

The OOB demo server is an OOB Server running on the machine
demo.easysoft.com and listening on port 8888. If you install the OOB
Client a demo datasource is created which you can use to test your OOB
Client installation:

[demo]
Driver = OOB
ServerPort = demo.easysoft.com:8888
LogonUser = demo
LogonAuth = easysoft
TargetDSN = pubs
TargetUser = demo
TargetAuth = easysoft

The TargetDSN "pubs" is a read-only database containing tables you can
query from the machine you have installed the OOB Client on. Your
client machine will need access to demo.easysoft.com and connection
through your firewall (if you have one) through port 8888.

This datasource on the demo server is only provided as a convenient
method of testing your OOB Client connection.

2.44 How do I upgrade to a newer version of OOB?
------------------------------------------------

The best way is to contact us at Easysoft and we can help you with the
upgrade process.

Upgrades of OOB will require a new license, so don't download and
upgrade an existing licensed server until you have organised to get a
new license.

Generally speaking you do not have to upgade your OOB Server just
because you upgraded your OOB Client(s) or vice versa. If you are
concerned about compatibility contact us before upgrading.

3. Trouble Shooting
------------------
3.1 Why do I get connection refused errors from the client?
-----------------------------------------------------------

If you get errors such as:

08001:1:4:[Easysoft ODBC (Client)]Client unable to establish connection
HY000:2:4:[Easysoft ODBC (Client)]Connection refused, <error text>

then the ODBC-ODBC Bridge server is not listening on the specified
port or the operating system refused the connection due to the listen
backlog queue filling (in this latter case see the question "Why do I
get connection refused under heavy loads?".  First check the DSN entry
you are using in the odbc.ini (or .odbc.ini or ODBC Administrator) is
correct. The attribute to check is SERVERPORT. If the server is up and
running on the specified machine, listening on the specified port you
should be able to telnet to that port and see if the server sends its
startup protocol message. e.g. if SERVERPORT is demo.easysoft.com:8888,
you should be able to telnet to port 8888 on demo.easysoft.com.

e.g. telnet demo.easysoft.com 8888

You should see something like this:

87FA9694x1:0:1998-1112-0000000001001:NT^02:4.0.1381^03:Intel^04:4^05:^06:Âp^07:1^

(Do not worry if it is not exactly the same as this depends on OOB
version, operating system and machine type).

If the telnet fails to connect then nothing is listening on that port
and you should check the port used on the server and make sure the
server is running. If you get connected but then see a connection
closed by foreign host message then you should see other questions in
this section.

If you are connecting to a non Windows server then check you
/etc/inetd.conf and /etc/services files or equivalent. These should be
similar to those below which are for the default installation:

/etc/services
esoobserver      8888/tcp                # Easysoft ODBC-ODBC Bridge

/etc/inetd.conf
esoobserver      stream  tcp     nowait  root    /bin/sh /bin/sh /usr/local/easysoft/server/server

This should have been done for you by the installation. The important
parts are:

[1] The name used in the /etc/services file should match the name used in
    the /etc/inetd.conf (esoobserver in the example).
[2] The 8888 is the port which inetd will listen to on the server's behalf.
    There must only be one 8888 in the /etc/services file. If 8888 is taken
    by another service simply replace it with an unused port number and
    change the SERVERPORT attribute in any odbc.ini files which reference
    this machine.
[3] The "/bin/sh bin/sh" columns in the /etc/inetd.conf file must be the
    path to a valid shell. If you suspect these trying running the named
    shell from the prompt e.g. /bin/sh. Sometimes, UNIX machines have a
    file called /etc/shells which lists valid shells.
[4] The last column in the inetd.conf file should be a path to a shell
    script which runs the esoobserver. The default installation is shown
    above where the shell script is:

    #!/bin/sh
    cd /usr/local/easysoft/server
    ./esoobserver inetd

    Check this script is executable and try running it. If esoobserver
    does not exist then you have not yet created a binary of the ODBC-ODBC
    Bridge linked with your ODBC driver. See BUILDING in the docs directory.

If you are connecting to a Windows server then you should look at the
following list for possible problems:

[1a] If on NT check that the NT service manager is running and the Easysoft
    ODBC-ODBC Bridge service is started. If the Easysoft service is not
    running start it.
[1b] If on Windows 95 then you have to start the esoobserver manually -
    see the Start Menu -> Programs -> Easysoft -> ODBC-ODBC Bridge
    program group and click on OOB Server.
[2] By default the service listens on port 8888. Run "netstat -a" from
    a DOS prompt to check that something is listening on port 8888.
[3] Check that the esoobserver.exe program runs by executing it from a
    DOS prompt. You should get a message saying the command line is
    missing a method followed by some help text.
[4] If on NT check the Application event log to see if there are any messages
    from the Easysoft service.
[5] The final checks all require examining the registry and are beyond
    the scope of this document. If you get to this stage please contact
    Easysoft Support for assistance.

3.2 Why do I get connection closed by foreign host messages when I try
----------------------------------------------------------------------
    to telnet to the port the server is listening on?
    -------------------------------------------------

First check all the points under the question "Why do I get
connection refused errors from the client?"
Connection closed by foreign host implies you got a connection then it
was prematurely disconnected.

If you are connecting to a non Windows server then you should check
the following:

[1] If you are running tcpwrappers make sure the client host is
    allowed to connect to the esoobserver service on the server
    machine. You will need to check your /etc/hosts.allow and
    /etc/hosts.deny files. See the man page on hosts_access and
    tcpwrappers. If your esoobserver entry in inetd.conf does not
    contain something like tcpd then you are probably not running
    tcpwrappers. Note that the default installation will not use
    tcpwrappers as this is a site consideration.

[2] Check that the script pointed to by the esoobserver entry in the
    inetd.conf file exists, is executable and runs the correct image.
    If you have not linked the Easysoft ODBC-ODBC Bridge server with an
    ODBC driver then this will be the problem. To access a remote database
    the server component of the ODBC-ODBC Bridge needs a local ODBC Driver.

[3] Check you system logs for other possible problems.

If you are connecting to a Windows server then we suggest calling
Easysoft Support once you've made the checks in the previous questions.

3.3 Why do my connections to the OOB server seem to be dropped after a while?
-----------------------------------------------------------------------------

The OOB Server has an inactivity timer which by default is set to 7200
seconds.  If a client connects to the server and does nothing for 7200
seconds (2 hours) the server will terminate that connection. This can
cause problems with applications using persistent connections
(e.g. PHP can do this) as if one of the connections is not used for 2
hours, it is terminated but PHP ( up to PHP 4 beta3) does not
recognise this and blindly attempts to continue with the connection.

The timeouts are there to stop unnecessary connections building up and
generally a useful feature. You can turn off the inactivity timeout by
setting it to 0 or just increase it to the period you desire.  See the
question "Are there any configurable options for the OOB" for
information on other OOB configurable parameters and how to set them.

3.4 Why do I get "Data source not found and no default driver" message when
---------------------------------------------------------------------------
    I am sure I have defined the DSN in my odbc.ini file?
    -----------------------------------------------------

If you get this error and are sure that a DSN exists with the same name
as the one you specified, check for the following:

[a] The section for the DSN in the odbc.ini file needs to contain the
    following entry:

    Driver = OOB

    -or-

    Driver = OOB_r

    for the thread-safe OOB Client driver.</p>

[b] The odbcinst.ini file needs to contain an entry for the OOB Client
    driver. The entry looks similar to this:

    [OOB]
    Description = OOB
    Driver = /usr/local/easysoft/oob/client/libesoobclient.so.1
    Setup = /usr/local/easysoft/oob/client/libesoobsetup.so
    UsageCount = 1

    -or-

    [OOB_r]
    Description = OOB (MT)
    Driver = /usr/local/easysoft/oob/client/libesoobclient_r.so.1
    Setup = /usr/local/easysoft/oob/client/libesoobsetup.so
    UsageCount = 1

    for the thread-safe driver.

    If the entry is missing, look at "Post installation steps for
    non-root installations" in the "Installing on Unix" section of the
    OOB manual for instructions on how to add it.

3.5 Why do I get authorisation failures from the client.
--------------------------------------------------------

There can be multiple reasons for this depending on which element of
the connection is turning down the connection. You have to look at the
ODBC error diagnostics from SQLError(), SQLGetDiagRec() or SQLGetDiagField()
to see where the connection is being turned down.

If the Easysoft ODBC-ODBC Bridge Client/Server has turned down the
connection then you will get a messages similar to this:

28000:1:1326:[Easysoft ODBC (Client)]Invalid authorization specification

Here you should check the LogonUser and LogonAuth attributes of your
client DSN. They should be a valid username and password for logging
on to the server machine. This has nothing to do with the database engine.

See the question "Why do I get "Invalid authorization specification"
when LogonUser and LogonAuth are set to a valid username and password"
where the error number (in the above case 1326) may be looked up.

If your database engine requires a username/password then these are
specified as UID and PWD in the connection string or alternatively
as the ODBC-ODBC Bridge attributes TargetUser and TargetAuth. Check your
odbc.ini (.odbc.ini or the ODBC Administrator) to make sure these are
valid for your database. Here is an example from MS SQL Server:

28000:1:18456:[Microsoft][ODBC SQL Server Driver][SQL Server]Login failed for user 'Fred'.

3.6 How do I find out why an ODBC call is failing?
--------------------------------------------------

The best why to discover the problem is to call SQLError or
SQLGetDiagRec with the same handle used in the ODBC SQL API
call. These functions return a status and error text which may used to
identify the problem.

A small C example is:

    ret = SQLDriverConnect(hdbc, NULL, in_connection_string, SQL_NTS,
    			   out_con_str, sizeof(out_con_str),
    			   &out_con_str_len, SQL_DRIVER_COMPLETE);
    if (!SQL_SUCCEEDED(ret))
    {
    	int		i=0;
	SQLRETURN	ret;
	char		state[7];
	SQLCHAR		text[1024];
	SQLSMALLINT	len;
	SQLINTEGER	native;
	char		cbuf[2048];

	while(SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_DBC, hdbc, ++i, state,
    				          &native, text, sizeof(text), &len)))
    	{
            sprintf(cbuf, "error: %s:%d:%ld:%s\n",
	            state, i, native, text);
    	    fprintf(stderr, cbuf);
    	}
    	exit(1);
    }
    
This will print the error diagnostic for the last call using a
connection handle which may look like this:

error: IM002:1:0:[Easysoft ODBC (Client)]
 Data source not found and no default driver specified

The state value (IM002) may be looked up against the function to find
out why it failed.

You may retrieve error diagnostics from Perl DBI, PHP, mxODBC and
other ODBC interfaces in a similar way.

3.7 Why can't I connect to the data source?
-------------------------------------------

There can be many reasons for getting SQL_ERROR back from
SQLDriverConnect or SQLConnect.  See question "How do I find out why
an ODBC call is failing" first. The most likely reasons are:

IM002 - DSN or TargetDSN not found.  The DSN specified in the
        connection string could not be found by the OOB client in the
        odbc.ini file (or equivalent) (or the Driver Manager could not
        find the DSN) or the TargetDSN attribute was missing from the
        DSN or connection string. See also HY000 below.

        The MOST common cause for this when going to a Windows server
        is setting TargetDSN to a USER DSN instead of a SYSTEM DSN.
        Check the DSN on your Windows machine is a SYSTEM DSN.

28000 - Invalid authorization specification. Either the
        LogonUser/LogonAuth attribute pair or TargetUser/TargetAuth
        attribute pair were incorrect. The LogonUser/LogonAuth must be
        a valid username/password pair used by the OOB server to logon
        to the target machine. The TargetUser/TargetAuth are converted
        to UID=name,PWD=name and passed in to the remote
        SQLDriverConnect where the ODBC driver uses them for database
        logon (if they are required).

08001 - Client unable to establish connection. The machine specified
        in the Server attribute could not be found, it is not running
        the OOB server or one of many other possible networking
        issues.  Check the Server attribute in the specified DSN is a
        valid machine name (or IP address), check the name can be
        looked up via DNS (if you are using DNS or examine the hosts
        file), check you are on the same network by pinging the target
        server, check the Port attribute in the specified DSN is
        correct, try telnetting to the Server machine on port Port.

HY000 - A general error. A common mistake might be not specifying all
        the connection attributes required to connect to the
        server. e.g.  omitting the SERVER attribute from the DSN in
        the odbc.ini file in UNIX/VMS. In this case you will get IM002
        and a secondary error of HY000 explaining why.

4. Application/Driver-specific
------------------------------

4.1 Perl Related
----------------

4.1.1 How do I use Perl with OOB?
---------------------------------

You need to obtain the Perl modules, DBI and DBD::ODBC. These may be
obtained from your nearest CPAN archive. Instructions for building
Perl DBI, DBD::ODBC and OOB are contained in the Perl_DBI_DBD_ODBC
file contained in the docs directory of the OOB distribution.

4.1.2 What versions of Perl modules can I use with OOB?
-------------------------------------------------------

OOB has been tested with DBI 1.02 to 1.48 although it is likely to
work with all recent versions.

OOB has been tested with DBD::ODBC 0.20 to 1.13 although it is likely
to work with all recent versions.

You should check DBI and DBD to make sure you have the minimum Perl
requirements before attempting to install DBI, DBD::ODBC or OOB.

If you are running DBI 1.38 or above you can check installed versions
of DBI and DBD's using:

perl -MDBI -e 'DBI->installed_versions'

If you are using DBI prior to 1.38 you can use the following commands
to find out the version of DBI and DBD::ODBC:

perl -e 'use DBD::ODBC; print $DBD::ODBC::VERSION;'
perl -e 'use DBI;print $DBI::VERSION;'

For Windows change the ' above to ".

4.1.3 Where can I find more information about Perl DBI and DBD:ODBC?
--------------------------------------------------------------------

Perl DBI and DBD page:
http://dbi.perl.org/
perldoc DBI (once you've installed DBI has many useful references)

DBI Users mailing list archive:
http://www.bitmechanic.com/mail-archives/dbi-users/

The Perl you need to know (for web authoring):
http://wdvl.com/Authoring/Languages/Perl/PerlfortheWeb/index.html

Recently (March 2000) the long awaited book by Alligator Descartes and
Tim Bunce, "Programming the Perl DBI" was released (ISBN
1-56592-699-4).  This is an excellent book for anyone writing Perl DBI
and DBD::ODBC.

4.1.4 Do I have to set DBI_DSN, DBI_USER and DBI_PASS  environment variables
----------------------------------------------------------------------------
     before running my Perl script?
     ------------------------------

Not unless your Perl script uses these environment variables.

The DBD::ODBC installation and test procedure requires these environment
variables to be set because it calls DBI->connect without any arguments.
From the DBI documentation:

=====
$dbh = DBI->connect($data_source, $username, $password, \%attr)

The $data_source value should begin with "dbi:driver_name:". The
driver_name specifies the driver that will be used to make the
connection. (Letter case is significant.)

As a convenience, if the $data_source parameter is undefined or empty,
the DBI will substitute the value of the environment variable DBI_DSN.
If just the driver_name part is empty (i.e., the $data_source prefix
is "dbi::"), the environment variable DBI_DRIVER is used. If neither
variable is set, then connect dies.

If $username or $password are undefined (rather than just empty), then
the DBI will substitute the values of the DBI_USER and DBI_PASS
environment variables, respectively.  The DBI will warn if the
environment variables are not defined.
=====

The documentation also suggests that using these environment variables
is not recommended for security reasons and that this mechanism is
intended to simplify testing. To avoid using the DBI_xyz environment
variables specify the values directly in the call to DBI->Connect:

DBI->Connect('dbi:ODBC:dsn_name', 'username', 'password')

Obviously you can prompt for the username/password.

4.1.5 How can I put attributes other than the DSN in my Perl DBI->connect call?
-------------------------------------------------------------------------------

From DBD::ODBC 0.21 you can put all of the connection attributes you
can specify in your odbc.ini in the connection string passed to
DBI->connect().

e.g.

Suppose your odbc.ini looked like this:

[dsn_name]
ServerPort = demo.easysoft.com:8888
LogonUser = fred
LogonAuth = password
TargetDSN remotedsn

You can do away with the entire odbc.ini file and use the following
Perl instead:

my $DSN = 'Driver={OOB};ServerPort=demo.easysoft.com:8888;';
$DSN = $DSN . 'LogonUser=fred;LogonAuth=password;TargetDSN=remotedsn';

my $dbh = DBI->connect("dbi:ODBC:$DSN",
		       "database_user",
		       "database_password")
          || die "Database connection failed: $DBI::errstr";

This can be particularly useful if you want to hide your usernames and
password for instance if you did not want them visible in the odbc.ini
file. You could retrieve the username and password from somewhere else
or even prompt for them.

4.1.6 How can I debug my Perl DBI, DBD::ODBC?
---------------------------------------------

Print out the contents of $DBI::errstr when an error occurs. This
often shows more detail, e.g. If the ODBC driver posts multiple errors
all of them can be seen.

You can enable Perl DBI tracing for all handles using DBI class method
with:

DBI->trace($trace_level)
DBI->trace($trace_level, $trace_filename)

To enable trace information for a specific handle use the similar
$h->trace.

Trace level is a number between 0 and 9 but usually 2 is sufficient.

More detailed information is included in the Perl documentation. Try
typing perldoc DBI. You might also like to look up the DBI_TRACE
environment in the Perl DBI documentation.

Recent versions of DBI include DBI::Shell which allows you to use DBI
to examine your database from a shell session. This can be a useful
way of verifying that you driver is installed and working. Start dbish
with either:

perl -MDBI::Shell -e shell
or
dbish

You will be provided with a choice of drivers and then once a driver
is chosen, a choice of data sources. e.g.:

$ dbish
DBI::Shell 10.6 using DBI 1.13 

WARNING: The DBI::Shell interface and functionality are
=======  very likely to change in subsequent versions!

Available DBI drivers:
 1: dbi:ADO
 2: dbi:ExampleP
 3: dbi:ODBC
 4: dbi:Proxy
Enter driver name or number, or full 'dbi:...:...' DSN: 3

Enter data source to connect to: 
 1: DBI:ODBC:Postgres
 2: DBI:ODBC:test
Enter data source or number, or full 'dbi:...:...' DSN: 2
Connecting to 'DBI:ODBC:test' as ''...
@DBI:ODBC:test> 

You can now enter dbish commands and SQL to query/change your
database.  A good start is usually "/table_info" which lists all your
tables. See perldoc DBI::Shell for a list of the commands.

4.1.7 Why do I keep getting data truncated errors in my Perl?
-------------------------------------------------------------

If you are getting truncation errors when retrieving data for a column
check what sort of column it is. Perl DBI needs to be told about long
columns or the data will be truncated. You can do this just after a
DBI->connect with:

$dbh->{LongReadLen} = 32768; # some big number

4.1.8 Why does Perl DBD::ODBC appear to open the DEFAULT data source with OOB?
------------------------------------------------------------------------------

Since DBD::ODBC 0.21, Perl has required an ODBC driver manager (or at
least some of the functions a Driver Manager supplies). In addition,
since 0.21 the DBD::ODBC module connection code (dbdimp.c) started
calling SQLDriverConnect first with your DSN name and only if that
failed called SQLConnect with the same DSN name. The problem is that
SQLDriverConnect is supposed to take a list of attributes of the form:

attribute=name;

and a DSN should be specified as "DSN=name;". Perl DBD::ODBC does not
appear to append the "DSN=" to the DSN before calling SQLDriverConnect
and so the OOB follows ODBC and assumes a DSN=DEFAULT. If the DEFAULT
DSN is not found (likely), DBD::ODBC tries calling SQLConnect with the
same DSN name but SQLConnect only takes a DSN name and does not
require the "DSN=" so this tends to work.

If the time taken to go through this process bothers you change the
name on your calls to DBI->connect to "DBI:ODBC:DSN=dsnname;". However,
one warning here; the db username and db password (second and third
arguments to DBI->connect) are ignored when using SQLDriverConnect so
you need to put UID=dbuser;PWD=dbpass into the connection string if
your database engine requires authentication.

4.1.9 Why do I get undefined symbols when running the Perl DBD::ODBC test?
--------------------------------------------------------------------------

An example might look like this:

Can't load 'blib/arch/auto/DBD/ODBC/ODBC.so' for module DBD::ODBC: 
blib/arch/auto/DBD/ODBC/ODBC.so: undefined symbol: SQLDataSources
 at /usr/lib/perl5/5.00502/i686-linux/DynaLoader.pm line 168.

The problem depends on what symbol is undefined. If the symbol is
SQLDataSources or SQLDrivers then the likelihood is that you are
attempting to build a version of OOB prior to 0.4.0.0 with DBD::ODBC
0.21. Versions of the OOB prior to 0.4.0.0 are not compatible with
linking directly to DBD::ODBC 0.21. To use these older versions of OOB
with Perl DBD::ODBC 0.21 you must either:

[1] install a driver manager under Perl DBD::ODBC and then tell the
driver manager about OOB.

[2] download a newer version of OOB (0.4.0.0 or newer).

4.1.10 Why does test 13 of the simple test in Perl DBD::ODBC fail?
------------------------------------------------------------------

Test 13 in the simple test is testing SQLDataSources. If you have
built Perl DBD::ODBC directly with OOB (without a driver manager) then
SQLDataSources in OOB only lists data sources in the odbc.ini file in
the current working directory. If the odbc.ini file in the current
working directory does not contain any data sources then
SQLDataSources returns SQL_NO_DATA and the DBD::ODBC test classes this
as a fail.  Either add a data source to the odbc.ini file in the
current working directory, build with an ODBC driver manager or ignore
this failure.

4.1.11 Why do I get compile errors building Perl DBD::ODBC on AIX?
------------------------------------------------------------------

The DBD::ODBC source code contains C++ comments which some AIX
compilers do not accept. You can either convert the c++ comments in
dbdimp.c to normal C comments (// text <end of line> becomes /* text
*/) or edit the generated makefile to add -qcpluscmt (add this to
CCFLAGS).

4.1.12 Why do I get "undefined symbol: SQLParamData" when testing DBD::ODBC?
----------------------------------------------------------------------------

When building DBD::ODBC with unixODBC and running the make test you
see something like this:

PERL_DL_NONLAZY=1 /usr/bin/perl -Iblib/arch -Iblib/lib 
-I/usr/lib/perl5/5.00503/i386-linux -I/usr/lib/perl5/5.00503 -e 'use 
Test::Harness qw(&runtests $verbose); $verbose=0; runtests @ARGV;' t/*.t
t/01base............install_driver(ODBC) failed: Can't load 
'blib/arch/auto/DBD/ODBC/ODBC.so' for module DBD::ODBC: 
blib/arch/auto/DBD/ODBC/ODBC.so: undefined symbol: SQLParamData at 
/usr/lib/perl5/5.00503/i386-linux/DynaLoader.pm line 169.

The undefined symbol SQLParamData is reported by the dynamic linker as
the first symbol it looked for but could not find.

This happens when building DBD::ODBC with unixODBC because the
Makefile.PL is now incompatible with newer unixODBC releases. The
Makefile.PL searches ODBCHOME/lib for *odbc*.* and finds libodbc.so
AND libodbcinst.so. It then goes on to choose libodbcinst.so which is
the incorrect shared object.  You can check this by running ldd on
blib/arch/auto/DBD/ODBC/ODBC.so where you will probably see something
like:

libodbcinst.so1 (libc6) => /usr/local/easysoft/unixODBC/lib/libodbcinst.so1

To fix this edit the Makefile.PL and delete the second '*' in the line:

    elsif ($myodbc eq 'unixodbc') {
        my @ilibs = <$odbchome/lib/*odbc*.*>;

so it becomes:

    elsif ($myodbc eq 'unixodbc') {
        my @ilibs = <$odbchome/lib/*odbc.*>;

Now rerun perl Makefile.PL and it should pick up the correct libodbc
shared object.

Note that this problem in DBD::ODBC's makefile is now fixed.

4.1.13 Why does make test for Perl DBD::ODBC fail with "invalid object name"
----------------------------------------------------------------------------
       errors?
       -------

The make test for Perl DBD::ODBC attempts to create tables in the
database, populate them and read the data back. If you use a DSN which
points to a database which is read-only (or for which you do not have
permission to create tables) the tests will fail. This will happen if
you use the demo DSN which is supplied with OOB as it points to our
database which is read-only as far as external users are concerned. A
typical failure when going to our demo data source looks like:

t/02simple..........DBD::ODBC::db do failed: 
[unixODBC][Microsoft][ODBC SQL Server Driver][SQL Server]
CREATE TABLE permission denied, database 'pubs', owner 'dbo'. 
(SQL-37000)(DBD: st_execute/SQLExecute err=-1) at t/ODBCTEST.pm line 80.
DBD::ODBC::db prepare failed: 
[unixODBC][Microsoft][ODBC SQL Server Driver][SQL Server]
Invalid object name 'PERL_DBD_TEST'. (SQL-S0002)

4.1.14 Why does make test in DBD::ODBC return 09multi errors containing
-----------------------------------------------------------------------
       "Data mismatch, result set 1"?
       ------------------------------

This is bug ID 1338 - see the OOB Changes.txt file. You need to
install at least 1.0.0.38 of OOB on the client AND the server.

4.1.15 Why do I get "String data, right truncation" retrieving result-sets
--------------------------------------------------------------------------
       from MS SQL Server?
       -------------------

Please see the question "Why do I keep getting data truncation errors
in my Perl" first as that is more likely to be the answer you are
looking for.

Before going in to the specifics of an issue in the MS SQL Server ODBC
driver it should be noted that the most common reason for this error
is calling SQLGetData or binding a column and supplying too small a
buffer for the column data.

e.g.

SQLExecDirect(select var_char_column from table)
SQLDescribeCol(column=1)
  returns a column size of 100
  or SQLColAttributes(column=1, SQL_DESC_DISPLAY_SIZE)
     which also returns 100
SQLFetch
SQLGetData(column=1, type=SQL_C_CHAR, buffer, buffer_size = 10)

or 

SQLExecDirect(select var_char_column from table)
SQLDescribeCol(column=1)
  returns a column size of 100
  or SQLColAttributes(column=1, SQL_DESC_DISPLAY_SIZE)
     which also returns 100
SQLBindCol(column=1, type=SQL_C_CHAR, buffer, buffer_size = 10)
SQLFetch

In both cases the buffer supplied for the column data was too small
and you will get a SQL_SUCCESS_WITH_INFO return from
SQLGetData/SQLFetch and a state of 01004.

However, there is one specific issue with the MS SQL Server ODBC
driver which can seriously confuse ODBC applications that bind columns
as SQL_C_CHAR. When retrieving column data from a result-set as strings
the average ODBC application:

[1] issues the query
[2] calls SQLNumResultCols to find out how many columns in the result-set
[3] calls SQLDescribeCol for each column to find out the type of the
    column and sometimes SQLColAttribute to get the display size.
[4] for each column calls SQLGetData (or SQLBindCol) passing a buffer
    based on the reported display size.

Ordinarily this works fine with the MS SQL Server driver but when "Use
Regional Settings" is checked in the MS SQL Server ODBC driver DSN
setup dialog everything changes. Once "Use Regional Settings" is
checked the ODBC driver returns integer fields using the current
regional settings and this generally increases the size of the
returned data. For UK machines the simple integer 1234, is returned as
"1,234.00". The problem is that when "Use Regional Settings" is
checked SQLDescribeCol and SQLColAttribute return the same column-size
as they do when this setting is unchecked and so for larger numbers
the column-size of 10 will be insufficient to hold the number and you
will get "string data right truncated". A simple example illustrates
the problem:

SQLGetTypeInfo(SQL_LONGVARCHAR)
  this returns a result-set describing the SQL_LONGVARCHAR type of
  which one of the columns (column 3) is the maximum column size that
  the server supports for this data type. In MS SQL Server the maximum
  size of a SQL_LONGVARCHAR is 2147483647 bytes.

SQLDescribeCol(column=3)
  this returns
  Name : COLUMN_SIZE
  Type : 4
  Size : 10
  Decimal Digits : 0
  Nullable : 1

  Note the Size=10. Most applications will use this number to allocate
  a buffer to receive the column data if the column data is being
  retrieved as SQL_C_CHAR (they add 1 for the terminating NUL as
  well).

SQLColAttribute(column=3, SQL_DESC_DISPLAY_SIZE)
  returns 11

SQLGetData(column=3, buffer, buffer_size=100)
  returns "2,147,483,647.00" in the UK which is too big to fit in the
  previously returned size of 10 or 11.

We have found a number of applications that suffer from this problem
but perhaps the most common is Perl's DBD::ODBC which binds integer
columns as SQL_C_CHAR (quite naturally really given Perl's text
processing features). If "Use Regional Settings" is checked in your
MS SQL Server data source and you run make test for DBD::ODBC you are
likely to see something like:

# make test
PERL_DL_NONLAZY=1 /usr/local/bin/perl "-MExtUtils::Command::MM" "-e"
  "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/01base.........ok
t/02simple.......ok 2/17
DBD::ODBC::st fetchrow failed:
[unixODBC][][Microsoft][ODBC SQL Server Driver]
String data, right truncation (SQL-01004)
(DBD: st_fetch/SQLFetch (long truncated) err=-1) at t/ODBCTEST.pm line 56.
DBD::ODBC::st fetchrow failed:
[unixODBC][][Microsoft][ODBC SQL Server Driver]
String data, right truncation (SQL-01004)
(DBD: st_fetch/SQLFetch (long truncated) err=-1) at t/ODBCTEST.pm line 56.
Unable to find a suitable test type for field COL_C at t/ODBCTEST.pm line 63.
t/02simple.......dubious
        Test returned status 255 (wstat 65280, 0xff00)

There are two possible solutions to this problem:

[1] uncheck "Use Regional Settings" in the MS SQL Server data source.
    
[2] add Regional=No to your connection string passed to DBI->Connect.
    e.g. "dbi:ODBC:DSN=mydsn;UID=dbuser;PWD=dbpassword;Regional=No;"

The MS help for the "Use Regional Settings" specifically says "Select
this option for applications that only display data, not for
applications that process data".

For DBD::ODBC and perhaps for some other ODBC applications you will
find that disabling "Use Regional Settings" is the only way of making
them work.

4.1.16 Why does a query on columns containing colons in the name fails from
---------------------------------------------------------------------------
        DBD::ODBC?
        ----------

One of our customers was trying to issue a query like this:

select aa:bbbb from table where ccc like 'name%'

and received the following error:

DBD::ODBC::db prepare failed: [xxx][yyy] Column not found:
aa? (SQL-S0000)(DBD: st_prepare/SQLPrepare err=-1) at
file.cgi line nn.
Can't call method "execute" on an undefined value at
file.cgi line nn.

It appears that this problem is restricted to column names containing
colons and if there is a space between the colon and the next word it
works fine. Interestingly, Oracle uses the : syntax for parameters.
Investigation of the dbdimp.c showed code in dbd_preparse which
translates aa:bbbb to aa? and assumes bbbb is a bound parameter.

More recent versions of DBD::ODBC have the
odbc_ignore_named_placeholders private DBD::ODBC attribute which may
be used to turn this behavior off.

4.1.17 Why do my Perl scripts complete but end in a segmentation violation?
---------------------------------------------------------------------------

Did you build Perl DBD::ODBC with unixODBC?
If so, you should ensure unixODBC is built without threads (use the
configure option --enable-threads=no).

The unixODBC driver manager that comes pre-built with the standard OOB
is built without threads being enabled. OOB distributions containing
"mt" in the distribution name are thread-safe and currently will not
work with Perl.

4.1.18 Why do I get "SQLSetConnectOption err=-2" errors in my Perl scripts
--------------------------------------------------------------------------

When running a Perl script using DBD::ODBC linked with the unixODBC
driver manager you see something similar to this:

DBI->connect(test) failed:
(Unable to fetch information about the error)
(DBD: dbd_db_login/SQLSetConnectOption err=-2) at perl_e1.pl line 9

We believe this is caused by the combination of lazy linking and
RTLD_GROUP.

a) If you are using Perl directly from the shell:

  Did the make test work when building DBD::ODBC? The DBD::ODBC make
  test sets PERL_DL_NONLAZY to 1 so if LAZY linking is the problem you
  don't see it in the DBD::ODBC test but can see it later when running
  your own scripts.

  Try running your perl script again with the environment variable
  PERL_DL_NONLAZY set to 1.

  If this cures the problem then you probably have a unixODBC which
  sets the RTLD_GROUP flag to dlopen.

  If you are using the unixODBC driver manager distributed with OOB
  please let us know the name of your OOB distribution file and we
  will correct. If you are using unixODBC newer than 2.2.6 then you
  can rebuild unixODBC with the configure option
  --enable-rtldgroup=no.

  If you are using unixODBC 2.2.5 or earlier then you need to stop
  unixODBC using the RTLD_GROUP flag in libltdl/ltdl.c.

  Edit libltdl/ltdl.c in the unixODBC source tree, look for a dlopen
  call using RTLD_GLOBAL which is ORed with LT_LAZY_OR_NOW and delete
  the "LT_GLOBAL |"

  e.g.
    lt_module   module   = dlopen (filename, LT_GLOBAL | LT_LAZY_OR_NOW);

  becomes

    lt_module   module   = dlopen (filename, LT_LAZY_OR_NOW);

b) If you are using Perl as CGI under Apache without mod_perl

   Try adding

   SetEnv PERL_DL_NONLAZY  1

   to the httpd.conf and restart Apache. Then follow instructions
   under a).

c) If you are using mod_perl under Apache then set the environment
   variable PERL_DL_NONLAZY to 1, export it and then stop/start
   Apache.

   If this cures the problem then you need to add PERL_DL_NONLAZY=1
   and export PERL_DL_NONLAZY to your apachectl startup program.

   If it does not cure the problem and you are using a unixODBC newer
   than 2.2.6, you need to rebuild unixODBC with the configure option
   --enable-rtldgroup=no.

Easysoft build unixODBC with the following configure options:

./configure --prefix=/usr/local/easysoft/unixODBC
            --sysconfdir=/etc
            --enable-threads=no (or yes when building a thread-safe version)
            --enable-iconv=no
            --enable-drivers=no
            --enable-gui=yes (or no if you don't have X and QT)
            --enable-stats=no

--enable-rtldgroup=yes needs to be added to unixODBC 2.2.6, 2.2.7,
2.2.8 when unixODBC is dlopened by an application.

We also use --enable-readline=no on some platforms because our base
build boxes are older and many newer machines don't have the older
libreadline.

4.1.19 Why cannot I insert timestamps with DBD::ODBC 0.32 - it worked with
--------------------------------------------------------------------------
       previous versions of DBD::ODBC?
       -------------------------------

DBD::ODBC 0.32 had the quoted identifier character changed from ' (a
single quote) to " (a double quote). This means if you attempt to
insert a timestamp of the form {ts '2001-02-15 01:02:03'} it will be
preparsed by DBD::ODBC and changed to {ts '2002-02-15 12??.00'}
because it now looks like a placeholder.

You will need to upgrade to a more recent version of DBD::ODBC to fix
this problem or go back to an older version.

4.1.20 Why do tests 1, 2 and 6 of 20Sqlserver test in DBD::ODBC fail to
-----------------------------------------------------------------------
       MS SQL Server?
       --------------

Symptom.

You are doing a make test in DBD::ODBC and tests 1, 2 and 6 of the
20Sqlserver test fail like this:

t/20SqlServer....NOK 1Please upgrade your ODBC drivers to the latest SQL Server drivers available.
t/20SqlServer....FAILED tests 1-2, 6
        Failed 3/25 tests, 88.00% okay

If you run the test again with TEST_VERBOSE=1 the relevant failures are:

t/20SqlServer....1..25
Inserting:  0,  string length 13
Inserting:  1, 2001-01-01 01:01:01.110 string length 12
Inserting:  2, 2002-02-02 02:02:02.123 string length 114
Inserting:  3, 2003-03-03 03:03:03.333 string length 251
Inserting:  4, 2004-04-04 04:04:04.443 string length 282
Inserting:  5, 2005-05-05 05:05:05.557 string length 131
Retrieving: 0,  string length 13
Retrieving: 1, 2001-01-01 01:01:00.000 string length 12 !time
Retrieving: 2, 2002-02-02 02:02:02.123 string length 114
Retrieving: 3, 2003-03-03 03:03:03.333 string length 251
Retrieving: 4, 2004-04-04 04:04:04.443 string length 282
Retrieving: 5, 2005-05-05 05:05:05.557 string length 131
not ok 1
f ne foo
Please upgrade your ODBC drivers to the latest SQL Server drivers available.
not ok 2
1
2
3
ok 3
CREATE PROCEDURE PERL_DBD_PROC1 (@i int, @result int OUTPUT) AS BEGIN     SET @result = @i+1;END 
ok 4
ok 5
2002-07-12 05:09:00.000
not ok 6

Here you will note that test 1 and 6 fails because the datetime
inserted is not retrieved correctly (the seconds and milliseconds are
zeroed) and test 2 fails because the string "foo" that was inserted is
retrieved as "f". We have identified this problem as a bug in the MS
SQL Server driver. If you go to the ODBC Administrator on your server
machine and click on drivers the version of your SQL Server driver is
likely to be 2000.80.194.00 (if it is not please let us know).

The solution is to upgrade your SQL Server ODBC driver. The version in
MDAC 2.7 appears to work OK. Version 2000.81.9030.04 of the SQL Server
ODBC driver is also OK.

4.1.21 Why do I get "Makefile:311: *** missing separator.  Stop." when
----------------------------------------------------------------------
       building DBD::ODBC 1.06?
       ------------------------

There is a mistake in the Makefile.PL. Edit the Makefile.PL and search
for "NOOP" to find the line:

    @$(NOOP)

Replace the spaces in front of "@$(NOOP)" with a <tab> character.
Now rerun perl Makefile.PL.

Also, if you are using RedHat 9 you may want to see

https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=87682 and
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=84268

which suggest that when LANG is set to include UTF8 (default), perl
generated make files and even perl -V output are incorrect. This is
apparently corrected by setting LANG to something other than UTF8
e.g. LANG=en_US, LANG=C.

4.1.22 Why do I get "Can't change param 1 maxlen (51->50) after first bind"
---------------------------------------------------------------------------
       error when running make test in DBD::ODBC?
       ------------------------------------------

This applies to DBD::ODBC 1.13 (and earlier versions) and Perl 5.8.8
and later versions. DBD::ODBC 1.14 contains the fix for this issue.

Perl's internal SvGROW function changed in Perl 5.8.8 so that it grows
a scalar up to the next longword boundary instead of up to the size
specified in the SvGROW call (although they can obviously be the
same).

This affects DBD::ODBC which uses SvGROW to grow a scalar because
it tests the length the scalar is grown to against the length it asked
for and produces the error:

Can't change param 1 maxlen (51->50) after first bind
at t/20sqlserver.t line 180

if the scalar is not equal to what was requested.

The solution is a simple change to the dbdimp.c module. Look for the
line:

   else if (maxlen && maxlen != phs->maxlen) {

at around line 2931 and change it to:

   else if (maxlen && maxlen > phs->maxlen) {

4.1.23 Why does make test in DBD::ODBC to SQL Server 2005 and SQL Server
------------------------------------------------------------------------
       Express fail?
       -------------

This applies to DBD::ODBC 1.13 (and earlier versions). DBD::ODBC 1.14
contains the fix for this issue.

SQL Server 2005 and SQL Server Express have changed the way:

  dbcc TRACESTATUS(-1)

works. This affects tests 28, 31, 32 and 33 in the 20SqlServer module.

The errors look like:

t/20SqlServer....ok 4/37
#   Failed test 'dbcc messages being returned'
t/20SqlServer....NOK 28#   in t/20SqlServer.t at line 443.
#     '0'
#         >
#     '0'
t/20SqlServer....ok 29/37Describe failed during DBI::st=HASH(0x9d65010)->FETCH(o
dbc_more_results,0) at t/20SqlServer.t line 453.

#   Failed test 'ensure 2 error messages from two print statements'
#   in t/20SqlServer.t at line 459.
#          got: '3'
#     expected: '2'
t/20SqlServer....NOK 31
#   Failed test 'validate error messages being retrieved'
#   in t/20SqlServer.t at line 460.
#          got: 'Connection is busy with results for another hstmt'
#     expected: 'END'
t/20SqlServer....NOK 32
#   Failed test 'Multiple concurrent statements should fail'
#   in t/20SqlServer.t at line 471.
DBI::db=HASH(0x9d1f1cc)->disconnect invalidates 1 active statement handle (eithe
r destroy statement handles or call finish on them before disconnecting) at t/20
SqlServer.t line 473.
t/20SqlServer....ok 36/37# Looks like you planned 37 tests but only ran 36.
# Looks like you failed 4 tests of 36 run.
t/20SqlServer....dubious
        Test returned status 4 (wstat 1024, 0x400)
DIED. FAILED tests 28, 31-33, 37
        Failed 5/37 tests, 86.49% okay

You can ignore these failures as they are an error in the test rather
than a bug in DBD::ODBC itself. Alternatively you can follow the
instructions below to correct the problem.

Edit the file t/20SqlServer, search for:

   $sth = $dbh->prepare("dbcc TRACESTATUS(-1)");

and change it to:

   $sth = $dbh->prepare("dbcc TRACESTATUS(0)");

4.2 PHP/Apache Related
----------------------

4.2.1 How do I use Apache/PHP with OOB?
---------------------------------------

You need to obtain the source distributions of Apache and PHP from
http://www.apache.org and http://www.php.net. Instructions for
building Apache and PHP with OOB can be found in the Apache_PHP file
contained in the docs directory of the OOB distribution.

Please make sure you carefully read the INSTALL files that come with
Apache and PHP as they contain valuable information that can save you
a lot of headaches.

4.2.2 What versions of PHP (and Apache) can I use with OOB?
-----------------------------------------------------------

OOB has been tested with Apache 1.3.n.

OOB has been tested with PHP 3.0.0 to 3.0.16, the first three betas
of PHP4 and should work with any version after 4.0.

4.2.3 Why do I get parse errors when compiling PHP with OOB?
------------------------------------------------------------

There are a number of reasons why you may get parse errors whilst
building PHP and OOB many of which are nothing to do with OOB. However
some that we have seen are:

In file included from /usr/local/easysoft/oob/client/include/odbc.h:2,
                 from functions/php3_unified_odbc.h:199,
                 from internal_functions.c:90:
/usr/local/easysoft/oob/client/include/sqlext.h:1652: parse error before `0'
/usr/local/easysoft/oob/client/include/sqlext.h:1756: parse error before `0'

In this case a beta tester was building PHP with informix
(--with-informix) and custom ODBC support. The problem with doing this
is that the both drivers define many of the same symbols. In this case
SQLCHAR was defined as '0' by Informix. If you want multiple ODBC
drivers available from PHP, Easysoft recommend that you install a
driver manager (e.g.  unixODBC http://www.unixodbc.org) and then tell
the driver manager about your multiple drivers.

4.2.4 Why do I get undefined reference to xyz when making Apache/PHP
--------------------------------------------------------------------

e.g.

modules/php3/libphp3.a(unified_odbc.o): In function `_free_result':
/work/builds/php-3.0.11/functions/unified_odbc.c:192: undefined reference to `SQLFreeStmt'
modules/php3/libphp3.a(unified_odbc.o): In function `_results_cleanup':
/work/builds/php-3.0.11/functions/unified_odbc.c:208: undefined reference to `SQLFreeStmt'

Look at the linker line before the undefined reference messages start
and check that there is a -lesoobclient. If this is missing you have
probably misconfigured PHP as described below. You can usually check
this is what has happened by doing a grep for esoobclient in the top
level Makefile:

e.g.
/work/php-3.0.12-> grep esoobclient Makefile

which should show something like:

LIBS = -lgd pcrelib/libpcre.a regex/libregex.a -lgdbm
 -L/usr/local/easysoft/oob/client/lib -lesoobclient
 -lgd -lm -ldl -lcrypt -lnsl  -lresolv

The actual output will depend on the platform but should contain
"-lesoobclient".

The CUSTOM_ODBC_LIBS defines the name of the shared object which
provides the ODBC driver which in this case is the ODBC-ODBC Bridge
client shared object (libesoobclient.so, the .so depends on the
platform and may be .a or .sl). If the CUSTOM_ODBC_LIBS variable was
not set BEFORE making PHP Apache will not include a reference to the
shared object containing the SQL functions and hence the undefined
references.  See the Apache_PHP text file in the docs directory of the
distribution.

If you are not using a shell that allows variables to be assigned at
the same time as running a command then set CUSTOM_ODBC_LIBS to
"-lesoobclient" and then export the CUSTOM_ODBC_LIBS:

e.g.
> CUSTOM_ODBC_LIBS="-lesoobclient"
> export CUSTOM_ODBC_LIBS

4.2.5 Why does a build of PHP4 RC1 and OOB fail?
------------------------------------------------

If you are attempting to build PHP4 RC1 with OOB you will probably get
compilation errors such as:

php_odbc.c: In function `php_if_odbc_execute':
php_odbc.c:849: parse error before `FAR'
php_odbc.c:852: parse error before `FAR'

This problem is due to someone adding code to PHP4 which expects FAR
to be defined (FAR was an old Win16 macro). OOB header files do not
define FAR as OOB only runs on UNIX, VMS and WIN32. PHP4 has now be
changed to remove the use of FAR and this change is available in the
latest CVS tree. Until the next RC is released, if you do not have
access to the CVS tree the quickest solution is to define CFLAGS as
-DFAR="" before running configure.

e.g.
CFLAGS=-DFAR=""
export CFLAGS
./configure --enable-track-vars ... etc etc

4.2.6 Why do I get compile warnings in php_odbc.c with OOB 1.0.0.15?
--------------------------------------------------------------------

When compiling PHP 4.0.n with OOB 1.0.0.15 you may see compilation
warnings about implicit conversion of integer to pointer. There are
updated versions of the sqlext.h and sqltypes.h header files included
with OOB posted to the OOB news group. Alternatively, upgrade the OOB
client to 1.0.0.16 or above.

4.2.7 I don't want to rebuild Apache for PHP/ODBC support, what can I do?
-------------------------------------------------------------------------

If you already have Apache installed on your machine but it does not
have PHP support you may not want to rebuild Apache to include PHP.
If your Apache was built with DSO support then you can add PHP (or any
other module) to Apache afterwards without rebuilding Apache.  In
order to determine if your Apache has DSO support you need to run
Apache's -l option to list the included modules:

./httpd -l

You need to look for mod_so.c.

e.g. in a standard Linux/RedHat 6.1 distribution Apache is installed
in /usr/sbin:

> cd /usr/sbin/
> ./httpd -l
Compiled-in modules:
  http_core.c
  mod_so.c

Here Apache was built with DSO support so you can build PHP with ODBC
support separately and tell Apache to load it separately.

When building PHP with ODBC support for Apache with DSO support read
the php-x.y.z/INSTALL file in the PHP distribution and follow the
instructions under "INSTALL (DSO - Dynamic Shared Object)". Basically
you need to configure PHP with the --with-apxs and --with-esoob (or
--with-unixODBC) options.

Once PHP is built and installed you will need to add a LoadModule
command to your httpd.conf file to enable PHP in Apache (see the
Apache and PHP INSTALL files for details).

4.2.8 How do I tell Apache to pass PHP scripts to the PHP interpreter?
----------------------------------------------------------------------

You should read the INSTALL file that comes with PHP very carefully
before using Apache and PHP. It has instructions which tell you how to
make Apache pass PHP scripts to the PHP interpreter. Briefly you must
add lines like:

For PHP3:

AddType application/x-httpd-php3 .php3

or

AddType application/x-httpd-php3 .phtml

or for PHP4 just:

AddType application/x-httpd-php .php

to your Apache srm.conf file. Note that this changed for PHP4 betas
where the type became application/x-httpd-php4. The best place to find
out is in the INSTALL file that comes with PHP.

4.2.9 Apache/PHP can't seem to find my odbc.ini file or
-------------------------------------------------------
      Datasource not found and no default driver error.
      -------------------------------------------------

When you start Apache with PHP built with ODBC support, PHP
immediately allocates an ODBC environment handle. Unfortunately, the
OOB searches for the odbc.ini file when an environment handle is
created and so your odbc.ini file needs to found at server
startup. This can be a nuisance since most people start Apache at
machine boot time from an rc script but locate their odbc.ini files in
the same directory as their PHP scripts. The best way around this is
to put all your DSN definitions in the /etc/odbc.ini (or
SYS$ROOT:odbc.ini for VMS) file.

4.2.10 Why don't my PHP scripts appear to run on the web server?
----------------------------------------------------------------

Your first port of call should probably be the various PHP or Apache
(or whatever web server you are using) news groups, mailing lists and
FAQs. However, here are a few pointers specific to Apache/PHP.

[a] Did you build Apache with PHP?

[b] Make sure Apache knows what to do with a PHP script. You need to
    tell Apache in the httpd.conf (or one of the other config files)
    that files with the extension php3 or phtml should be passed to
    PHP. You do this with lines like this:

    AddType application/x-httpd-php3 .php3
    AddType application/x-httpd-php3 .phtml

    These tell Apache to pass files ending in .php3 and .phtml to PHP
    for processing.

[c] Check you can run a simple PHP script. Create a file called test.php3
    in the htdocs directory of your web server containing:

    <html>
    <head>
    <title>Test</title>
    </head>
    <body>
    <p>
    You should see PHP info below:
    <?
    	phpinfo();
    ?>
    </body>
    </html>

    Then use the URL http://my_web_server/test.php3 (replace
    my_webserver with the appropriate machine name and domain) from
    your browser to see if you get a page of PHP information back.  If
    you don't something far more serious is wrong with your Apache/PHP
    configuration than not being able to make ODBC connections from
    PHP through the OOB.

If all the above OK you might try:

[a] Examine your Apache error log. This file is named in your Apache
    configuration file(s) (e.g. httpd.conf) with the "ErrorLog"
    setting.

[b] Make sure you followed the PHP INSTALL file and copied the sample
    php ini file (php3.ini-dist) to the correct place. Some options in
    this file can prove useful for debugging:

    [1] "track_errors = On" stores the last error in the php_errormsg
        variable.
    [2] "error_reporting = 7" outputs Normal errors, Normal warnings,
        Parser errors.
    [3] "error_log = filename" defines the file errors/warnings will be
        sent to.

If PHP appears to be working but you do not get data back through OOB
then see the questions on turning logging on in the OOB.

4.2.11 How can I find out why my PHP script is not working?
-----------------------------------------------------------

There are general guidelines to help you in the PHP documentation and
via a number of PHP mailing lists, you should read those first. A
quick method is to turn on tracing in PHP. You can do this by editing
your /usr/local/lib/php3.ini file (if you don't have one then see the
INSTALL file that comes with PHP which documents a template ini file).

Ensure error_reporting is set to 7, log_errors is set to On and set
error_log to the name of a file (e.g. /tmp/php_errors). Once you have
made these changes restart Apache and all the normal errors and
warnings and parser errors will be logged to the file.

You can also set track_errors to On which makes the last error
available in the $php_errormsg variable.

4.2.12 Can I use PHP with OOB and driver X?
-------------------------------------------

You cannot build PHP with multiple ODBC drivers or driver managers
e.g. you cannot use any two of the configure options from the list
below (current of PHP4b3):

--with-custom-odbc
--with-iodbc
--with-esoob
--with-unixODBC
--with-openlink

If you want to access multiple ODBC drivers from PHP the best method
is to install the unixODBC driver manager and then tell the unixODBC
driver manager about your ODBC drivers.

You can build PHP with an ODBC driver and other database drivers such
as Oracle or MySQL as these drivers do not provide the same ODBC API.

4.2.13 In PHP, why can I only use/get column names up to 30 characters when
---------------------------------------------------------------------------
       my database supports much longer column names?
       ----------------------------------------------

PHP, up to version 4.0 (final release) restricts column names to 30
characters. The OOB places no restrictions on column name lengths.

4.2.14 Why is my column data truncated at 4096 bytes from PHP?
--------------------------------------------------------------

If you built PHP yourself make sure you copied the php.ini-dist file
from the PHP source tree to /usr/local/lib as documented in the PHP
INSTALL file. The php.ini file contains the default setting for
uodbc.defaultlrl (or odbc.defaultlrl) of 4096 which limits the amount
of data retrieved from a single column to 4096 bytes. You can increase
defaultlrl to get more data without changing your PHP or you can use
the PHP function called odbc_longreadlen.

4.2.15 Why does phpinfo() display "Active Persistent Links" of 0/1 when I
-------------------------------------------------------------------------
       know there are more open connections to my database?
       ----------------------------------------------------

Please read http://www.php.net/manual/features.persistent-connections.php.

Currently in UNIX, Apache and PHP is a single-threaded process where
the main web server creates children to deal with HTTP requests. When
you set allow_persistent to On in your php.ini file and use
odbc_pconnect a persistent connection will be created in one of the
HTTP child processes.  However, it is up to the main HTTP which child
will handle the request and the persistent connection only exists in
that httpd child.  Similarly when you browse a PHP page which calls
phpinfo(). You cannot control which HTTP child process will answer the
request so it may be one which has never connected to the database
(Active Persistent Links = 0) or one which has connected to the
database (Active Persistent Links = 1).  This is easy to confirm for
yourself:

[1] Stop http server and configure it so only you can connect (or
    arrange that no-one else connects to it whilst you are testing).
    Make sure allow_persistent = On in your php.ini file.
[2] Start http server.
[3] Browse a php page which calls phpinfo() - it will display 
    Active persistent Links = 0. No matter how many times you refresh
    this page it will show 0.
[4] Browse a php page which connects to your database with odbc_pconnect().
[5] Browse the page in [3] again and hit refresh a number of times.
    You will see "Active persistent Links" change between 0 and 1 even
    though there is no activity on your web server other than
    yourself. This is the main HTTP server farming out your HTTP
    request to different children, one of which made the connection in [4]
    and all the others which have never made a database connection.

The only way to get Active Persistent Links greater than 1 is to open
more than one persistent connection in a single PHP script.

4.2.16 Why don't my changes to PHP odbc settings in php.ini file get picked up?
-------------------------------------------------------------------------------

On some versions of php the distributed example php.ini-dest file
contains a section containing ODBC settings where the names are
uodbc.xyz but PHP looks for odbc.xyz. You need to edit the php.ini
file and change the uodbc to odbc for the settings you have changed
from the defaults.

4.2.17 Why doesn't PHP's max_persistent setting limit the total number of
-------------------------------------------------------------------------
       ODBC connections to my database?
       --------------------------------

Please see the question "Why does phpinfo() display Active Persistent
Links of 0/1 when I know there are more open connections to my
database".

The max_persistent limit is per HTTP server process. Setting
max_persisent to 1 does not limit the total number of ODBC connections
to 1. Eventually, all the HTTP server children will probably have 1
connection to the database.

4.2.18 What is this problem I'm seeing when using PHP persistent connections?
-----------------------------------------------------------------------------

Please see the other questions about PHP in this section. What follows
is a general list of additional issues we have found with persistent
connections in PHP.

[1] Some versions of PHP (specifically 4.2.0 but we did not test them
    all) appear to close connections automatically when a PHP script
    completes even if odbc_close() is not called. However, this only
    happens if odbc_connect() is used to open the connection and not
    when odbc_pconnect is used. You should appreciate this fact
    especially when considering the next point.

[2] PHP can allow open transactions to exist over persistent
    connections i.e. if you turn off autocommit with
    odbc_autocommit(connection, FALSE), then do some inserts/updates
    and forget to commit or rollback the transaction it remains in the
    uncommitted state in that connection.  The implications of this
    can be most serious and at worst may result in blocking due to
    database locks in your scripts. As an example here is some code
    which works the first time PHP is run and blocks the second time
    (run to MS SQL Server although it could happen with other
    databases depending on their locking strategy):

$dbc = odbc_pconnect("db", "user", "password");
odbc_autocommit($dbc, FALSE);
$stmt = odbc_exec($dbc, "update table set col2 = 'update' where col1=1");

    Note that there is no odbc_close() and odbc_pconnect() is used so
    because of [1] above, the connection is not closed when the script
    completes. When the URL causing this PHP is browsed again, the
    chances are the web server will hand the request off to a
    different web server process which executes the same PHP but
    blocks on the odbc_exec() call because of the outstanding update
    issued by the script the first time it was run. With MS SQL Server
    you can verify that it is a lock by simply changing the odbc_exec
    call to:

$stmt = odbc_exec($dbc,
  "set lock_timeout 5 update table set col2 = 'update' where col1=1");

   which returns:

Warning: SQL error:
  [unixODBC][Microsoft][ODBC SQL Server Driver][SQL Server]
  Lock request time out period exceeded.,
  SQL state 37000 in SQLExecDirect in script.phtml on line nn

[3] Not strictly to do with persistent connections but related to [2]
    above.  If you repeated [2] but with an odbc_connect() then when
    the db connection is automatically closed by PHP, the call to
    SQLDisconnect will fail with an "outstanding transaction". What
    PHP does here is roll back the transaction and then call
    SQLDisconnect again. In fairness this is probably the only thing
    it can do but:

    [a] you should realise your transaction is being rolled back in
        these circumstances.

    [b] even if you call odbc_close(), as it does not not return a
        value, you will not be aware your transaction was rolled back.

    [c] this behavior is contrary to the documentation which says

    "odbc_close will fail if there are open transactions on this
    connection. The connection will remain open in this case."

4.3 Microsoft SQL Server / Access
---------------------------------

4.3.1 Why can't I use bound parameters with MS Access
-----------------------------------------------------

The MS Access ODBC Driver currently does not support SQLDescribeParam
which is often used by ODBC interfaces which use bound parameters (e.g
Perl DBD:ODBC). If the ODBC interface you are using requires
SQLDescribeParam to support bound parameters you must avoid binding
parameters when going to MS Access.

4.3.2 Why does my second connection to MS Access hang?
------------------------------------------------------

You may notice if you try attaching a MS Access ODBC driver data source
to the MS Access application in windows that it does not let you do
this.  Easysoft have seen problems making more than one simultaneous
connection from UNIX through the OOB to the MS Access ODBC driver (
specifically hanging). We think that the MS Access ODBC driver dll may
contain some shared data that is incompatible with our default
configuration of a multi-threaded OOB server. You can work around this
problem by changing the OOB Server to run multi-process instead of
multi-threaded.

According to Microsoft's web site 
(http://www.microsoft.com/data/mdac21info/MDAC21sp2manifest.htm)

==========
Known Issue: ODBC Jet driver in multithreaded environments 
Component: ODBC Jet driver 

When running in a multithreaded or stress environment such as IIS, it
is recommended not to use ODBC because of issues with threading in the
driver as well as the Jet engine. The recommendation for this
situation is to work with the OLE DB provider for Jet.
==========

To make the OOB Server run multi-process instead of multi-threaded use
the OOB Server administration interface by browsing
http://mywindowsmachine:8890. Select Configuration, Change
Configuration and then check the MultiProcess checkbox. Click on
submit. If the OOB Server configuration page had an
"AutoUpdateConfiguration" checkbox and it was not checked you will
need to restart the OOB Server Service. Versions of the OOB Server
administration interface without the "AutoUpdateConfiguration"
checkbox do not need the service restarting.

Update to this. According to Microsoft's web site JET 4 is now thread-safe:

http://support.microsoft.com/support/kb/articles/Q169/4/70.asp

You can ascertain if you have JET 4 by clicking on the drivers tab in
Control Panel -> DataSources and examining "Microsoft Access Driver".
If it says 4.xxxx then you should not need to switch the OOB Server in
to MultiProcess mode (as detailed above).

4.3.3 Why do I get corrupted text columns back from MS SQL Server
-----------------------------------------------------------------

We have had reported to us a problem accessing text fields in MS
SQL Server.  The reporter was attempting to retrieve multiple columns
defined as SQL Server "text" in PHP and always retrieved garbage in the
second text column. This problem only appears to happen when
retrieving multiple text fields from a table with SQLGetData and
occurs for the second text column retrieved. PHP sees that text fields
in SQL Server can be very long so instead of binding the column (as
usual) it uses SQLGetData. This problem could occur in any other ODBC
interface if SQLGetData is used for multiple text fields.

The specific report involved a table created as follows:

create table BENCH_TEXT (f1 integer, f2 text, f3 text)
insert into BENCH_TEXT values(1, 'some text', 'some text')
select f1, f2, f3 from BENCH_TEXT

The f1 and f2 columns are retrieved OK with SQLGetData but when the f2
column is requested with SQLGetData the returned StrLen_or_IndPtr
value is usually too short and the data is garbage.

After a search of the net we discovered a similar report by Chad
Slater-Scott which read:

Subject: BUG: Service Pack 1 on SQL7.0 (SQLExtendedFetch Returns
         metadata on SQLGetData)
Date: 09/27/1999
Author: Chad Slater-Scott <avacado@usa.net>

Just wanted to let you all know that SP1 For SQL Server has a new
bug. After using SQLExtendedFetch or SQLFetchScroll to retrieve
records using SQL_ABSOLUTE or SQL_RELATIVE positioning, a SQLGetData
call to a text field will return garbage.  This is not reproducible if
the text field is the only field selected or if you the text field is
the first field called.  In order to reproduce it, another field value
must be retrieved using SQLGetData.  I reported this to Microsoft and
a Bug has been filed.  If any of you are using this sequence of calls
and have installed SP1, check your stuff for garbage on the text
fields.  The Bug ID is 56509 is want to track its status.

We have been told that the problem is in the SQL Server driver included
in SP1 for SQL Server and SP6 for NT. The version with the problem
appears to be C:\winnt\system32\sqlsvr32.dll (3.70.06.90) and the
working version is 3.70.0623.

Our machines running SQL Server 7 and NT 4 sp4 appear OK.

4.3.4 Why are my connections to MS SQL Server so slow?
-----------------------------------------------------

Microsoft introduced changes to MS SQL Server 7.0 which can cause
connections to an OOB Server and MS SQL Server and subsequent
operations to be very slow. These settings elevate the priority of
SQL Server to such an extent that other processes on the machine do not
get a look in. (e.g.  when someone is issuing a query, TaskManager
even stops displaying). If you are running MS SQL Server 7 and the OOB
Server is running on the same machine as SQL Server you should try the
following:

[1] The settings are available from the properties menu of the
    Enterprise Manager.  The settings are "Boost SQL Server Priority
    on Windows NT" and "Use NT fibres".  When these are set NT is so
    busy servicing SQL Server, the accept() in the OOB Server can take
    some time due to NT not scheduling any other process.

[2] Move your OOB Server to another machine where MS SQL Server is not
    running.

4.3.5 Why is my NT OOB Server using a lot of CPU, my ODBC connections go to
---------------------------------------------------------------------------
      MS SQL Server?
      --------------

Obviously, there could be many reasons for this. It should be
remembered that all the CPU used and showing in Task Manager for
esoobserver includes the CPU used by the driver manager and any ODBC
drivers you are using.  If the OOB Server is running threaded (the
default) then CPU usage SEEN in Task Manager will be greater than if
the OOB Server is running MultiProcess.  This is simply due to the
fact that when in MultiProcess mode a new process is created to handle
each incoming connection, when that connection is closed the OOB
Server process handling it will die and you cannot see the CPU usage
for a dead process.

The most common scenario where the OOB Server appears to be using a lot
of CPU is when it is handling a connection MS SQL Server, a result-set
has been generated but not consumed/closed and an attempt to create a
new result-set is made. In this case, the MS SQL Server ODBC driver
appears to spin-wait, consuming a lot of CPU. We have seen this
ourselves on our web site and a few customers have hit the same
problem - it is always down to not closing the result-set. The example
below is a real example which occurred in a PHP script, it is provided
in the hope it will help others avoid this problem.

The table in the MS SQL Server database contained a column defined as
TEXT. One row in the table contained one of these text columns with
over 7K in it but PHP's odbc.defaultlrl (default long read length) was
set to the default of 4K. A query was issued which retrieved all of
the columns from this table. PHP bound columns for most of the columns
in the table but used SQLGetData to retrieve the TEXT column as it was
defined as SQL_LONGVARCHAR. The problem arises because when PHP's
odbc_result() was called to retrieve the result-set data, PHP passed a
4K buffer which was insufficient, MS SQL Server returned 4K and
SQL_SUCCESS_WITH_INFO and hence the result-set is not consumed (ODBC
says you can call SQLGetData multiple times on the same column to
retrieve the data in chunks).  The PHP script then goes on to issue
another query which hangs. At this stage the OOB Server on the NT
machine showed a lot of CPU usage which was tracked down to
spin-waiting in the ODBC driver. This problem can be avoided very
simply by closing any result-set you generate, in PHP that means
calling odbc_free_result(), in ODBC terms it is a call to
SQLFreeStmt(SQL_CLOSE).

In every case high CPU usage in the OOB Server has been reported to
us, the connection was always to MS SQL Server and always resulted
from the result-set not being closed.

4.3.6 Why cannot I insert timestamps with sub-millisecond fractions in to
-------------------------------------------------------------------------
      MS SQL Server datetime field?
      -----------------------------

Firstly, consult
http://support.microsoft.com/support/kb/articles/Q263/8/72.asp

MS SQL Server only does millisecond accuracy (precision of 3) on
datetime columns so anything sub-millisecond tends to generate an
error such as 22008 [Microsoft][ODBC SQL Server Driver]Datetime field
overflow. As the fraction part of a timestamp can range from 0 to
999,999,999 you need to specify the fraction in thousands of second.

If you are using column-wise bound parameters to insert a timestamp in
to a datetime field make sure the ColumnSize is set to 23.

4.3.7 Why have connection times to MS SQL Server slowed down since upgrading
----------------------------------------------------------------------------
      to Windows 2000 Server?
      -----------------------

We don't know but if you install Windows 2000 Service Pack 1
they come down again. We did notice this service pack appears to
include a WinSock update.

4.3.8 Why are my output bound parameters from a MS SQL Server procedure
-----------------------------------------------------------------------
      not retrieved?
      --------------

Assuming your application was written correctly then the likelihood is
you are not calling SQLMoreResults() after each SQLExecute. A quote
from Microsoft's web site says:

"For SQL insert statements, ODBC 3.5 changed the behavior with respect
 to SQLMoreResults such that, output parameters aren't stored in the
 application's buffer until after the app calls SQLMoreResults and it
 returns SQL_NO_DATA_FOUND. The ODBC 2.65 driver would read-ahead and
 sometimes lump result sets together or skip over them. The ODBC 3.5
 driver was changed to provide result sets in a consistent fashion w/o
 the various problems that used to occur." 

So if you have procedures that return values and they contain insert
statements you must call SQLMoreResults() to fill your output bound
parameters.

You may also get a function sequence error if you attempt another
SQLExecute call before SQLMoreResults() has returned
SQL_NO_DATA_FOUND.

According to Microsoft, setting "SET NOCOUNT ON" in your SQL will also
work. However, if you do this you need to insert it into the first
line of your procedure (it is no good putting it in to the SQL that
calls your procedure in the SQLPrepare).

If you are using unixODBC there was a bug in an early 2.2.4 release
(dated around Jan 20 2003). If SQLMoreResults returned SQL_ERROR then
all further calls to SQLMoreResults were not passed through to the
driver and returned SQL_NO_DATA. This prevents the OOB client from
obtaining the procedure return output parameter.

4.3.9 Why do I get "Could not find file '(unknown)'" errors using MS Access
---------------------------------------------------------------------------
      ODBC driver?
      ------------

The error is also sometimes:

The Microsoft Jet database engine cannot open the file '(unknown)'.
It is already opened exclusively by another user, or you need
permission to view its data.

OR

Couldn't use '(unknown)'; file already in use

This problem usually occurs because the MS Access mdb file specified
in the ODBC data source cannot be found but it can also be due to
permissions.

Go in to control panel, select ODBC or Data Sources and locate the MS
Access SYSTEM DSN you are using with OOB. The name of the mdb file
should be shown (if you cannot read all of it click on select). Does
this file exist? Was it on a mapped drive that is no longer mapped?

If the file exists then you should check the following:

[1] The permissions on the file. The file needs to be
    readable/writable by the user your OOB client logs on with
    i.e. the value of the LogonUser attribute in your DSN.

[2] If the mdb file is on a mapped drive check the LogonUser is the
    same person who mapped the network drive. i.e. if user XXX is
    interactively logged in to the Windows server and mapped drive H
    from a network share any user other than XXX will not have access
    to the mapped drive.

[3] Is the mdb file linked to a table where the table linked to is in
    another mdb file on a network drive - if so, see [2].

[4] Make sure the system environment variable TEMP is assigned to
    an existing directory and one which the LogonUser has access to.

    To do this enter Control Panel and double click the System icon.
    When the System Properties pane has loaded up select the Advanced
    tab and click into Environment Variables. Select the Environment
    Variable Temp from the System Variables list. If it does not point
    to an existing directory change it. Once this has been edited
    click ok and this will save your new value.

[5] Make sure you have permission to create temporary files in the same
    directory as the mdb file.

[6] Another process or user has the Access database open.

You may also see error 80004005 in Active Server Pages and Microsoft Data
Access Components. Check all of the above plus:

[1] The account that MS Internet Information Server is using does not
    have the correct Windows NT permission for a file based database or
    for the folder that contains the file. IIS usually runs under the IUSR
    account.

[2] The file and the data source are marked as Exclusive.

[3] The error may be caused by a delegation issue. Check the authentication
    method (see Microsoft web site).

[4] See article ID 189408 on Microsoft's web site.


4.3.10 Why do I get "Incorrect Syntax near the Keyword 'by'" error message
--------------------------------------------------------------------------
       when calling SQLDescribeParam in the MS SQL Server ODBC driver?
       ---------------------------------------------------------------

When calling SQLDescribeParam in the MS SQL Server ODBC driver you get
an error return with the diagnostic text:

"Incorrect Syntax near the Keyword 'by'"

This was a bug in MDAC 2.6 and is fixed in MDAC 2.6 sp1.

It happens if you have a column named "c", "ca" or "cas" and you call
SQLDescribeParam because the driver is checking for a CASE statement
and does the check incorrectly.

See http://support.microsoft.com/directory/article.asp?ID=KB;EN-US;Q273813.

4.3.11 Why do I get "[Microsoft][ODBC SQL Server Driver][Named Pipes]
---------------------------------------------------------------------
       ConnectionOpen (CreateFile())"?
       -------------------------------

It is a resource issue when running a lot of processes
(e.g. MultiProcess in the OOB Server) to the MS SQL Server ODBC driver
issue. Switch to TCP/IP instead of named pipes in the MS SQL Server
ODBC DSN and the problem will go away.

4.3.12 Why do parameterised inserts appear to hang and my OOB Server is
-----------------------------------------------------------------------
       using over 90% of cpu?
       ----------------------

This was first reported to us from a customer using Perl but it is not
Perl related, it appears SQL Server 7 specific. If you call
SQLDescribeParam after preparing a parameterised insert but the SQL is
incorrect the SQL Server ODBC driver talking to SQL Server 7 does not
appear to return from the SQLDescribeParam call.

e.g.

insert into table values (column1, column2) (?,?)

Note this SQL is incorrect as the "values" should come after the
column names.

The sequence of ODBC calls is:

SQLPrepare("insert into table values (column1, column2) (?,?)")
SQLNumParams() returns 2 correctly
SQLDescribeParam(1) hangs never returning

It appears the SQL Server ODBC driver rearranges the SQL to issue a
select statement on the table for the specified columns so it can find
out column information to be returned as parameter information.  In
the case of incorrect SQL, this process does not appear to work to SQL
Server 7.

4.3.13 Why do I get an Access Violation in MS SQL Server ODBC Driver?
---------------------------------------------------------------------

  Issue 1:
  --------
  
  We reported the following issue on microsoft.public.sqlserver.odbc:
  
  Using MS SQL Server ODBC driver version 3000.81.9030.04.
  Create a table and deny select permission to a specific user
  From odbctest do a full connect with ODBC 2.0 checked
  Do an SQLPrepare(select * from table)
  Do an SQLNumResultCols - this fails with permission denied
  DO an SQLExecute and you get an exception in odbctest
  
  "The instruction at "0x119c8fcc" referenced memory at
  "0x0170e000". The memory could not be written"
  
  Better exception data from my own application instead of
  odbctest says:
  
  Exception Address: 0X1F9C8F22
  Number of Parameters: 2
  Exception Record: 0X00000000
  Exception Information (RW Flag) : Write
  Exception Information (Virtual Address) : 0X0162E000
  
  Module: C:\WINNT\System32\SQLSRV32.dll, Section: 01,
  Offset:00007F22
  Call Stack:
  Address   Frame
  1F9C8F22  0120F854  SQLNumResultCols+3EB
  1F9EF7E4  0120F8B8  BCP_init+5D2
  1F9F1737  0120F8CC  SQLNativeSqlW+637
  1F9F47DA  0120F900  SQLExecute+1E1
  1F7CD793  0120F91C  SQLExecute+D1
  004227CC  0120F988  0001:000217CC
  C:\WINNT\System32\esoobserver.exe
  00419A85  0120FF84  0001:00018A85
  C:\WINNT\System32\esoobserver.exe
  0042F218  0120FFB8  0001:0002E218
  C:\WINNT\System32\esoobserver.exe
  77F04EDE  0120FFEC  lstrcmpiW+BE
  No deeper stack frame
  
  Brannon Jones, MDAC Developer said he had reproduced it and submitted a
  bug.
  
  We have also seen it in version 2000.85.1025.00 of the MS ODBC driver.
  
  You might be able to identify this problem from the entry the OOB
  Server puts into the application event log or the esoob.exception file
  in LogDir. An example follows:
  
  Current OOB Flags: 0X112
  OS: Major 5, Minor 0, Build 2195, Service Pack 4
  PageSize: 4096, AllocationG: 65536, MinAppA: 00010000, MaxAppA: 7FFEFFFF
  Active Processor Mask: 1, Number of Processors: 1
  Username: XXXXX
  Computer Name: YYYYY
  cwd: C:\WINNT\system32
  System Dir: C:\WINNT\system32
  Windows Dir: C:\WINNT
  Exception Code: 0XC0000005 (ACCESS_VIOLATION) 
  Exception Flags: 0 
  Exception Address: 0X0176136B 
  Number of Parameters: 2 
  Exception Record: 0X00000000 
  Exception Information (RW Flag) : Write 
  Exception Information (Virtual Address) : 0X01C0D000
  exception_filter() at 0041C7B0
  RPCAllocHandle() at 0042EE98
  Last RPC: Name=sql_execute, Ordinal=91
  Current Thread : 2060
  Module: C:\WINNT\System32\SQLSRV32.dll, Section: 01, Offset:0000036B 
  Thread List:
  in_use, threadid, threadh, socket, client_ip, dsn,start_time 
  0 340 0x00000000 1744 10.10.10.5 - Tue Sep 14 13:25:11 2004
  
  You can view the posting in Google
  http://groups.google.co.uk/group/microsoft.public.sqlserver.odbc/browse_thread/thread/f4a32fc17fa5521c/eb4ffe115b956fbd?lnk=st&q=Brannon+Jones+martin+evans&rnum=7&hl=en#eb4ffe115b956fbd

Issue 2:
--------

  One of our customers came to us with an exception like the one
  below. After much investigation it appears the MS SQL Server ODBC
  driver was writing off the end of the parameter status array (i.e.
  the buffer set with SQL_ATTR_PARAM_STATUS_PTR). The circumstances in
  which this happens are fairly complicated but are summarised as:
  
  create a statement
  prepare some sql
  set SQL_ATTR_PARAM_STATUS_PTR
  set SQL_ATTR_PARAMSET_SIZE to N (e.g. 1000)
  bind parameters
  execute the statement
  reset parameters with RESET_PARAMS
  set SQL_ATTR_PARAMSET_SIZE to N-M (e.g. 800)
  set SQL_ATTR_PARAM_STATUS_PTR
  bind parameters
  execute <- fails here
  
  What appears to be happening is that the driver has missed the
  reduction in the SQL_ATTR_PARAMSET_SIZE when writing the parameter
  status array values back.
  
  Easysoft ODBC-ODBC Bridge
  Version: 02.00.0012
  Component: OOB Server (ODBC thread/process)
  Build Date: $Built: Jan  9 2006 11:30:53 $
  Caught Exception on Thu Jan 12 00:36:51 2006
  
  Current OOB Flags: 0X8112
  OS: Major 5, Minor 2, Build 3790, 
  PageSize: 4096, AllocationG: 65536, MinAppA: 00010000, MaxAppA: 7FFEFFFF
  Active Processor Mask: 3, Number of Processors: 2
  Computer Name: XXXXX
  cwd: C:\WINDOWS\system32
  System Dir: C:\WINDOWS\system32
  Windows Dir: C:\WINDOWS
  Exception Code: 0XC0000005 (ACCESS_VIOLATION)
  Exception Flags: 0
  Exception Address: 0X1F9DA74F
  Number of Parameters: 2
  Exception Record: 0X00000000
  Exception Information (RW Flag) : Write
  Exception Information (Virtual Address) : 0X0144910E
  exception_filter() at 004208C0
  RPCAllocHandle() at 00434BFC
  Last RPC: Name=sql_execute, Ordinal=91
  Current Thread : 5884
  Module: C:\WINDOWS\system32\SQLSRV32.dll, Section: 01, Offset:0001974F
  Call Stack:
  Address   Frame
  1F9DA74F  0184F150  SQLDescribeColW+2978
  No deeper stack frame
  Last error from StackWalk = 0
  Thread List:
  in_use, threadid, threadh, socket, client_ip, dsn,start_time
  1 760 0x00000118 364 172.20.30.10 vtqrs Thu Jan 12 00:36:16 2006
  
  1 5884 0x0000014C 368 172.20.30.10 vtqrs Thu Jan 12 00:36:16 2006

  We saw this in SQL Server ODBC driver versions 2000.85.1025.00,
  2000.86.1830.0, 2000.85.1117.00 and 2000.85.1022.00 but it may also
  be in others.

4.3.14 Why are my numeric and currency values returned too long with
--------------------------------------------------------------------
       an additional random character from MS SQL Server?
       --------------------------------------------------

If you check "Use regional settings when outputting currency, numbers,
dates and times" in a MS SQL Server data source and then retrieve numeric
or currency fields as chars (SQL_CHAR) you will encounter two
problems:

1. For numeric data MS SQL Server will convert the number using your 
   regional settings. e.g. the number 1000 in the UK is converted to
   1,000.00. Unfortunately length returned by the SQLGetData or SQLFetch
   (with SQLBindCol) is one more than the actual data returned. 
   For the returned string "1,000.00" MS SQL Server will actually say this
   string is 9 characters long when in fact it is 8.

   You can reproduce this with a simple bit of perl:

   my $sth = $dbh->prepare("select count(*) from table");
   $sth->execute;
   my @row = $sth->fetchrow_array);
   print "\"$row[0]\" length of ". length($row[0]). "\n";
   print "unpacked - |". unpack("H*", $row[0]), "|\n";

   which when there are 1000 rows prints:

   "1,000.00" length of 9
   unpacked - |312c3030302e303000|

   Notice the length of 9 (one too many) and the last character is
   hex 00 here but in actual fact seems pretty random. If you run this
   code under the perl debugger and use the 'x' command on $row[0] you'll
   see something like this:

   DB<1> x $row[0]
   0  "1,000.00\c@"

   To reproduce in the ODBC API simply:

   connect etc
   SQLExecDirect("select count(*) from table");
   SQLFetch
   SQLGetData(SQL_CHAR, buffer, buffer_size=20, StrLen_or_IndPtr)

   and you'll get 9 back in StrLen_or_IndPtr when the returned data
   is "1,000.00" (one too many).

2. The second problem is that when regional settings are turned on numeric
   and currency data are longer than with regional settings off but
   SQLDescribeCol does not return larger column sizes. This is best
   documented in
   4.1.15 Why do I get "String data, right truncation" retrieving result-sets
   from MS SQL Server?"

If you cannot change the type retrieved from SQL_CHAR to SQL_INTEGER
then you'll need to uncheck the regional settings in the data source.

4.4 Other applications/interfaces
---------------------------------

4.4.1 ld: cannot open -lesoobclient: No such file or directory
--------------------------------------------------------------
      when attempting to link an application with the OOB
      ---------------------------------------------------

You need to tell the dynamic linker where to find the libesoobclient
shared object (there are some other required shared objects in the
easysoft/lib subdirectory of the installation path too).

For Linux:

In the beta releases, the installation script does not add entries to
the /etc/ld.so.conf file if the installing user is NOT root or if only
the client is installed. You need to add the paths to all the shared
objects in the OOB installation to /etc/ld.so.conf and rerun ldconfig
(usually in /sbin). e.g. if you installed OOB in the default location
you would add:

/usr/local/easysoft/lib
/usr/local/easysoft/oob/client

to /etc/ld.so.conf and then run /sbin/ldconfig. To be sure they are
picked up properly you can use /sbin/ldconfig -v where part of the
output for the default installation path would be:

/usr/local/easysoft/lib:
        libesrpc.so => libesrpc.so
        libsupport.so => libsupport.so
/usr/local/easysoft/oob/client:
        libesoobclient.so => libesoobclient.so

Note that you must be root to run ldconfig and probably, to edit
/etc/ld.so.conf.

For other UNIX platforms:

Read the above for Linux first. However, most platforms do not have
an equivalent of the /etc/ld.so.conf file and that usually means
you have to add the paths to the LD_RUN_PATH, LD_LIBRARY_PATH, SHLIB_PATH
or LIBPATH environment variables and then export them. e.g.

$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/easysoft/lib:/usr/local/easysoft/oob/client
$ export LD_LIBRARY_PATH

An alternative, although not one that Easysoft particularly recommends
is that you move the shared objects to a directory which is on your
linker's default search path (e.g. /usr/lib).

If you installed the unixODBC driver manager in the OOB distribution
you will want to add the path /usr/local/easysoft/unixODBC/lib to the
above.

4.4.2 Why do I get Driver's SQLAllocHandle on SQL_HANDLE_ENV failed with the
----------------------------------------------------------------------------
      Microsoft Oracle ODBC driver?
      -----------------------------

When connecting to a DSN using the Microsoft Oracle ODBC driver
SQLAllocHandle/SQLAllocEnv fails and SQLGetDiagRec or SQLError
returns:

IM004:1:0:[Microsoft][ODBC Driver Manager]
Driver's SQLAllocHandle on SQL_HANDLE_ENV failed

You need to install the NET 8 libraries which may be obtained by
installing the Oracle client. The Oracle ODBC driver includes them so
this problem does not occur when the Oracle ODBC driver is used.

You also need to make sure that the path to the Oracle DLLs included 
with the Oracle client is included in your system PATH. e.g. if
Oracle client is installed in C:\oracle\ora81 then C:\oracle\ora81\bin
needs to be in your PATH environment variable. Two common problems
related to incorrectly set PATH are:

[1] the Oracle client was installed by user A on the machine where user
    A is not the administrator. User A's PATH includes the path to the
    Oracle client libraries but the OOB Server is a service running as
    local admin and so the Oracle client directory needs to be in the
    system PATH.

[2] the PATH environment contains the correct path but preceded by
    an old Oracle client install directory which still exists.

You can check the PATH environment by going to control panel -> System ->
Environment. System environment variables available to everyone are in
the top pane and user-specific variables in the lower pane.

4.4.3 Why do I get "IM004, Driver's SQLAllocHandle on SQL_HANDLE_HENV failed"
-----------------------------------------------------------------------------
      connecting to DB2?
      ------------------

This error generally occurs in UNIX because the environment variable
DB2INSTANCE is not set and exported before the OOB Server is started.
You need to either:

[1] edit /usr/local/easysoft/oob/server/server and add 
    DB2INSTANCE=xyz
    export DB2INSTANCE
    before the cd at the end of the file or
[2] defined DB2INSTANCE and export it before starting esoobserver
    standalone.

Alternatively, if you are using the unixODBC driver manager you can
use SQL_ATTR_UNIXODBC_ENVATTR in the odbc.ini file (see elsewhere in
this FAQ) to set environment variables per DSN.

4.4.4 Why am I having intermittent problems with a particular ODBC driver?
--------------------------------------------------------------------------

Some ODBC drivers are not thread-safe and by default the OOB Server
for Windows runs multi-threaded. This can give rise to a whole host of
intermittent and peculiar errors. You should make the OOB server run
multi-process so that there is only ever one thread at a time in the
ODBC driver. See "Why does my second connection to MS Access hang?"
for the method of making the OOB server run multi-process.

Drivers we have encountered that it is best to set the OOB server to
run multi-process for are MS Access ODBC, Freedom Intelligence,
Navision, Margin Minder, TPS ODBC and eMatrix ODBC.

4.4.5 Why doesn't a query return recently inserted data?
--------------------------------------------------------

Insert statements seem to work okay and an immediate select with the
same cursor works to display the data, but when I retry the query the
data is gone.

Some ODBC enabled languages have autocommit set to off by default. (In
PHP and Perl autocommit is set to on by default)

There are two options to ensure that insert statements are committed
to the database.

1. Ensure that the relevant autocommit flag is switched on in your
   connection.

2. Use appropriate commit and rollback methods in your script.


See the following resources for detailed information on how to do this
in individual languages: -

Python - mxODBC
http://www.lemburg.com/files/python/mxODBC.html

Perl
perldoc DBI or http://dbi.perl.org

PHP 
http://www.php.net

4.4.6 I don't like my odbc.ini in the same directory as my PHP/Perl script
--------------------------------------------------------------------------
      as people browsing my web site may see it and it contains passwords.
      --------------------------------------------------------------------
      What do I do?
      -------------


You can place your odbc.ini file in the current users home directory
or in the file pointed to by the ODBCINI environment variable. You can
also put your DSNs in /etc/odbc.ini. You can also place the sensitive
information in the call to SQLDriverConnect by setting the attributes
in the in_connection_string parameter.


e.g. SQLDriverConnect(dbc,
                      "DSN=dsn_name;LOGONUSER=username;LOGONAUTH=password;",
		      ...);

Attributes set in the in_connection_string argument to
SQLDriverConnect override values in the odbc.ini file.

To set the ODBCINI environment variable from PHP use:
putenv ("<path>/odbc.ini");

To see what environment variables are set to from PHP use:
phpinfo();

4.4.7 Why cannot I use multiple active statements?
--------------------------------------------------

Multiple active statements is an ODBC driver facility.

The ODBC-ODBC Bridge will allow multiple statements on a connection if
the ODBC driver allows this.

The ODBC API defines a method of obtaining whether a driver handles
multiple active statements. 

In ODBC 2.0 you need to call SQLGetInfo() requesting
SQL_ACTIVE_STATEMENTS. This returns a 16 bit integer value specifying
the maximum number of active statements that the driver can support
for that connection. If there is no limit of the limit is unknown,
this value will be returned as zero.

In ODBC 3.0 you need to call SQLGetInfo() requesting
SQL_MAX_CONCURRENT_ACTIVITIES. This returns a SQLUSMALLINT value
specifying the maximum number of active statements that the driver
can support for that connection. A statement is defined as active if
it has results pending, with the term "results" meaning rows from a
SELECT operation, or rows affected by an INSERT, UPDATE or DELETE
operation (such as a row count), or if it is in a NEED_DATA
state. This value can reflect a limitation imposed by either the
driver or the data source. If there is no specified limit or the limit
is unknown, this value is set to zero.

With MS SQL Server, whilst you may allocate multiple statement handles
against a connection, you can only have one statement with a rowset
associated with it (using the default result sets). If you attempt to
use multiple active statements in MS SQL Server you will get an error
similar to the following:

[Microsoft][ODBC SQL Server Driver]Connection is busy with results for 
another hstmt (SQL-S1000)

There appear to be ways around this (at least in SQL server 6.5) but
they all involve clearing the remainder of the current resultset which
is generally not useful.

See http://msdn.microsoft.com/library/psdk/sql/6_030_2.htm for more
information on this.

If you need to keep things simple at the application end and have a
single connection then you can employ the Easysoft SQL Engine on the
server (i.e. the machine where the OOB server resides). This allows
you to have a single connection and open multiple statements against
SQL Server or any other ODBC data source.

For information on the Easysoft SQL Engine see

http://www.easysoft.com/products/sql_engine/main.phtml

Failing that you have to employ multiple connections from your
application.

4.4.8 Why can't I run CGI programs using OOB under
--------------------------------------------------
      Netscape Enterprise Server?
      ---------------------------

By default the Netscape Enterprise Server does not export environment
variables to the CGI program. We found this reference which explains
how to make it export environment variables:

http://help.netscape.com/kb/corporate/19960804-40.html

On most UNIX platforms you need to export LD_LIBRARY_PATH by adding
the following to your obj.conf file:

Init fn="init-cgi"
LD_LIBRARY_PATH="<path-to-easysoft>/oob/client:<path-to-easysoft>/lib"

4.4.9 Why do I not get a list of all the tables and columns in a database?
--------------------------------------------------------------------------

By default OOB uses metadata blockfetchmode which is an optimisation
speeding up the retrieval of metadata result sets. Some ODBC drivers
do not work properly with metadata blockfetchmode which binds the
columns in the result set and sets the row array size. The symptom is
usually that you see the first two tables/columns and then every 10th
table/column and all the others are missing. If you suspect you are
having this problem disable metadata blockfetchmode in your DSN by
either:

[1] In the Windows OOB DSN, uncheck metadatablockfetch.
[2] In UNIX, add MetaDataBlockFetch=0 to the affected DSNs in your odbc.ini
    file.
[3] Pass MetaDataBlockFetch=0 in the connection string.

At present we have only had this reported for the tickets.com ODBC
driver and Neon Systems Shadow Connect driver for DB2.

This attribute is only available in OOB 1.0.0.13 onwards.

In versions prior to 1.0.0.13 you can do one of the following:

[1] UNIX/OpenVMS
    Add

    {Settings}
    Flags = 0x8 

    to the top of an odbc.ini file in the current working directory of
    your application.
[2] In Windows add 8 to the registry key:

HKEY_LOCAL_MACHINE\
SOFTWARE\
EASYSOFT ODBC-ODBC BRIDGE\
CONFIGURATION\
SYSTEM\
SETTINGS\
FLAGS

4.4.10 Why do I get a transaction already started error calling a procedure?
----------------------------------------------------------------------------

This often happens if the procedure mixes insert/update and select
operations and auto-commit has been turned off. This is quite a common
question from people using Perl where the script connects with
autocommit turned off (as in one of the OOB examples):

my $dbh = DBI->>connect($ENV{DBI_DSN},
                        $ENV{DBI_USER},
                        $ENV{DBI_PASS},
                        {
                            RaiseError => 1,
                            AutoCommit => 0
                            }
                        ) || die "Database connection failed: $DBI::errstr";

4.4.11 Why do I get ODBC driver authentication denied when using  unixODBC's
----------------------------------------------------------------------------
       isql and DataManager?
       ---------------------

isql and DataManager (in unixODBC 1.8.8 and prior versions at least)
call SQLConnect passing a database username and password even if you
do not specify them. isql, takes two optional arguments after the DSN
which are the database username and database password. If you omit
them then isql passes empty strings to OOB which believes a
username and password were specified and hence does not pull the
TargetUser and TargetAuth out of the DSN.

If your ODBC driver requires a username and password and you are using
isql or DataManager you must specify them either on the command line
or in the dialogue DataManager pops up.

4.4.12 How do I pass LD_LIBRARY_PATH down to CGI programs from Apache?
----------------------------------------------------------------------

If you are running an application using OOB under Apache as CGI
(e.g. a perl script) on a platform where the dynamic linker needs to
be told where to find all required shared objects using an environment
variable your CGI program will need this environment variable set
up. You need to add to your Apache configuration file (probably
httpd.conf) a SetEnv (or PassEnv if Apache 1.1 or later) command
similar to the one below:

SetEnv LD_LIBRARY_PATH /usr/local/easysoft/unixODBC/lib:/usr/local/easysoft/oob/client:/usr/local/easysoft/lib

Not all dynamic linkers use LD_LIBRARY_PATH, some use LIBPATH,
SHLIB_PATH etc. Check you dynamic linker documentation for the correct
environment variable.

The Apache group has full documentation for SetEnv at
http://httpd.apache.org/docs/mod/mod_env.html

The above assumes you are using straight CGI with your program running
external to your web server. If you are running something like
mod_perl where the Perl interpreter is built into Apache then you may
need to tell your dynamic linker where to find OOB shared objects
before Apache is started. For Apache you might set and export
LD_LIBRARY_PATH etc in the apachectl.

4.4.13 Does OOB work with OpenOffice.org?
-----------------------------------------

We have tested OOB with OpenOffice.org 2.0+ on RedHat 9.0 (which
includes unixODBC 2.2.3) and OpenOffice.org 1.0+ on RedHat 8.0 (which
includes unixODBC 2.2.2). For OpenOffice.org 1.0+, pass through queries
work from the various OpenOffice.org applications but queries built
using the query builder do not work. This is reported as instance
10577 at OpenOffice.org and can be found here:

http://www.openoffice.org/issues/show_bug.cgi?id=10577


4.4.14 What does "[Easysoft ODBC][unixODBC][Driver Manager]Can't initiate
-------------------------------------------------------------------------
       unicode conversion" mean?
       -------------------------

This ODBC diagnostic is from the unixODBC driver manager. This
diagnostic may be returned by the unixODBC driver manager when calling
SQLConnect, SQLDriverConnect or SQLBrowseConnect and results in a
SQL_SUCCESS_WITH_INFO return. SQL_SUCCESS_WITH_INFO is not an error
return, but some ODBC applications output informational diagnostics
after connection. You should look at any subsequent diagnostics if
your connection failed as this one does not cause connection failures.
It means unixODBC was built with iconv support but it could not find a
map in iconv. It is not a matter of concern for most people.

iconv support in unixODBC is used to translate ASCII to UNICODE and
vice versa. If your application is not making UNICODE ODBC calls
(SQLxxxW functions), and most do not, then you are not using iconv
support anyway.

Some releases of OOB contain unixODBC which was built with iconv
support unnecessarily. RedHat distribute unixODBC with iconv support.
If you build unixODBC yourself then you will probably get iconv
support by default. You can disable iconv support when configuring
unixODBC using the configure option --enable-iconv=no.

4.4.15 Why does SQLDriverConnect return "The driver doesn't support the
-----------------------------------------------------------------------
       version of ODBC behavior that the application requested"?
       ---------------------------------------------------------

This is an informational (SQL_SUCCESS_WITH_INFO) message and not an
error. It usually occurs if the application requests ODBC 3.0 behavior
and the ODBC driver is ODBC 2.0. It does not mean your application
will not work as the ODBC Driver Manager will attempt to map between
the two.

When running oobping or clicking on Test in the OOB DSN setup dialogue
you may see this warning when connecting to ODBC 2.0 drivers as
oobping and OOB's test code is ODBC 3.0. It does not cause oobping or
OOB's test to fail. If either fail it is because there is another
error message which caused the failure.

ODBC can stack multiple diagnostics when an API is called, then when
SQLError/SQLGetDiagRec are called repeatedly they will show all the
diagnostics. As example from OOB's test dialogue:

08004:1:1058:[Navision Software a/s][Navision Financials ODBC Driver]
    Data source rejected establishment of connection
01000:2:0:[Microsoft][ODBC Driver Manager]
    The driver doesn't support the version of ODBC behavior that the
    application requested

The first diagnostic is an error with a native error code of 1058
which may be looked up in the ODBC driver documentation. The second
diagnostic is informational and the connection failed because of the
first error.

4.4.16 How can I avoid setting shell environment variables required by
----------------------------------------------------------------------
       a driver?
       ---------

Some drivers require environment variables setting before you can
successfully connect (e.g. DB2 and DB2INSTANCE, Oracle and
ORACLE_HOME). If you are using the unixODBC Driver Manager you can set
environment variables per DSN in the odbc.ini file using the following
syntax:

DMEnvAttr = SQL_ATTR_UNIXODBC_ENVATTR={ENVVAR=value}

e.g.

DMEnvAttr = SQL_ATTR_UNIXODBC_ENVATTR={DB2INSTANCE=db2inst2}

The unixODBC driver manager will then set the environment variable
before connecting to the driver. Note, this only works this way when
using DSN based connections.

4.4.17 Why do I get the error "Initialization function SQLAllocConnect
----------------------------------------------------------------------
       not found" when attempting to use Oracle heterogeneous services
       ----------------------------------------------------------------
       (hsODBC) on AIX?
       ----------------

Assumptions:

You are using Oracle's heterogeneous services (hsODBC) and the ODBC-ODBC
Bridge on AIX.

You are using the unixODBC driver manager (it does not matter if you
built it yourself or are using the one that came with OOB).

You have set your LIBPATH correctly to include the paths
/usr/local/easysoft/unixODBC/lib and /usr/local/easysoft/lib.

You are getting an error similar to the example below when attempting
to use your defined hsODBC link in sqlplus:

ERROR at line 1:
ORA-28500: connection from ORACLE to a non-Oracle system returned this
message:
[Generic Connectivity Using ODBC]DRV_InitTdp: DB_ODBC_INTERFACE(6);
Initialization function SQLAllocConnect not found
DB_ODBC_INTERFACE(7); Cannot connect to shareable
/usr/local/easysoft/unixODBC/lib/libodbc.a. Using dummy functions
ORA-02063: preceding 3 lines from OCI1

On AIX this is a problem due to hsODBC being linked against libodbc.so
but the unixODBC you are using contains libodbc.so.1 in the libodbc.a
archive. You can check this by:

1. cd /usr/local/easysoft/unixODBC/lib 
   or the lib directory or where you installed unixODBC

2. ar -tv libodbc.a

If this shows the archive contains libodbc.so.1 this is your problem
and the solution is:

1. Become root or whoever you need to be to create files in the
   unixODBC lib subdirectory.

2. cd /usr/local/easysoft/unixODBC/lib or the lib directory or where
   you installed unixODBC

3. Run
   ar -xv libodbc.a

   This should extract the file libodbc.so.1 to the currrent
   directory.

4. Rename libodbc.so.1

   mv libodbc.so.1 libodbc.so

5. Point HSODBC at it directly by amending the HS_FDS_SHAREABLE_NAME
   in your init[name].ora file to be:

   HS_FDS_SHAREABLE_NAME = /usr/local/easysoft/unixODBC/lib/libodbc.so

Restart your Oracle listener. Your link should now work.

4.4.18 Why cannot I see my tables in Excel/Query for MAC OS X?
--------------------------------------------------------------

Operating System: MAC OS X
Application: Microsoft Query X and Microsoft Excel X

Symptom: When you start a new worksheet and use Data -> Get External
Data > New Database Query, select a data source and click on "Show
Tables" MS Query X displays the tables dialogue but no tables are
shown. You can click on lines in the tables dialogue and scroll up and
down but all the table names are blank.

Easysoft have identified this issue as Microsoft Query X not handling
SQL_WVARCHAR column types and the MS SQL Server ODBC driver describes
the table name column as SQL_WVARCHAR. To work around this you need to
add:

DisguiseWide=1

to the data source you are using.

4.4.19 Does OOB work with Lotus Notes/Domino?
---------------------------------------------

Yes. There are installation/configuration notes available on the
Easysoft web site at
http://www.easysoft.com/products/2002/lotus.phtml.

4.4.20 Can I access Foxpro databases with OOB?
----------------------------------------------

Yes.

1. Install the OOB client on the UNIX machine where you want access to
   the FoxPro database.

2. Install the OOB Server on the Windows machine where you have an ODBC
   driver for FoxPro.

3. Create a SYSTEM DSN on the Windows machine using the FoxPro setup
   dialogue off the Data Source Administrator.

4. Create an OOB Client DSN on the UNIX machine which points to the
   OOB Server with a TargetDSN named as in 3.

See the OOB manual for a full description of this process.

4.4.21 Can I use OOB with Actuate Reporting Applications?
---------------------------------------------------------

Yes, we have customers doing this.

The basic formula below assumes you have Actuate installed in
$AC_SERVER_HOME and OOB in /usr/local/easysoft:

1. cd $AC_SERVER_HOME/lib
   ln -s /usr/local/easysoft/unixODBC/lib/libodbc.so ODBC.so

2. Your DSN can go in /etc/odbc.ini.

3. You should not need to set ODBC_INI_PATH or ODBC_MGR_PATH in the pmd7.sh
   file.

4. Make sure pmd7.sh has LD_LIBRARY_PATH to include

   /usr/local/easysoft/lib:/usr/local/easysoft/unixODBC/lib

4.4.22 Can I use the OOB with Oracle heterogeneous services (hsodbc)?
---------------------------------------------------------------------

Yes.

You can use the OOB to access remote ODBC drivers from Oracle e.g. MS
SQL Server or MS Access. This allows you to exchange data between
Oracle and other databases.

See the Easysoft web site, select OOB then Applications and Interfaces
then select hsodbc for a full description.

Many of our customers have used OOB under hsodbc in Oracle 10G, and
Oracle 9 to connect their Oracle database to many other remote
databases like MS SQL Server.

NOTE:
1. hsodbc is a 32-bit application. You need to use it with a 32-bit
   Easysoft ODBC driver. For 64-bit platforms, choose the 32-bit
   version of the driver even when there's a 64-bit version
   available. 32-bit drivers will still function correctly on a 64-bit
   platform.

2. You may need to set OOB's connection attribute DisguiseWide to 1
   because hsodbc does not seem to understand SQL_C_Wxxx types.
   See 'Why do I get "table of view does not exist" when selecting from
   a table using Oracle hsODBC connected to MS SQL Server with OOB?'


4.4.23 Why do I get "table of view does not exist" when selecting from a table
------------------------------------------------------------------------------
   using Oracle hsODBC connected to MS SQL Server with OOB?
   --------------------------------------------------------

If you connect from Oracle hsODBC to SQL server via the ODBC-ODBC
Bridge and when selecting from a table (CUSTOMERS found in the
Northwind sample database for instance) you get an error along the
line of:

SQL> select * from CUSTOMERS@hsodbc;
select * from CUSTOMERS@hsodbc
             *
ERROR at line 1:
ORA-00942: table or view does not exist
[Generic Connectivity Using ODBC]
ORA-02063: preceding 2 lines from HSODBC

It may of course be because you have mistyped the table name.

It could mean the table contains a Wide Character that the Oracle
application has problems with. To solve this add the following
attribute to the OOB datasource within the odbc.ini file:

disguisewide = 1

This will allow the data to be represented within sql*plus

4.4.24 Can I use OOB to access my remote database?
--------------------------------------------------

If you have an ODBC driver on a machine where you can install the OOB
Server then yes. Our customers use OOB to remotely access hundreds of
databases including btrieve, pervasive, MS SQL Server, Oracle, FoxPro,
Paradox, MS Access, MS Excel, Navision, Sybase, DB2, Dbase, ISAM, RMS,
Lotus Note/Domino, SystemZ, Tetra, Coda and many, many more.

4.4.25 Why do I get "libodbc.a(odbc.so) could not be loaded" using
------------------------------------------------------------------
       Informatica with unixODBC and OOB?
       ----------------------------------

The actual error reported to us was:

0509-150 Dependent module
/usr/local/easysoft/unixODBC/lib/libodbc.a(odbc.so) could not be loaded.

and this is an AIX-specific issue.

At various stages in unixODBC's history libtool (used to create
unixODBC shared objects) has created:

libodbc.a(libodbc.so)
libodbc.a(libodbc.so.1)

Applications linked against the library are dependent on the name of
the archive (libodbc.a) and the name of the object inside it. Running
dump -H on unixODBC's isql included with OOB2 might display:

INDEX  PATH                          BASE                MEMBER
3                                    libodbc.a           libodbc.so.1

Informatica has a dependency on libodbc.a(odbc.so). To ensure, isql
(and any other applications built directly with your current unixODBC)
continue to work but also allow Informatica to work you need to extract
the current object from libodbc.a, rename it and add it back to the
archive.

e.g.

$ cd /usr/local/easysoft/unixODBC/lib
$ ar -tv libodbc.a
rwxr-xr-x   201/1     698963 Oct 04 11:21 2004 libodbc.so.1
$ ar -xv libodbc.a
x - libodbc.so.1
$ mv libodbc.so.1 odbc.so
$ ar -rv libodbc.a odbc.so
a - odbc.so

4.4.26 Why do I receive the error "No ODBC driver is installed" when
--------------------------------------------------------------------
       I try to retrieve data in Microsoft Excel for MAC?
       --------------------------------------------------
On Mac OS X 10.4 (Tiger), you will be unable to retrieve data from ODBC
data sources to Excel X unless you install the iODBC SDK. This is
because Microsoft Query (an application that Excel uses to retrieve
external data) is a CFM application, and the ODBC libraries that Apple
install are Mach-O libraries (a different format).

5. Operating System Specific - Linux
------------------------------------
5.1 Which version of OOB should I be using?
-------------------------------------------

Linux systems can run with two different and incompatible C runtime
libraries. libc5 is the old C runtime library and glibc (aka libc6) is
the latest thread-safe version. The OOB version for libc5 will not
work with a glibc based system and vice versa. It is not always that
straight forward deciding whether your system, is libc5 based or glibc
based as many newer Linux distributions come with glibc as the default
but have the older libc library for backwards compatibility. If you
don't know whether you are libc5 or glibc based then try the
following:

ls  /lib/libc.*

On our glibc based machine at Easysoft that produces:

/lib/libc.so.4
/lib/libc.so.5
/lib/libc.so.6
/lib/libc.so.4.7.6
/lib/libc.so.5.4.46

Notice the libc.so.6 which is the tell tale sign that this machine is
running glibc. If you don't see a libc.so.6 then the chances are that
you have a libc5 based system.

The OOB install contains a small program called testlib (this will be
in the directory created when you unpack the OOB distribution). It is
a small C program which uses C runtime functions and maths library
functions and is built on the same machine as the OOB
distribution. When run it should output "hello4". The install runs
this to make sure you have the correct libraries and if you don't the
install will be aborted.

There are however further issues. Even if you have support for libc5
and glibc what version of the the C runtime library does your compiler
and linker use when you create new libraries and executables? This is
a key issue as if you have both libc5 and glibc but gcc/ld create
executables linked with glibc then you cannot use the libc version of
OOB with other programs which you build yourself (e.g. Perl/PHP).  The
testlib program referred to above is basically:

#include <stdio.h>
#include <math.h>

int main()
{
    double      j = 3.14;

    printf("hello%1.0f\n", ceil(j));
    return 0;
}

To be sure which version of OOB you should download compile the above
c program as follows:

[1] create testlib.c containg the above.
[2] compile with cc -o testlib testlib.c -lm
[3] run ldd on testlib - ldd ./testlib
[4] examine the output to see what versions of the C runtime library and
    maths library your system is using.
e.g.
> cc -o testlib testlib.c -lm
> ldd ./testlib
        libm.so.5 => /lib/libm.so.5 (0x4000b000)
        libc.so.5 => /lib/libc.so.5 (0x40013000)

This system is using libc5 and the version5 of the maths library so
download the libc5 distribution of OOB.

> cc -o testlib testlib.c -lm
> ldd ./testlib
        libm.so.6 => /lib/libm.so.6 (0x40018000)
        libc.so.6 => /lib/libc.so.6 (0x40035000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

This system is using glibc and version 6 of the maths library so
download the glibc distribution of OOB.

There is one further distribution of OOB for glibc based systems and
that is the thread-safe version which is linked with -lpthread (Linux
Threads).  You should only use this version if your application
creates multiple threads and certainly do not attempt to use this with
Perl currently which is not threaded. The threaded (thread-safe) OOB
distributions have -mt in the distribution name. You should also be
aware that there have been a number of bugs reported in
glibc/linux_threads and you should check the glibc web pages and
mailing lists or the web page for your Linux distributor.

Once you have worked out which C run time library you are using
download the appropriate version from our FTP site.

Please make sure that you at least have the minimum version of libc
required for your kernel. If you are unsure, check the
Documentation/Changes file in the kernel sources.

5.2 What Linux kernels can I run?
---------------------------------

The Easysoft ODBC-ODBC Bridge is currently built on 2.0.36 with libc5
(5.4.33) and 2.2.14 with glibc 2.1. Easysoft will always endeavor to
support the latest stable kernel version and it is unlikely that the
OOB will not work with the latest development kernels.

It is unlikely that the OOB will work with 1.2.n kernels and perhaps
even 1.3.n kernels.

Please make sure that if you experience problems that you double check
the Documentation/Changes file in the kernel sources to make sure that
all the minimum requirements for the kernel you are running are
satisfied. This can be particularly important when it comes to the
run-time C library. We have seen people with libc5 based systems at
version 5.4.38 experiencing problems when used on a 2.2.n kernel but
the minimum requirement is 5.4.46.

5.3  Linker errors building Apache/PHP with OOB
-----------------------------------------------

There are generally 2 reasons for linker failures when building
Apache/PHP with OOB.

[1] You have installed a libc5 distribution of OOB on your glibc based
    Linux distribution or vice versa.

A typical result of this when building Apache is:

Creating Configuration.apaci in src
ld: warning: libm.so.5, needed by
    /usr/local/easysoft/oob/client/lib/libesoobclient.so,
    may conflict with libm.so.6
/usr/i486-linux-libc5/lib/libm.so.5: warning: erfcl is not implemented
    and will always fail
/usr/i486-linux-libc5/lib/libm.so.5: warning: erfl is not implemented
    and will always fail
/usr/i486-linux-libc5/lib/libm.so.5: undefined reference to `__getfpucw'
make: *** [dummy] Error 1

This output resulted from building Apache on a glibc based system with
the libc5 version of OOB.

[2] The linker does not know how to find the OOB client shared object.

Make sure you followed the Apache_PHP document in the docs directory
of the OOB distribution carefully. Pay particular attention to

[a] --with-custom-odbc setting for PHP configuration.

[b] CUSTOM_ODBC_LIBS setting for PHP configuration. The example log in
    the Apache_PHP file shows one actual command line split over multiple
    lines in the text file. Make sure you enter this all as one line.

[c] LDFLAGS setting when configuring Apache. If you fail to set
    LDFLAGS as in the Apache_PHP document you will most likely get
    an error during configuration such as:

    /usr/bin/ld: cannot open -lesoobclient: No such file or directory
    collect2: ld returned 1 exit status
    make: *** [dummy] Error 1

[d] Check that the path to the libesoobclient.so shared object is in
    your /etc/ld.so.conf file and that ldconfig has been run to re-read
    this file.

5.4 Which is best, inetd or standalone startup for the OOB Server?
------------------------------------------------------------------

The standalone OOB Server is 10x faster at accepting connections than
the inetd started server. If you are making a lot of small connections
to a UNIX OOB Server then starting it standalone (without inetd) is
preferable.  The OOB HTTP server is only available when the OOB Server
is running standalone.

However, the inetd solution has one advantage which is that if the
server crashes for any reason future connections will still work
without you having to restart the server.

5.5 Can I use a multi-threaded application with OOB on Linux and if so how?
---------------------------------------------------------------------------

Yes but make sure you download a thread-safe version of OOB. The
thread-safe distributions of OOB are identified by "-mt" in the
distribution name.

Do not use this OOB distribution unless your application is known to
be threaded and linked with Linux Threads.

When building your application add the -pthread switch to gcc and do
NOT use -lpthreads. Make sure you use thread-safe/reentrant versions
of library functions (e.g. gethostbyname_r etc) and define _REENTRANT
by adding -D_REENTRANT to your compile lines.

If you are using GNU PTH instead of Linux Threads please contact us
for availability.

5.6 Why is inetd terminating the OOB Server service?
----------------------------------------------------

inetd counts the number of server instances created in a 60 second
interval. If your OOB Server is very busy accepting a lot of
connections in a short period of time, inetd may decide the OOB Server
is being flooded or looping and suspend the service for a while. A
typical message output by inetd looks like this:

/var/log/messages:Feb 16 14:35:41 machine inetd[52]: esoobserver/tcp
 failing (looping or being flooded), service terminated for 10 min

By default, most inetd servers count 40 instances in 60 seconds as too
many. If you need a higher threshold that this you need to edit your
inetd.conf file and amend the OOB Server line to add a maximum number
of server instances [see the inetd.conf(8) man page]. Usually, all
that is involved is placing a . and a number after the nowait.

e.g.

esoobserver stream tcp nowait.60 root /bin/sh /bin/sh
   /usr/local/easysoft/oob/server/server

Do not forget to tell inetd to reread its configuration files after
making changes to inetd.conf.


5.7 Why are second and subsequent connections to the OOB Server under inetd
---------------------------------------------------------------------------
    so slow?
    --------

We have some ODBC benchmark code which connects and disconnects as
quickly as it can to an OOB Server. On one particular Linux machine
the first connect took 0.3s and subsequent connects took 1.5s. It
appears some Linux distributions (notably RedHat 6.1) contain a
version of inetd that has this peculiar characteristic. We have not
been able to track down the bug report or specific change.

We downloaded netkit-base-0.17 and this cured the problem. xinet
(distributed with more recent RedHat distributions) does not appear to
have this problem.

5.8 Why do I get the error "libqt.so.3: symbol _res, version GLIBC_2.0
----------------------------------------------------------------------
    not defined"?
    -------------

The QT libraries that ship with the OOB are incompatible with the
Native POSIX Thread Library (NPTL) introduced in Red Hat 9. If you get
the following error when running ODBCConfig on Red Hat 9:

relocation error: /usr/local/easysoft/lib/libqt.so.3: symbol _res,
   version GLIBC_2.0 not defined in file libc.so.6 with link time reference

you need to ensure that the QT libraries use the previous LinuxThreads
implementation. Do this by setting the environmental variable
LD_ASSUME_KERNEL to 2.4.19. For example:

LD_ASSUME_KERNEL=2.4.19
export LD_ASSUME_KERNEL

To run ODBCConfig, you also need to ensure that the
<install_path>/easysoft/lib and <install_path>/easysoft/unixODBC/lib
directories are in the dynamic linker search path by setting the
LD_LIBRARY_PATH environment variable. Replace <install_path> with the
Easysoft installation path,by default /usr/local. For example:

LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/easysoft/lib:/usr/local/easysoft/unixODBC/lib
export LD_LIBRARY_PATH

6. Operating System Specific - Windows
--------------------------------------
6.1 What username/password do I need to specify for LogonUser
-------------------------------------------------------------
    and LogonAuth?
    --------------

For Windows 95 and 98 you need to specify a username and password
defined for that machine.

For NT it is slightly more complex as NT machines are usually part of
an NT domain. You may specify either a local username and password on
that NT server or a NT domain username/password. The OOB Server,
passes either NULL or the specified domain name to the NT function
LogonUser(). You can specify a domain in the LogonUser attribute like
this:

Domain/username

If "Domain/" is not specified, the OOB Server passes NULL to LogonUser()
which means the local account database is searched first and then
trusted domains.

If Domain is "." (e.g. ./username), then the search is restricted to
the local account database on the NT Server.

6.2 What do I do if I get an Access Violation or Fault popup window?
--------------------------------------------------------------------

If an access violation or other fault occurs when running a program in
Windows a popup dialogue appears. This may occur on the client side
when running you application connected to the OOB client or at the
server side.

In general:

[1] you should note down any information in this popup.
[2] write down exactly what you were doing before this occurred.
[3] if you have a Dr Watson log take a copy of the log (see later)
[4] send all of the above along with the version of the OOB you are
    running to support@easysoft.com.

If you are writing your own ODBC compliant application then your first
port of call should be to thoroughly investigate your code and satisfy
yourself that nothing is wrong with it. Any application can generate
an access violation in an ODBC driver by passing invalid pointers to
ODBC APIs.

Dr Watson log files are created by drwtsn32.exe. After installing
Windows your machine is set up to run drwtsn32.exe when a program
fails (note that installing other software e.g. Microsoft Developer
Studio can change the spawned debugger). This program writes
information about your operating system and the program that failed
into a log file. It shows the threads, where each of them were when
the program failed and which thread caused the problem. This file can
be an invaluable aid in determining the source of the problem. The Dr
Watson log file is DRWTSN32.LOG and is created in the your Windows
directory.

If you have installed the WIN32 SDK then the debugger is changed to
WINDBG.  You can change the debugger back to Dr Watson by editing the
following key in your registry:

HKEY_LOCAL_MACHINE\
SOFTWARE\
Microsoft\
Windows NT\
CurrentVersion\
AeDebug

This key contains string values "Auto" and "Debugger". If you want to
temporarily change the spawned debugger to Dr Watson to generate a log
file then write down the current version of the "Debugger" entry and
change it to:

DRWTSN32 -p %ld -e %ld -g

Once you have generated a log file you can reset the debugger entry.

These entries are also available in Windows 95/98 but they are in the
win.ini file instead of the registry. The section [aedebug] has
entries that correspond to the registry.

From OOB 1.0.0.3 (for Windows) the OOB Server traps exceptions and
reports them in the file LOGDIR\esoob.exception (where LOGDIR is a
server configurable parameter defaulting to c:\temp). Any exceptions
on NT will also be reported to the Event Log. If you have an
esoob.exception file, send that to us with a description of what you
were doing.

6.3 Does the OOB client support file DSNs?
------------------------------------------

Yes.

You can create File DSNs from the ODBC Administrator, just like user
or system DSNs. Simply click on File DSN, enter a name for the DSN and
then fill in all the OOB fields as usual.

6.4 Why does the install hang?
-----------------------------

On Windows NT we have seen (and had reported to us) the installation
hanging in two places. The course of action depends on where the hang
occurs.

[1] If the hang occurs whilst the Setup dialogue shows "Easysoft
    ODBC-ODBC Bridge is preparing the InstallShield(R) wizard which
    will guide you through the rest of the setup process. Please Wait"
    and the 100% progress bar is displayed:

    Be patient and wait (up to 5 minutes) and the installation will
    continue as normal. This appears to occur on other company's
    InstallShield installations too and so we do not think this is a
    problem specific to the OOB installation.

    Make sure you have closed all applications before installing.

[2] If the hang occurs after you have run through all the dialogue
    boxes and provided all the installation information requested:

    You are probably running a version of the OOB including and prior to
    version 1.0.0.3. These versions contained a bug in the InstallShield
    supplied service template that can cause it to loop forever waiting
    for the previously installed OOB Server Service to close down. The
    solution in this case is to either:

   [a] Get a more recent version of OOB which fixes this problem.

   [b] Abort the installation (use the Task Manager). Then go to
       control panel -> services and make sure the OOB Server Service
       is stopped (it probably will be). Then run the installation again
       and it should progress correctly.

6.5 Why do I get "Invalid authorization specification" and/or
-------------------------------------------------------------
    "authentication error number nnnn" when the LogonUser and LogonAuth
    -------------------------------------------------------------------
    are set to a valid username and password?
    -----------------------------------------

If you are sure the username and password are correct then you need to
call either SQLError or SQLGetDiagRec() or
SQLGetDiagField(SQL_DIAG_NATIVE).  The native error is actually the
error code returned by GetLastError (the WIN32 function) and it gives
an indication of why the OOB server failed to logon as your specified
user. In later versions of OOB, a second diagnostic "authentication
error number nnnn" is added (where nnnn is the error number) which
saves you looking at the native error code.

Error codes we have seen and their solutions are:

1385
Logon Failure: the user has not been granted the requested logon type at this
computer. Check the user has the Logon Locally permission.

If you have installed the OOB Server on your primary or secondary
domain controller in Windows 2003 Server then you should know that a
standard user added to the domain is by default added to the 'Domain
Users' group and they cannot login to a domain controller. The only
ways around this are:

o Add the user to the 'Administrators' or 'Domain Admins' group.
o move the OOB Server off a domain controller and on to another Windows
  machine.

1314
A required privilege is not held by the client. The OOB Server needs
the "Act as part of the operating system" access right to authenticate
and become the LogonUser.

1326
Logon Failure: unknown username or bad password. The username is not a
valid user or the password is invalid. If you have checked these are
valid and the user is in an NT domain try prefixing the username with
DOMAIN/ e.g. NTDOMAIN/Username.

1327
Error Account_Restriction: Indicates a referenced user name and
authentication information are valid, but some user account
restriction has prevented successful authentication (such as
time-of-day restrictions).

For Windows XP this can occur if you attempt to login to an OOB Server
using a username with an empty password. In XP, by default, users with
no passwords are only allowed to login at the console.

1328
Account logon time restriction violation. This account is has logons
restricted to certain times and the current time is outside the
allowable times.

1330
The specified account password has expired. Renew the password expiration.

1331
Logon failure: account currently disabled. Re-enable the account.

1355
The specified domain did not exist. You are using the Domain/Username
syntax in LogonUser and Domain does not exist.

1789
The trust relationship between workstation where the OOB Server is
running and the primary domain failed. Usually this means the
workstation is not in the domain.

1909
Account locked out. Unlock the account.

87
Parameter incorrect. You have specified an invalid username for the
LogonUser attribute e.g. a zero length one. Check the LogonUser
attribute is spelt correctly in your registry or ini file
e.g. LogonUser is incorrect and results in the OOB client not finding
a username and passing a zero length one.

1907
The user must change his password before he logs on the first time.
Check the logon settings for the user you are using or logon as that
user and set the password.

1792
An attempt was made to logon, but the network logon service was not
started.  Go to control panel, services and make sure the Net Logon
service is running.

6.6 Why do I get connection refused/reset under heavy loads
-----------------------------------------------------------
(Windows OOB server)?
---------------------

The main OOB Server thread listens on the specified port (defaults to
8888) for incoming connections from OOB clients. Once a connection is
accepted the main OOB server thread creates a new thread/process which
handles the ODBC connection. Whilst the main server thread is starting
up a new connection thread/process it is not accepting other
connections. The time required to start a new connection handler is
usually very short but to avoid newly incoming connections being
dropped the server attempts to set the listen backlog queue to 20. The
listen backlog queue allows the TCP/IP stack to queue the connection
until the server gets around to accepting the connection.

If the listen backlog queue fills the TCP/IP stack will reject the
connection and the OOB Server never sees it.

Unfortunately, in Windows 9X and NT Workstation the maximum listen
backlog is 5. Since the OOB Server is usually pretty quick at
accepting connections this low backlog value is not usually a
problem. However, it does mean that concerted attempts to make lots of
connections in a short period of time can fill the backlog queue. This
makes Windows NT Workstation and Win9X in particular a bad choice for
a high-load server.

The OOB Server could use SOMAXCONN in WinSock2 to set the listen
backlog queue to its maximum value (this has no affect on NT
workstation and Win9x). However, large backlogs make SYN flood attacks
much more effective since the queue is non-pageable system memory.

You may find the following article useful:
http://support.microsoft.com/support/kb/articles/q142/6/41.asp

The OOB client can help with connection refused problems due to the
socket backlog filling in Win9x and NT workstation by making multiple
connection attempts. See the question "How does the OOB client handle
refused connections?"

6.7 How can I check which version of MS MDAC I have?
----------------------------------------------------

MDAC - Microsoft Data Access Components.

MDAC contains the ODBC driver manager and various ODBC drivers

You can download the MDAC component checker from Microsoft and run it.
The MDAC component checker is an extremely useful diagnostics tool
which checks the ODBC components such as the driver manager and ODBC
drivers on your machine to see what you are using and if they are
correctly installed. You can get it from:

http://www.microsoft.com/data

6.8 What version of MS MDAC do I need?
--------------------------------------

You are best using a recent MDAC (2.1 or above but preferably at least
2.8).  Some drivers we have tested do not work with older MDACs and
OOB - e.g. Centura SQLBase and MDAC 1.5b. To find out which version of
MDAC you have installed see the question "How can I check which
version of MS MDAC I have?".

6.9 Where do I get WinSock 2 for Windows 95?
--------------------------------------------

OOB for Windows 95 requires WinSock 2. You can get the WinSock 2
update for Windows 95 from:

ftp://ftp.microsoft.com/bussys/winsock/winsock2/

6.10 Why does OOB install fail with
-----------------------------------
     "Setup is unable to locate the layout file"?
     --------------------------------------------

When installing the ODBC-ODBC Bridge on windows I get the following
error:

Setup is unable to locate the layout file
'C:\Temp\pft2D~tmp\Layout.bin' which is needed to complete the
installation. Error 112.

This error indicates that environment variables that InstallShield
needs to unpack an ODBC-ODBC Bridge distribution are set incorrectly
and InstallShield cannot find the directory it needs. To correct this
problem reset the Environment Variables that point to the two
temporary directories. To do this enter Control Panel and double click
the System icon.  When the System Properties pane has loaded up select
the Advanced tab and click into Environment Variables. Select the
Environment Variables Temp & Tmp from the System Variables list and
change them to point to C:\temp and C:\tmp and make sure these
directories exist. Once these have been edited click ok and this will
save your new values.

6.11 Why do I get "Initialization of the dynamic link library xxx failed"
-------------------------------------------------------------------------
     dialogues on my server desktop when running in MultiProcess mode?
     -----------------------------------------------------------------

This problem relates to running the OOB Server in MultiProcess mode on
Windows NT/2000. If you are running in Multi-Threaded mode (the
default) this FAQ item does not apply.

These popup windows seem to appear when an OOB client is connecting to
the server and they look similar to the following:

Initialization of the dynamic link library
c:\WINNT\system32\COMCTL32.dll failed. The process is
terminating abnormally.

although the actual DLL may be USER32.DLL, KERNEL32.DLL or perhaps
even a DLL supplied with OOB. The OOB client connected to the OOB
Server will hang until the OK button on the dialogue is pressed.

We have not seen this problem in Windows NT sp3 although now that we
understand it better it is still possible. We first encountered this
problem around about the time NT sp4 was installed.

Useful references on Microsoft's web site are:

http://support.microsoft.com/support/kb/articles/Q225/1/02.ASP
http://support.microsoft.com/support/kb/articles/Q142/6/76.ASP
http://support.microsoft.com/support/kb/articles/Q126/9/62.ASP

Please note that the first reference mentions calling CreateProcess
with DETACHED_PROCESS and CREATE_NO_WINDOW flags which OOB already
does.

It appears that around NT sp4 the Windows registry string in

HKEY_LOCAL_MACHINE\
System\
CurrentControlSet\
Control\
Session Manager\
SubSystems\

was amended. In sp3 it included SharedSection=1024,3072 and changed
to SharedSection=1024,3072,512. The references to Microsoft's web site
above appear to contradict each other. We have found that without the
3rd argument (512) the desktop heap size appears to default to 512K
(in post NT sp4 and above) and a much higher default was used in NT
sp3 and before. 512 is sufficient for around 60 - 100 OOB Server
processes depending on whatever else is running on the
desktop. Lowering it to 128 allows around 17 OOB Servers and
increasing it to 1024 allows around 220 OOB Servers. It would appear
from our experiments that the default heap size was much higher in NT
sp3. Note that you need to reboot after changing this value.

6.12 Why cannot I connect to an OOB Server running on a clustered windows
-------------------------------------------------------------------------
     server using virtual IP addressing?
     -----------------------------------

If you find that a telnet <server name> 8888 fails with
"Connecting To <server_name>...Could not open a connection to host on port
8888 : Connect failed" try a netstat -a command on the server running
the bridge server. You should see the following returned:

TCP    <server_name>:8888         <server_name>:0             LISTENING

This confirms the OOB Server is running and listening on port 8888.

If the server returns the above then there could be the likelihood
that you may be connecting to the wrong host name/IP Address. Try
running an ipconfig /all command and entering the IP address as
returned from this. We have seen this kind of behavior on clustered
windows servers using virtual IP addresses.

6.13 What can't I connect to my OOB Server since installing Windows XP
----------------------------------------------------------------------
     Service Pack 2?
     ---------------

Windows XP Service Pack 2 turns the Windows Firewall on by default
unless you have some other firewall it recognises in use. You should
read "Configuring Firewalls to enable the Easysoft Server Processes"
at the link below which explains how to make your server accessible
again.

http://www.easysoft.com/products/9999/documentation/firewall/firewall.html

6.14 How do I restart the OOB Server?
-------------------------------------

The OOB Server on Windows is a service. To start/stop/restart etc go
into your control panel and look for Services (it is under
Administrative tools on some versions of Windows). Start the service
manager, scroll down the list of service names until you find
"Easysoft ODBC-ODBC Bridge Server". Highlight the OOB Server service
then use the control buttons to start/stop/restart/pause etc (on newer
versions of Windows you can right click on a service to find the
actions).

7. Operating System Specific - Solaris
--------------------------------------

7.1 Why do I get undefined symbol for h_errno?
----------------------------------------------

Currently the OOB client for Solaris is not built against the Solaris
threads library. As a result, if you attempt to link a threaded
program with the libesoobclient shared object you will probably get an
undefined symbol for h_errno. When a program is built threaded,
h_errnop is defined instead of h_errno.

An example where you might see this is if you build unixODBC with
threads (the default configuration) and then try and use OOB with it.
The solution is to rebuild unixODBC without threads
(--enable-threads=no).

8. Operating System Specific - OpenBSD
--------------------------------------

8.1 Can I use the ODBC-ODBC Bridge for FreeBSD on OpenBSD?
----------------------------------------------------------

Although we have not tested this configuration according to the
OpenBSD web-site OpenBSD supports binary emulation "of most binaries
from SVR4 (Solaris), FreeBSD, Linux, BSDI, SunOS, and HPUX." To our
knowledge this has been successfully tested by a number of customers
with no reported problems.

9. Operating System Specific - FreeBSD
--------------------------------------
9.1 When linking Perl DBD::ODBC with the OOB on FreeBSD I get errors
--------------------------------------------------------------------
    regarding wchar.h what should I do?
    -----------------------------------

When linking the ODBC-ODBC bridge with Perl DBD::ODBC you may get the
following error:

/usr/local/easysoft/oob/client/include/sql.h:46,
                 from
/usr/local/easysoft/oob/client/include/sqlext.h:46,
                 from dbdodbc.h:9,
                 from ODBC.h:9,
                 from ODBC.xs:1:
/usr/local/easysoft/oob/client/include/sqltypes.h:14: wchar.h: No such
file or directory

To rectify this problem you need to comment out any references to
wchar.h in the following file:

/usr/local/easysoft/oob/client/include/sqlext.h

10. Operating System Specific - OpenVMS
---------------------------------------

10.1 What VMS float types are SQL_C_REAL, SQL_C_DOUBLE and SQL_C_FLOAT?
-----------------------------------------------------------------------

The OOB for OpenVMS is built with the DECC qualifier /FLOAT=G_FLOAT.

An SQL_C_FLOAT should be a F_FLOAT.
An SQL_C_DOUBLE should be a G_FLOAT.
An SQL_C_REAL should be a F_FLOAT.

e.g. if you call SQLGetData asking for a SQL_C_FLOAT you should
get a VMS F_FLOAT back.

The OOB converts floats/doubles on the remote machine to local machine
format.

11. Programmming
----------------

11.1 Can I fork child processes after SQLDriverConnect and use the connection
-----------------------------------------------------------------------------
    handle in each one?
    -------------------

No.

The OOB client connects to the OOB server during the call to
SQLDriverConnect.  After SQLDriverConnect returns, a socket is open
between the client and server. If you then fork children they inherit
the dbc and open socket.  If the children use the dbc in further calls
to SQL functions this will cause multiple processes to be sending data
down the same socket.  This just will not work. You need to make the
call to SQLDriverConnect in each child.

11.2 Can I use a multi-threaded application with the OOB client?
----------------------------------------------------------------

In Windows yes.

On most UNIX operating systems we support, a thread-safe version of
the OOB client is not yet available. However, for Linux/glibc,
Solaris/Sparc/Intel, Tru64 and FreeBSD a MT-safe OOB distribution is
available. These distributions have "-mt" in the
distribution/filename.

There are a few issues specific to OOB and unixODBC regarding threads:

o If you are building unixODBC yourself then make sure you put
  --enable-threads=yes on the configure line if you want a thread-safe
  driver manager.

o Please read DriverManager/__handles.c in the unixODBC source code as
  it describes how to protect ODBC drivers running under unixODBC. The
  2.2.4 version of this text is reproduced here:

   /*
    * If compiled with thread support the DM allows four different
    * thread strategies
    *
    * Level 0 - Only the DM internal structures are protected
    * the driver is assumed to take care of it's self
    *
    * Level 1 - The driver is protected down to the statement level
    * each statement will be protected, and the same for the connect
    * level for connect functions, note that descriptors are considered
    * equal to statements when it comes to thread protection.
    *
    * Level 2 - The driver is protected at the connection level. only
    * one thread can be in a particular driver at one time
    *
    * Level 3 - The driver is protected at the env level, only one thing
    * at a time.
    *
    * By default the driver open connections with a lock level of 3,
    * this can be changed by adding the line
    *
    * Threading = N
    *
    * to the driver entry in odbcinst.ini, where N is the locking level
    * (0-3)
    */

  For mt distributions of OOB you can set Threading = 0 as the OOB
  client is thread-safe.

o One of the ways the OOB client maintains thread-safety is by holding
  a mutex on the socket created for each ODBC connection. The protocol
  used on the socket is therefore not asynchronous and multiple
  threads cannot use the socket created for an ODBC connection at the
  same time. i.e. an ODBC call from the application results in one or
  more Remote Procedure Calls (RPCs) over the socket; each one is a
  send with the request then wait for response. The socket layer is
  thread-safe because the OOB does not allow multiple threads to use
  the socket at the same time.

    e.g. thread1 calls SQLAllocHandle and a RPC call is made. The kernel
         switches to thread2 which also calls SQLAllocHandle which also results
         in an RPC call. OOB will block thread2 until thread1's SQLAllocHandle
         RPC has completed.

    You can get around this by making each thread open a new ODBC connection
    which results in multiple sockets.

o Be careful to avoid database locks when using multiple threads on the
  same ODBC connection. In fact, this is one of the biggest reasons why
  not to use multiple threads on the same database handle. Because of
  the way locking is implemented in some database engines and in the OOB
  client you can deadlock if you use multiple threads per connection.
  Some database engines or ODBC drivers spin-wait on locks.

  e.g. Suppose thread1 does something which locks table S. thread2 now
  attempts an operation on table S but it is locked. The ODBC driver
  will spin-wait thread2 so thread2 is stuck in the ODBC driver and
  hence as far as the OOB client is concerned it has not returned from
  the RPC and the socket is blocked for thread1. Now when thread1
  attempts to do something the OOB client will block thread1 because
  thread2 has not returned from the RPC.

11.3 I am trying to compile/link my C code and it fails with undefined
----------------------------------------------------------------------
     symbol errors?
     --------------

If the undefined symbols are all SQLxxx then the likelihood is you
have forgotten to add a -lodbc to the link line. This tells the linker
to use libodbc.<ext>.

11.4 Where can I get help with developing C applications using ODBC?
--------------------------------------------------------------------

Easysoft recommend that you refer to the ODBC Programmers Reference
Guide and other documentation provided on Microsoft's
msdn.microsoft.com web site (see question "Where do I get information
about the ODBC API?")

A full OOB installation comes with some example ODBC applications
written in C, PHP and Perl - see the examples directory under your OOB
installation.
