February 28, 2021
Hot Topics:

Using Database Engines in a Mobile Application

  • By Alex Gusev
  • Send Email »
  • More Articles »

There is no need to note that, with database functionality, application logic becomes much simplier. And, a programmer's life—I don't even have to mention how that's simplified.... Windows CE has its own database support, but its usage is a bit complicated. It isn't overly complicated, but it's complicated enough enough from my point of view to choose flat binary files instead of inviting all this headache. Currently, you also may find a lot of database solutions for mobile devices. Which one of them you should use often depends on quite unrelated factors, such as existing environment, price, capabilities, and so forth. Microsoft provides, as a standard engine, SQL Server CE (in version 2.0 already), so I'll focus on this particular engine in this article. We definitely won't dive into all the details, but I'll try to cover in 'one touch' several techniques or environments, so you will be able to make your decision what to choose.


Using ADOCE on a Pocket PC is simple enough, even from C++ applications. If you are familiar with ADO for the desktop, you will find a pretty similar environment. Unfortunately, ADOCE development, along with eVB development, is no longer supported under the eVC4 IDE. Microsoft requires managed code and ADO.NET. That's really out of the clear blue sky, I would say. Nevetherless, Pocket PC 2002 devices are still alive, so it's not totally dead.

Windows CE provides two sets of interfaces: ADOCE and ADOXCE. ADOCE is used to access data in databases, and ADOXCE serves to manupulate the database objects such as tables, columns, and so forth. All this stuff is designed for single-user access only. For more convenient work, it's advised to use smart pointers with all interfaces. After all this dry theory, a small sample below demonstrates the taste of ADO under Windows CE:

#undef EOF
#import "adoce31.tlb"
#import "adoxce31.tlb"

using namespace ADOCE;
using namespace ADOXCE;
CString CSQLCEApp::m_sConnString =
      Data Source=\\Test.sdf");
int CSQLCEApp::CreateCatalog()
   _CatalogPtr pCatalog;
   if ( FAILED( pCatalog.CreateInstance( _T("ADOXCE.Catalog.3.1"))
      ) )
      TRACE(_T("Failed to create Catalog object\n"));
      return 0;

   _bstr_t bstrConnection(m_sConnString);
   _variant_t varConnection;
   varConnection = pCatalog->Create(bstrConnection);
   if(varConnection.vt != VT_DISPATCH)
      TRACE(_T("Catalog already exists\n"));
      return 1;
   TRACE(_T("Catalog created successfully\n"));
   return 1;

As you can see, the working environment is comfortable enough. You do import tlb-files and then use interfaces such as C++ classes. Pay attention to two things. First, #undef EOF—the usual ADO workaround. Second, in the connection string, you may define any existing provider, e.g. native Windows CE databases. Choosing ADO gives you relative simplicity in coding, but you pay for it by taking a performance hit. When your application doesn't keep a large amount of data, ADOCE may be the best choice. With heavy amounts of data, the user will be happy to throw the device in the recycle bin pretty quickly.

Similarly to the desktop environment, ADOCE provides you with two main methods of data manipulation. You either may execute SQL queries for all possible needs or work with database objects (such as tables) directly. The last method may be quicker, but not always suitable. Thus, the correct strategy depends on your application.

In addition, you have an option to synchronize databases with a desktop computer via ActiveSync. (Frankly, now only native and SQLCE databases may be synchronized via ActiveSync unless your database provider has implemented its own.)

CF.NET and the C# world

Since .NET 1.1, you have had a new namespace (System.Data.SqlServerCe) to work with a SQL server from C# applications. The following code snippet is just a short extraction from VC7 Help:

using System.Data.SqlServerCe;
string connStr = @"Data Source = \Test.sdf; Password = <password>";

SqlCeEngine engine = new SqlCeEngine(connStr);

SqlCeConnection conn = null;

   conn = new SqlCeConnection(connStr);

   SqlCeCommand cmd = conn.CreateCommand();
   cmd.CommandText = "CREATE TABLE TestTable (col1 int, col2 ntext)";
catch {}

We won't stick it in here specifically because you can find many good samples on the Web, for example here. As a bottom line, a C# programmer has a rich set of classes, even though not all of the desktop ones are supported under WinCE. But, at least replication and remote data access (RDA) are supported as far as manipulating data in local database goes. Once again, performance may be a bottleneck in this case also.

Page 1 of 3

This article was originally published on May 17, 2004

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date