Oracle C++ OCI Database Example

Aim
The aim of this C++ tutorial is to create a simple client that uses Oracle C++ OCI (OCCI Oracle C++ Call Interface) to connect to an Oracle database. We will be using the windows command line C++ compiler cl.exe that comes with Visual Studio C++ for this example. This demonstrates connectiong to the Oracle database and manipulating data. Leave any questions or problems as comments and I will endeavour to answer them.

If you would like to see a database pool implemented for Oracle OCCI the please visit Oracle C++ OCI Database Connection Pool.

Assumptions
This article assumes that you have an Oracle database installed and running and you have downloaded and installed/unzipped the Oracle Client which contains the header files and libs required. For purposes of this example the the project directory is OracleOCCIExample. Also you have VC++ installed and configured. See Problems and Solutions Installing VC++ Express Edition, to install and run vcvars32.bat.

Versions used in this example
Sofware/ComponentImage
Windows XP SP2N/A
Oracle Client10201_client_win32.zip
Visual Studio Express Editions 2008 VC++N/A
Links to these files can be found here

Oracle client is installed (expanded) in the "D:\oracle" directory for this example. Please remember to substitute your own directories for these.

NOTE: OCCI uses tnsnames.ora to connect to the database. So make sure you have this file configured with the database details you wish to connect to.


Write and compile the Client
  1. Write the client and save it as oracleexample.cpp in your working directory.
     1. #include <iostream>
     2. #include <occi.h>
     3. 
     4. using namespace std;
     5. 
     6. int main(){
     7. 
     8.     oracle::occi::Environment* environment;
     9.     oracle::occi::Connection *con;
    10.     oracle::occi::Statement* stmt;
    11.     oracle::occi::ResultSet* res;
    12. 
    13.     try{
    14.     
    15.         environment = oracle::occi::Environment::createEnvironment(oracle::occi::Environment::DEFAULT);
    16.         con = environment->createConnection("gldbuser", "gldbuser", "MYDATABSE");
    17. 
    18.         stmt = con->createStatement("select * from example");
    19.         res = stmt->executeQuery();
    20.         
    21.         while (res->next())
    22.             std::cout<<res->getInt(1)<<"  "<<res->getString(2)<<std::endl;
    23.         
    24.         stmt->closeResultSet(res);
    25.         con->terminateStatement(stmt);
    26.         environment->terminateConnection(con);
    27. 
    28.     }catch(oracle::occi::SQLException &e){
    29.         std::cout<<e.what();
    30.     }
    31. 
    32.  return 0;
    33. }
    Hide line numbers

  2. Open a prompt to the working directory and compile the code using the windows cl.exe compiler. Make sure to point '-I' (capital i) option to the include files and to include mysqlcppconn.lib

    ..workspace\OracleOCCIExample>cl -o oracletest.exe oracleexample.cpp -I D:\oracle\product\10.2.0\client_1\oci\include D:\oracle\product\10.2.0\client_1\oci\lib\msvc\oraocci10.lib
    Substitue your local directories.

  3. This should now create the ocalceexample.exe file. However if you run it now you might get some errors saying that some DLLs are missing.

  4. Add these paths to your existing path so that the executable can find the required libraries. Again, don't forget to replace the directories with the ones on your local machine. Basically you need to give the 'bin' diretory of your MySQL database installation and the 'lib' directory in your MySQL Connector C++ directory.


    ..\worksapce\OracleOCCIExample>set path=%path%;D:\oracle\product\10.2.0\client_1\oci\lib\msvc\vc7

    ..\worksapce\OracleOCCIExample>set path=%path%;D:\oracle\product\10.2.0\client_1\BIN

  5. Now run the oracleexample.exe and you should see the result. The most likely errors are errors stemming from problems with the tnsnames.ora and maybe DLL entry points when you run the program. To fix the DLL entry points you can set your classpath only to the paths specified above, to make sure you are not picking up any other dll.

Perl Socket and File Example

The aim of this tutorial is to show how to read and write to a socket in Perl. We will open a socket to a website, write the request headers, read the response and write the response to the console. You do not need any prior HTTP 1.x knowledge.

First lets have a look at the example. It's really self explanatory.
 1.     use IO::Socket;
 2. 
 3.     my $sock = new IO::Socket::INET (PeerAddr => 'localhost',
 4.                                         PeerPort => 8080, 
 5.                                         Proto => 'tcp');
 6.     die "could not create socket: $!\n" unless $sock;                                        
 7.     
 8.     printf $sock ("GET / HTTP/1.0\n");
 9.     printf $sock ("Host: localhost\n");
10.     printf $sock ("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
11.     printf $sock ("User-Agent: Mozilla/5\n");
12.     printf $sock ("Connection: keepalive\n");
13.     printf $sock ("\n\n");
14.     
15.     while (<$sock>) {
16.         if($_=~ m/validate_response/i) {
17.              last;
18.         }
19.          else{
20.              print $_;
21.         }
22.     }
Hide line numbers


Line 3 We open the socket to localhost on port 8080. This is where my server tomcat ususally runs. But you can change this to anything

Lines 8-13 Here we write out the reust HEADER to the webserver. Just remember if you change your host from 'localhost' to something else, you need to change line 9 to reflect that too.

Lines 15-22 Read the response from the webserver and write it to the screen.

Nmake Makefile Tutorial and Example

Aim
The aim of this Nmake C++ tutorial is to give a quick introduction to nmake. We will look at the basics of an nmake makefile and go through the options of compiling and linking. Microsoft's C++ (Visual Studio) nmake is very similar to gnu's make with a few minor differences. Nmake has options very similar to gnu make and we will use some of them in this example. Leave any questions or problems as comments and I will endeavour to answer them.

Assumptions
This article assumes that you have a compatible version of Visual C++ installed. For this example we used Visual C++ 2008 Express Edition. However, there should not be any significant issues.

As an example we will use a makefile that is used to compile one of the examples in this website - the common database pool template.


When you run nmake it looks for a file called makefile in the current directory. You can specify a file using the nmake -f myfile option.

While it may look like cl.exe is doing all the work, cl.exe does the compiling and link.exe does the linking. For all the compile options you can use cl /? and for all the linker options you can use link /?
You can run nmake without a target or you can specify a target such as nmane clean. Without a target nmake will look for the first available target in the makefile and build it.

 1. MYSQL_HOME=D:\downloads\mysql-connector-c++-noinstall-1.0.5-win32
 2. MYSQL_INCS=$(MYSQL_HOME)\include
 3. MYSQL_LIBS=$(MYSQL_HOME)\lib
 4. 
 5. mysqlbuild: mysqlpool.obj examplemysql.obj crosshelper.obj
 6.   cl /o hello.exe mysqlpool.obj examplemysql.obj crosshelper.obj /link /LIBPATH:$(MYSQL_LIBS) mysqlcppconn.lib
 7. 
 8. 
 9. examplemysql.obj: ExampleMySQL.cpp
10.     cl /c ExampleMySQL.cpp /D WINDOWSXX -I $(MYSQL_INCS)
11. 
12. mysqlpool.obj: ..\mysql\MySQLPool.cpp 
13.     cl /c  ..\mysql\MySQLPool.cpp /D WINDOWSXX  -I $(MYSQL_INCS)
14. 
15. crosshelper.obj: ..\CrossHelper.cpp
16.     cl /c ..\CrossHelper.cpp /D WINDOWSXX 
17. 
18. oraclebuild:
19.     echo "oracle build goes here"
20. 
21. all:oraclebuild mysqlbuild
22. 
23. clean:
24.   del *.exe *.obj
Hide line numbers


lines 1,2 and 3
Defines variables that will be used in the compiling and the linking. Similar to environment variables.

line 5
Defines a target called mysqlbuild that depends on other targets mysqlpool.obj, examplemysql.obj and crosshelper.obj. Before you goto line 6 to do the build nmake has to make sure that the dependencies are built.

line 12,13
Here it finds the target mysqlpool.obj required at line 5. It depends on the CPP source file MySQLPool.cpp so now we go to the next line to compile the file. This is a compile only /c option. As you can see we are using the /D WINDOWSXX to define the WINDOWSXX macro and -I $(MYSQL_INCS) which is specifying the directory to search for include files.

line 9,10
Build examplemysql.obj target required at line 5.

line 15,16
Build corsshelper.obj target required at line 5.

line 6
Once all the dependencies are built come back to line 6 and build the target. Here we are using /link to give the linker options which in this case is the LIBPATH to the mysqlcppconn.lib

You can try nmake oraclebuild which will just display a message, and nmake all will try to build both the oraclebuild and mysqlbuild targets.

Running nmake clean will delete all the *.obj and *.exe files so you can build them again.

Back to the tutorial trail | Home

Connecting To SQL Server Using C++ ODBC Example

Aim
The aim of this Windows C++ tutorial is to connect to an SQL Server database using native C++ and perform a simple query. We will use a connection string with a DRIVER and not a DSN . This is a fairly simple C++ example and we will use the Windows command line compiler cl.exe. While it is simple, it demonstrates what is required for connecting and retrieving data using C++ and SQL DB, with some error handling too. It is upto the user to furthere explore these functions. Please have a look at SQL Server ODBC C++ Connection Pool for an ODBC connection pool in C++. Leave any questions or problems as comments and I will endeavour to answer them.

Assumptions
This article assumes that you have Microsoft SQL Server 2008 Express edition installed and configured. Please see Installing and Configuring SQL Server 2008 for more details. Also note that SQL Server does not have port 1433 enabled by default. Please see the afore mentioned link on how to do this.


Versions used in this example
Sofware/ComponentImage
Windows XP SP2N/A
VC++ 2008 express EditionN/A
SQL Server 2008 Express EditionN/A
Links to these files can be found here


Write and Compile the Example
  1. Write the client code and save it as MicrosoftSQLExample.cpp
     1. #include <iostream>
     2. #include <windows.h>
     3. #include <sqltypes.h>
     4. #include <sql.h>
     5. #include <sqlext.h>
     6. 
     7. using namespace std;
     8. 
     9. void show_error(unsigned int handletype, const SQLHANDLE& handle){
    10.     SQLCHAR sqlstate[1024];
    11.     SQLCHAR message[1024];
    12.     if(SQL_SUCCESS == SQLGetDiagRec(handletype, handle, 1, sqlstate, NULL, message, 1024, NULL))
    13.         cout<<"Message: "<<message<<"\nSQLSTATE: "<<sqlstate<<endl;
    14. }
    15. 
    16. int main(){
    17. 
    18.     SQLHANDLE sqlenvhandle;    
    19.     SQLHANDLE sqlconnectionhandle;
    20.     SQLHANDLE sqlstatementhandle;
    21.     SQLRETURN retcode;
    22. 
    23.     if(SQL_SUCCESS!=SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sqlenvhandle))
    24.         goto FINISHED;
    25. 
    26.     if(SQL_SUCCESS!=SQLSetEnvAttr(sqlenvhandle,SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0)) 
    27.         goto FINISHED;
    28.     
    29.     if(SQL_SUCCESS!=SQLAllocHandle(SQL_HANDLE_DBC, sqlenvhandle, &sqlconnectionhandle))
    30.         goto FINISHED;
    31. 
    32.     SQLCHAR retconstring[1024];
    33.     switch(SQLDriverConnect (sqlconnectionhandle, 
    34.                 NULL, 
    35.                 (SQLCHAR*)"DRIVER={SQL Server};SERVER=localhost, 1433;DATABASE=MyDatabase;UID=sa;PWD=Admin-123;", 
    36.                 SQL_NTS, 
    37.                 retconstring, 
    38.                 1024, 
    39.                 NULL,
    40.                 SQL_DRIVER_NOPROMPT)){
    41.         case SQL_SUCCESS_WITH_INFO:
    42.             show_error(SQL_HANDLE_DBC, sqlconnectionhandle);
    43.             break;
    44.         case SQL_INVALID_HANDLE:
    45.         case SQL_ERROR:
    46.             show_error(SQL_HANDLE_DBC, sqlconnectionhandle);
    47.             goto FINISHED;
    48.         default:
    49.             break;
    50.     }
    51.     
    52.     if(SQL_SUCCESS!=SQLAllocHandle(SQL_HANDLE_STMT, sqlconnectionhandle, &sqlstatementhandle))
    53.         goto FINISHED;
    54. 
    55.     if(SQL_SUCCESS!=SQLExecDirect(sqlstatementhandle, (SQLCHAR*)"select * from testtable", SQL_NTS)){
    56.         show_error(SQL_HANDLE_STMT, sqlstatementhandle);
    57.         goto FINISHED;
    58.     }
    59.     else{
    60.         char name[64];
    61.         char address[64];
    62.         int id;
    63.         while(SQLFetch(sqlstatementhandle)==SQL_SUCCESS){
    64.             SQLGetData(sqlstatementhandle, 1, SQL_C_ULONG, &id, 0, NULL);
    65.             SQLGetData(sqlstatementhandle, 2, SQL_C_CHAR, name, 64, NULL);
    66.             SQLGetData(sqlstatementhandle, 3, SQL_C_CHAR, address, 64, NULL);
    67.             cout<<id<<" "<<name<<" "<<address<<endl;
    68.         }
    69.     }
    70. 
    71. FINISHED:
    72.     SQLFreeHandle(SQL_HANDLE_STMT, sqlstatementhandle );
    73.     SQLDisconnect(sqlconnectionhandle);
    74.     SQLFreeHandle(SQL_HANDLE_DBC, sqlconnectionhandle);
    75.     SQLFreeHandle(SQL_HANDLE_ENV, sqlenvhandle);
    76.     
    77. }
    Hide line numbers

  2. Now open a promt to where you saved the file and compile it. Just a reminder to make sure you have run vcvars32 beforehand or you will have all kinds of issues.

    MicrosoftSQLExample>cl MicrosoftSQLExample.cpp odbc32.lib

Microsoft SQL Server Connection String

Got the code but can't get the SQL Server connection string? Fear not, here is the Driver string with host, port number, database, username and password.

DRIVER={SQL Server};SERVER=localhost, 1433;DATABASE=MyDatabase;UID=sa;PWD=Admin-123;


gemette

Installing and Configuring SQL Server 2008

Download and Install
Make sure you download the Runtime with Management Tools from the Microsoft Express Edition Site.  This contains all the database engine, database management tools and Management Studio Express. You will need about 1 GB for the install so make sure you have plenty of space.

Configuring port 1433
By default TCP is not enabled on SQL Server. Managment Studio Express talks to the database via memory sharing. To enable listening on port 1433 goto the  "Programs" and select Microsoft SQL Server 2008 -> Configuration Tools -> SQL Server Configuration Manager. Now select SQL Server Configuration -> Protocols for SQLExpress and click on TCP/IP. Now in the Protocol tab set enabled to yes and and in the IP Adresses tab scroll down to IPAll and set the Port to 1433. Now restart the SQL Server (SQLEXPRESS) under SQL Server Services.

Finally open a prompt and telnet to the port. It should connect!

Open JMS Example With Remote Client

Aim
The aim of this tutorial is to configure a JMS queue using Open JMS and connect to it from a remote Client via JNDI. We will use destinations/queues and topics in the one example. Leave any questions or problems as comments and I will endeavour to answer them. To learn how to do this using a glassfish JNDI topic have a look at JMS Example using Glassfish and a Remote Client .

Assumptions
This article assumes that you have Open JMS installed/unzipped and ready to go.

Versions used in this example
Sofware/ComponentImage
Windows XP SP2N/A
Open JMSopenjms-0.7.7-beta-1.zip
JDK 1.5.0N/A
Links to these files can be found here

For the purposes of this tutorial Open JMS has been exanded in the D:\downloads\openjms-0.7.7-beta-1 directory. Make sure to replace this with your local directory. The project directory is OpenJMSExample and we will only have two files. One to publish/produce and one to listen/consume.

OpenJMSExample
_|_OpenJMSPublisher.java
_|_OpenJMSListener.java
_|_jndi.properties

Startup the OpenJMS Server
  1. Open a prompt to the Open JMS bin directory and run admin.bat. You have to set the JAVA_HOME to point to your jdk beforehand.
  2. `
  3. Once the little admin GUI window pops up, select Actions -> Start Open JMS. Then select Actions -> Online. Now the server is ready and you can see the destinations and topics. We will be using the default topic1 and queue1 that is already configured. You can change this in the openjms.xml file in the config directory.

Create the properties file
  1. Create the jndi.properties file in your working directory.
     1. java.naming.provider.url=tcp://localhost:3035
     2. java.naming.factory.initial=org.exolab.jms.jndi.InitialContextFactory
     3. java.naming.security.principal=admin
     4. java.naming.security.credentials=openjms
    Hide line numbers
    You can choose not to use a file and put the properties such as Context.PROVIDER_URL directly. Please have a look at JMS Example using Glassfish and a Remote Client on how to do this.

Write and compile the publisher and listener
  1. Write the listener/consumer and save it as OpenJMSListener.java in your working directory.
     1. import java.io.*;
     2. import java.util.*;
     3. 
     4. import javax.jms.*;
     5. import javax.naming.*;
     6. 
     7. public class OpenJMSListener implements MessageListener{
     8.     
     9.     public static void main(String args[]){
    10.         new OpenJMSListener().Go();
    11.     }
    12.     
    13.     public void Go(){
    14.         try{
    15.             Properties props = new Properties();
    16.             props.load(getClass().getClassLoader().getResourceAsStream("jndi.properties"));
    17. 
    18.             Context context = new InitialContext(props);
    19.             TopicConnectionFactory tfactory = (TopicConnectionFactory) context.lookup("ConnectionFactory");
    20.         
    21.             TopicConnection tconnection = tfactory.createTopicConnection();
    22.             TopicSession tsession = tconnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
    23.       
    24.             //listen to topic  
    25.             TopicSubscriber subscriber = tsession.createSubscriber((Topic)context.lookup("topic1"));
    26.             
    27.             //listen to queue/destination
    28.             MessageConsumer subscriber2 = tsession.createConsumer((Destination)context.lookup("queue1"));
    29.         
    30.             subscriber.setMessageListener(this);
    31.             subscriber2.setMessageListener(this);
    32.             
    33.             tconnection.start();
    34.         
    35.             (new BufferedReader(new InputStreamReader(System.in))).readLine();
    36.         
    37.             context.close();
    38.             tconnection.close();
    39.         }catch(Exception e){
    40.             e.printStackTrace();
    41.         }
    42.         
    43.     }
    44.     public void onMessage(Message message){
    45.         if(message instanceof TextMessage){
    46.             try{
    47.                 System.out.println( ((TextMessage)message).getText());
    48.             }catch(Exception e){
    49.             }
    50.         }
    51.     }
    52. }
    Hide line numbers
  2. `
  3. Compile the code and install it using

    ..workspace\openJMSExample>javac -extdirs D:\downloads\openjms-0.7.7-beta-1\lib OpenJMSListener.java
    Substitue your local openjms\lib directory for the -extdirs.
  4. `
  5. Create the publisher/producer and save it as OpenJMSPublisher.java in your wroking directory.
     1. import java.io.*;
     2. import java.util.*;
     3. 
     4. import javax.jms.*;
     5. import javax.naming.*;
     6. 
     7. public class OpenJMSPublisher{
     8.     
     9.     public static void main(String args[]){
    10.         new OpenJMSPublisher().Go();
    11.     }
    12.     
    13.     public void Go(){
    14.     try{
    15. 
    16.       Properties props = new Properties();
    17.       props.load(getClass().getClassLoader().getResourceAsStream("jndi.properties"));
    18. 
    19.       Context context = new InitialContext(props);
    20.       TopicConnectionFactory tfactory = (TopicConnectionFactory) context.lookup("ConnectionFactory");
    21.          
    22.       TopicConnection tconnection = tfactory.createTopicConnection();
    23.       TopicSession tsession = tconnection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
    24. 
    25.       TextMessage message = tsession.createTextMessage();
    26.       message.setText("Hello there from publisher");
    27.       
    28.       //publish the message to topic
    29.       TopicPublisher publisher = tsession.createPublisher((Topic)context.lookup("topic1"));
    30.       publisher.publish(message);
    31.       
    32.       //send message to queue/destinations
    33.       MessageProducer sender = tsession.createProducer((Destination) context.lookup("queue1"));
    34.       sender.send(message);
    35.         
    36.       context.close();
    37.       tconnection.close();
    38.         
    39.     }catch(Exception e){
    40.       e.printStackTrace();
    41.      }
    42.   }
    43. }
    Hide line numbers
  6. `
  7. Now cd out to the workingdirectory compile the client

    ..workspace\openJMSExample>javac -extdirs D:\downloads\openjms-0.7.7-beta-1\lib OpenJMSPublisher.java
    Substitue your local openjms\lib directory for the -extdirs.

Running the example
  1. Open a promt to your working directory and run the listener/consumer

    ..workspace\openJMSExample>java -Djava.ext.dirs=D:\downloads\openjms-0.7.7-beta-1\lib OpenJMSListener
  2. `
  3. Now ppen anotehr promt to your working directory and run the publisher/producer.

    ..workspace\openJMSExample>java -Djava.ext.dirs=D:\downloads\openjms-0.7.7-beta-1\lib OpenJMSPublisher
    You should see "Hello there from publisher" twice. One sent via the topic and one via the destination/queue. If you stop the listener and run the publisher only, you can see the queued message in the admin GUI.

Back to the tutorial trail | Home