Home How To Online Documentation Support Download Order
 

 

 








SQLAPI++ Q&A

1. When linking a programm that uses SQLAPI++ I got an error: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall ...". What is missing?

2. How can I get status return code from stored procedure on Sybase? 

3. I work with Sybase ASE. I have a stored procedure that has an input-output parameter. But when I call SAParam::ParamDirType method for this parameter it always returns SA_ParamInput, and when I try to get the parameter's value after the command execution I receive nothing. What is wrong? 

4. Why is the "sybinit.err" file sometimes being appended to at a successful SQLAPI++ connection to ASE/ASA using Open Client? Console application also outputs some warning(s) about context allocation failure. 

5. I execute a "Select..." statement and then call SACommand::RowsAffected() method to determine the number of rows to be returned by the command, but the result is always incorrect (-1 or 0 most of the times). What is wrong?

6. When linking a programm that uses SQLAPI++ under Microsoft Visual Studio 2005 I got an error: error LNK2001: unresolved external symbol "public: __thiscall SAString::SAString(wchar_t const *)".  I do include sqlapiu.lib in the project. What's wrong?

7. When linking a programm with static SQLAPI++ library I got an error: sqlapis.lib(samisc.obj) : error LNK2019: unresolved external symbol _GetFileVersionInfoA@16 referenced in function "void * __cdecl SAGetVersionInfo(char const *)" (?SAGetVersionInfo@@YAPAXPBD@Z)

8. How can I connect to Microsoft SQL Server from Linux using SQLAPI++?

9. Is there a way to get the number of rows returned by some result set?

10. I got the .diff files, but how can I apply them to my existing source code? Could you please help me?

11. When compiling step1.cpp on Linux got an error: libsqlapi.so: undefined reference to `dlerror', 'dlopen', 'dlsym'... Could you help?

12. Could I have multiple SACommand in one SAConnection? I tested under MySQL database, keep SACommands being opened, and always get error "Commands out of sync; you can't run this command now".


1. When linking a programm that uses SQLAPI++ I got an error: unresolved external symbol "__declspec(dllimport) public: virtual __thiscall ...". What is missing?

Probably you forgot to include sqlapi.lib* (or other SQLAPI++ library, depends on the compiler and/or static/dynamic version) into the project. To link with SQLAPI++ Library you have to include sqlapi.lib into you project (as well as *.cpp).
For example, in Visual C++ you have to do the following:

  1. In workspace tree select the project that you link with SQLAPI++.
  2. Use "Add Files to Project..." command on the right click menu and add sqlapi.lib to you project.
  3. Press F7 button to compile and link you project.

*  sqlapi.lib should be used when linking with dynamic version of SQLAPI++ using Microsoft Visual C++.
To link with a static version using MSVC++ use sqlapis.lib.
To link with a dynamic version using Borland C++ compiler use sqlapib.lib.
To link with a static version using Borland C++ compiler use sqlapibs.lib.
To link with a dynamic version using Borland C++ Builder compiler use sqlapibb.lib.
To link with a static version using Borland C++ Builder compiler use sqlapibbs.lib.
To link with a debug version use appropriate lib file that ends with 'd'.

2. How can I get status return code from stored procedure on Sybase (or SQL Server)?

SQLAPI++ Library automatically creates SAParam object to represent procedure status return code. After a command execution you can check it value. This SAParam object's name is "RETURN_VALUE", object's type is SA_dtLong , object's direction type is SA_ParamReturn.

3. I work with Sybase ASE. I have a stored procedure that has an input-output parameter. But when I call SAParam::ParamDirType method for this parameter it always returns SA_ParamInput, and when I try to get the parameter's value after the command execution I receive nothing. What is wrong?

Sybase ASE server does not provide information about parameter's direction type, that's why SQLAPI++ Library defines all parameters (except status result code) as input (SA_ParamInput). If you have input-output parameters in the procedure you have to call SAParam::setParamDirType method for these parameters before command execution and set parameter's direction type explicitly (SA_ParamInputOutput).
You shouldn't call this method for procedure status result code because it is detected correctly (as SA_ParamReturn) by the Library.

There is no need to call this method for Sybase ASA because all parameters are detected correctly automatically (including the direction type).

4. Why is the "sybinit.err" file sometimes being appended to at a successful SQLAPI++ connection to ASE/ASA using Open Client? Console application also outputs some warning(s) about context allocation failure.

SQLAPI++ has to set the version of Client-Library behavior when it connects to Sybase. By default SQLAPI++ tries to set 12.5 behavior; if it fails, SQLAPI++ tries to set 11.0 behavior and so on from the highest version to the lowest one until it succeeds. Finally the connection is successful, but every time when it fails Sybase server generates the appropriate error message and adds the same error message to the "sybinit.err" file.

The solution is to set the CS_VERSION option to "Detect" using SAConnection::setOption method. In that case SQLAPI++ automatically detects the maximum available version of behavior via the version of Client-Library.

5. I execute a "Select..." statement and then call SACommand::RowsAffected() method to determine the number of rows to be returned by the command, but the result is always incorrect (-1 or 0 most of the times). What is wrong?

SACommand::RowsAffected() is only applicable to INSERT/UPDATE/DELETE queries. It is database APIs limitation, not the one of SQLAPI++. The only way to get to
know result set size in advance is to execute "Select count(*)..." command.

6. When linking a programm that uses SQLAPI++ under Microsoft Visual Studio 2005 I got an error: error LNK2001: unresolved external symbol "public: __thiscall SAString::SAString(wchar_t const *)".  I do include sqlapiu.lib in the project. What's wrong?

We provide SQLAPI++ binaries those are linked with Microsoft Visual Studio 6. Visual C++  2005 compiler turns the '/Zc:wchar_t' option on by default. This is incompatible with Visual C++ 6. To avoid this problem you can turn off '/Zc:wchar_t option' (use '/Zc:wchar_t-'  or look at the project options dialog 'Treat wchar_t as Build-in Type' item). But the best solution - rebuilding SQLAPI++ with Visual C++ 2005 compiler.

7. When linking a programm with static SQLAPI++ library I got an error: sqlapis.lib(samisc.obj) : error LNK2019: unresolved external symbol _GetFileVersionInfoA@16 referenced in function "void * __cdecl SAGetVersionInfo(char const *)" (?SAGetVersionInfo@@YAPAXPBD@Z)

Since SQLAPI++ 3.7.25 you also need the libraries: user32.lib, version.lib, oleaut32.lib and ole32.lib

8. How can I connect to Microsoft SQL Server from Linux using SQLAPI++?

There is the SQL Server ODBC/SQLNCLI Driver for Linux that provides native connectivity from Linux to Microsoft SQL Server. SQLAPI++ support this client software but Microsoft releases this driver only for x86-64 Linux platforms. When you'd like to run the software on 32-bit Linux or any ther Unix like system you must use ODBC connection. You need ODBC driver manger  (most known are  iODBC or unixODBC) and MSSQL ODBC driver (FreeTDS ODBC driver or commercial EasySOFT one.)
You must install and configure ODBC software. Often Linux distrubution mantainers split the software into several packages, for example Debian Lenny includes the next iODBC and FreeTDS packages:

iodbc - GTK+ config frontend for the iODBC Driver Manager
libiodbc2-dev - iODBC Driver Manager (development files)
libiodbc2 - iODBC Driver Manager
freetds-common - configuration files for FreeTDS SQL client libraries
freetds-dev - MS SQL and Sybase client library (static libs and headers)
libct4 - libraries for connecting to MS SQL and Sybase SQL servers
libsybdb5 - libraries for connecting to MS SQL and Sybase SQL servers
tdsodbc - ODBC driver for connecting to MS SQL and Sybase SQL servers
It's enough to have installed only iodbc, libiodbc2, freetds-common and tdsodbc packages. For the first time it's better to configure and test DSN (any driver manager includes console tool for command line SQL):
bedlam:~# cat ~/.odbc.ini
[ODBC Data Sources]
MSSQL = FreeTDS driver

[MSSQL]
Driver = /usr/lib/odbc/libtdsodbc.so
Server = BEDLAM-M\SQLEXP2008EN
Database = pubs
TDS_Version = 7.0

bedlam:~# cat ~/.odbcinst.ini
[ODBC Drivers]
FreeTDS driver = Installed

[FreeTDS driver]
Driver = /usr/lib/odbc/libtdsodbc.so
Setup = /usr/lib/odbc/libtdsS.so
iodbc package provides iodbctest tool I run with parameters to check the ODBC DSN status:
bedlam-home:~# iodbctest "DSN=MSSQL;UID=sa;PWD=xxx"
iODBC Demonstration program
This program shows an interactive SQL processor
Driver Manager: 03.52.0607.1008
Driver: 0.82 (libtdsodbc.so)

SQL>
Then I can use SQLAPI++:
con.Connect("MSSQL", "sa", "xxx", SA_ODBC_Client);
or without DSN configured:
conn.Connect("DRIVER={FreeTDS driver};SERVER=BEDLAM-M\\SQLEXP2008EN;DATABASE=pubs;TDS_Version=7.0", "sa", "xxx", SA_ODBC_Client);

9. Is there a way to get the number of rows returned by some result set?

Generally it's impossible. Because any DBMS can counts the result set rows only when all rows already cached at the client side. For such cases SACommand::RowsAffected() method returns the result set row count.

10. I got the .diff file, but how can I apply them to my existing source code?

You need a GNU patch tool. Version for win32 can be downloaded from SouceForge. Then run it from the console like:

C:\SQLAPI\src>patch.exe < myClient.cpp.diff
patching file myClient.cpp

C:\SQLAPI\src>

11. When compiling step1.cpp on Linux got an error: libsqlapi.so: undefined reference to `dlerror', 'dlopen', 'dlsym'... Could you help?

SQLAPI++ uses libdl library API to load DBMS API. So you should include this library when you linking your binary file with SQLAPI, like:

g++ -I../inclide -L../lib step1.cpp -o step1.out -lsqlapi -ldl

or with static SQLAPI without libpath:

g++ -I../inclide step1.cpp -o step1.out ../lib/libsqlapi.a -lsqlapi -ldl

12. Could I have multiple SACommand in one SAConnection? I tested under MySQL database, keep SACommands being opened, and always get error "Commands out of sync; you can't run this command now".

Default MySQL API doesn't allow to have several opened result set per connection. This is exactly what mysql_use_result does. The connection is blocked until you don't fetch all result set rows. When you'd like to run another command when there is not fetched result set at the same connection you must use another solution. The simplest - using MySQL 'store' result set:

SACommand cmd(&con, "select ...");
cmd.setOption("HandleResult") = "store";
cmd.Execute();
...

Then SQLAPI uses mysql_store_result and all rows cached at he client side after query is executed and you can fetch the result and execute another command at the same connection. The not good thing - this solution uses local MySQL client data cache. So MySQL guys added another feature - statement API. statement API allows to execute command but the result set stored at the client side. SQLAPI++ can use this feature with 'SELECT' commands. The limitation - the single, forward-only result set only:

SACommand cmd(&con, "select ...");
cmd.setOption("UseStatement") = "TRUE";
cmd.Execute();
...