Search code examples
c++sql-serverconnectionodbcado

Cannot make connection to SQL Server via ODBC


In the past, I have used ADO to access SQL Server, the connection string for the ADO connection object is:

Provider=sqloledb;Data Source=MYPC;Integrated Security=SSPI;

where MYPC is the name of my computer, and SQL Server is installed on my computer as the default instance.

The above connection string works well.

However, now it is said that ADO is outdated and ODBC is recommended again by Microsoft (see https://blogs.msdn.microsoft.com/sqlnativeclient/2011/08/29/microsoft-is-aligning-with-odbc-for-native-relational-data-access/ ), so I have to modify my code to use ODBC instead.

So I changed the connection to SQL Server to the following code:

    CDatabase Database;

    //  Provider=sqloledb;Data Source=MYPC;Integrated Security=SSPI;
    Database.OpenEx(_T("Driver = {SQL Native Client}; Server = MYPC; Trusted_Connection = yes;"), CDatabase::noOdbcDialog);

    Database.ExecuteSQL(_T("create database [MyDB2019] on primary (name=[MyDB2019_File],filename='F:\\MyDB2019.mdf')"));

    Database.Close();

However, this code does not work. After executing Database.OpenEx, there will be a CDBException indicating

Data source name not found and no default driver specified.

Why?

Note: I am using Visual C++ 2008 and ADO


Solution

  • The error/exception is pointing to the problem (albeit it seems a bit generic at first).

    "Data source name not found and no default driver specified"

    Data source name not found --> You did not specify a DSN, you do not want to use a DSN, ignore this part

    .

    and no default driver specified --> You intend to use a driver, so this part of the error most likely applies to you.

    The connection string appears syntactically correct: "Driver={Driver Name}...", so the next step is to check whether the driver you try to use, named SQL Native Client, exists on your machine.

    "SQL Native Client" was/is the driver name for SQL Server 2005. From SQL2008 the driver name got a version descriptor.

    Driver={SQL Native Client}             ,sql2005   
    Driver={SQL Server Native Client 10.0} ,sql2008  
    Driver={SQL Server Native Client 11.0} ,sql2012 and later  
    Driver={ODBC Driver 11 for SQL Server} ,sql2012 and later, odbc appears in the name
    Driver={ODBC Driver 13 for SQL Server}  
    Driver={ODBC Driver 17 for SQL Server}
    

    An easy way to find the installed 'SQL Native' and 'ODBC Driver for SQL Server' drivers on your machine, would be to run the ODBC Data Source Administrator. Type Odbc data sources in your search box or odbcad32.exe in the command/address bar (for 64bit: %windir%\system32\odbcad32.exe)

    When in ODBC Data Source Administrator, switch to the Drivers tab and there you will find all the available/installed drivers, at your disposal.

    Here is a powershell script that opens a connection to localhost using odbc. Adjust accordingly to your installed driver(s)

    cls
    $conn = new-object system.data.odbc.odbcconnection 
    $conn.connectionstring = 
    # all these installed on my pc and working
    #"Driver={SQL Server Native Client 11.0};Server=localhost; Database=master;Trusted_Connection=yes;" 
    #"Driver={SQL Server};Server=localhost; Database=master;Trusted_Connection=yes;" 
    #"Driver={ODBC Driver 11 for SQL Server};Server=localhost; Database=master;Trusted_Connection=yes;" 
    "Driver={ODBC Driver 17 for SQL Server};Server=localhost; Database=master;Trusted_Connection=yes;" 
    
    $conn.Open()
    $conn.State
    $conn.Close();
    

    ..and an mfc button

    void CMFCDBTestDlg::OnBnClickedButton1()
    {
        // TODO: Add your control notification handler code here
        CDatabase database;
        CString connectionstring = _T("Driver={SQL Server Native Client 10.0};Server=localhost;Trusted_Connection=yes;");
        CString messagetext;
    
        TRY{
            //database.Open(NULL, FALSE, FALSE, connectionstring, FALSE); //ok
            database.OpenEx(connectionstring, CDatabase::noOdbcDialog); //ok
    
            if (database.IsOpen()){
                messagetext = _T("open, database:") + database.GetDatabaseName();
                database.Close();
            }
       }CATCH(CDBException, e) {
           messagetext = _T("Database error: ")+e->m_strError;
       }
       END_CATCH;
    
       AfxMessageBox(messagetext, 0, 0);
    }