简体   繁体   中英

How can I query a MS SQL Compact Server 3.5 database in C++ not using the OLE DB API?

I have the dlls and the include files of MS SQL Compact Server 3.5. How can I use it without OLE DB? I just want to load the dlls and invoke the necessary methods myself, no COM please.

Does anyone know the API?

EDIT

If this is not possible is there a fully functional example in C++ demonstrating accessing a database using the MSSQL Compact Server edition?

I just noticed you mentioned no COM. If it weren't for that I would have suggested ADO. Recently I posted some OLEDB code for Raw C++ code to display the names of tables in an SQL compact server using OLE DB that you may find useful.

Otherwise, if you wish want to see my ADODB in C++ answer (that involves COM), I've worked through converting a ADODB VBScript example:

Dim con, rs
Set con = CreateObject("ADODB.Connection")
REM con.Provider = "Microsoft.SQLLITE.MOBILE.OLEDB.3.0"
con.Provider = "Microsoft.SQLSERVER.CE.OLEDB.3.5"
con.Open "InsertYourDatabase.sdf"
Set rs = con.Execute("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES")
While not rs.EOF
  WScript.Echo rs.Fields.Item(0).Value
  rs.MoveNext
Wend

To use ADODB in C++ is somewhat arduous, but, it is possible. The following C++ console application shows how to do this by using #import on the ADODB library:

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <oleauto.h>
#include <atlbase.h>
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" raw_interfaces_only, raw_native_types, no_namespace, named_guids

int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT hr = S_OK;

    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

    // Open a SQL Server CE 3.5 database.
    CComPtr<_Connection> spConnection;
    hr = spConnection.CoCreateInstance(CLSID_Connection);
    //hr = spConnection->put_Provider(CComBSTR(L"Microsoft.SQLLITE.MOBILE.OLEDB.3.0"));
    hr = spConnection->put_Provider(CComBSTR(L"Microsoft.SQLSERVER.CE.OLEDB.3.5"));
    hr = spConnection->Open(CComBSTR(L"InsertYourDatabase.sdf"), CComBSTR(L""), CComBSTR(L""), -1);

    // Execute a query.
    CComPtr<_Recordset> spRecordset;
    CComVariant varRecordsAffected;
    hr = spConnection->Execute(CComBSTR(L"SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES"), &varRecordsAffected, -1, &spRecordset);

    // Fetch the results.
    VARIANT_BOOL bEOF = VARIANT_TRUE;
    hr = spRecordset->get_EOF(&bEOF);
    while (SUCCEEDED(hr) && bEOF != VARIANT_TRUE)
    {
        // Fetch the TABLE_NAME.
        CComPtr<Fields> spFields;
        hr = spRecordset->get_Fields(&spFields);
        CComPtr<Field> spField;
        hr = spFields->get_Item(CComVariant((int) 0), &spField);
        CComVariant varTableName;
        hr = spField->get_Value(&varTableName);

        // Display the record.
        if (varTableName.vt == VT_BSTR)
        {
            wprintf(L"%s\n", V_BSTR(&varTableName));
        }

        // Move to the next record.
        hr = spRecordset->MoveNext();
        bEOF = VARIANT_TRUE;
        hr = spRecordset->get_EOF(&bEOF);
    }

    // Release smart pointers.
    spRecordset = NULL;
    spConnection = NULL;

    CoUninitialize();
    return 0;
}

You can extract the IDL of ADODB by using OleView (on my PC it was installed with Visual Studio under C:\\Program Files\\Microsoft SDKs\\Windows\\v7.0\\Bin\\OleView.exe). Once you have OleView running:

  • File > View TypeLib ...
  • Navigate to C:\\Program Files\\Common Files\\System\\ADO\\msado15.dll
  • Click Open

This will give you a full syntax of the ADODB library which will help you use it in C++. You can also refer to Microsoft MSDN's ADO API Reference .

For those who are interested in how the issue is resolved.

One does not have to install SqlCE in order to use its COM API.

Here are the steps:

  1. Make sure you have the right dlls.

    For SqlCE 3.0 the dlls are:

    • sqlceca30.dll
    • sqlcecompact30.dll
    • sqlceer30xx.dll
    • sqlceme30.dll
    • sqlceoledb30.dll
    • sqlceqp30.dll
    • sqlcese30.dll

    for SqlCE 3.5:

    • sqlceca35.dll
    • sqlcecompact35.dll
    • sqlceer35EN.dll
    • sqlceme35.dll
    • sqlceoledb35.dll
    • sqlceqp35.dll
    • sqlcese35.dll

    and for SqlCE 4.0:

    • sqlceca40.dll
    • sqlcecompact40.dll
    • sqlceer40EN.dll
    • sqlceme40.dll
    • sqlceoledb40.dll
    • sqlceqp40.dll
    • sqlcese40.dll

    You may also need the .h file for the definitions of the respective COM classes. I have these:

    • sqlce_err.h
    • sqlce_oledb.h
    • sqlce_sync.h
  2. Given an sdf Sql CE database file you have to determine which version it belongs to. Google for it, basically you need to read the first 16 bytes of the file, find the magic number and it determines the version.

  3. Knowing the Sql CE version, locate the directory containing the respective Sql CE dlls (see above).
  4. Call ::LoadLibrary win32 API for the sqlceoledbNN.dll, where NN is 30, 35 or 40. It depends on other dlls, so they must be near it.
  5. Call ::GetProcAddress win32 API to get the address of the exported DllGetClassObject function.
  6. Having at hand the pointer to the DllGetClassObject you are ready to exercise the COM API provided by the Sql CE.

"Enjoy"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM