title: Troubleshooting SQL Server connection in C++ using Visual Studio Express 2013
body: <p>I've been trying to get a simple program together that can perform some simple operations on a SQL Server database, but can't get any of the tutorials to actually run.  I'm trying to figure out if the problem is with the code or with my ODBC settings.  Any help/insight is greatly appreciated.</p>
  
  <p><b>EDIT/UPDATE: ADDITIONAL DETAIL &amp; CODE BELOW</b></p>
  
  <p>The main program right now is based on <a href="http://www.tidytutorials.com/2009/08/connecting-to-sql-server-using-c-odbc.html" rel="nofollow noreferrer">this tutorial</a>.  I had to make a few changes so that VS Express 2013 would compile the code:</p>
  
  <ul><li>All instances of SQLCHAR * had to be changed to SQLWCHAR *.<li>Had to use wcout to output the error messages<li>The 'GOTO: FINISHED' used in the tutorial generated errors that the objects might be uninitialized. I added an 'UNFIN' block after 'FINISHED' and changed those generating errors to GOTO UNFIN to make the compier happy<li>Added a few debugging markers to make sure I was following the program properly<li>Changed the connection string to match the server, username and password of the database I'm trying to connect to.  <b>Note:</b> Target database uses SQLServer2008</ul>
  
  <p>On running the program, I get the following error message (generated by the show_error() function):</p>
  
  <pre><code>Messsage: [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified 
  nSQLSTATE: IM002
  </code></pre>
  
  <p>Could it be something as simple as an ODBC setting that I need to toggle on my machine or a dependency I've missed in the project setup?  </p>
  
  <p>Here's the code.  (Note that there are extra headers for other features being tested.  Said other features are commented out in my current test program and deleted from the below copy-paste to reduce confusion)</p>
  
  <pre><code>#include "stdafx.h"
  #include &lt;stdio.h&gt;
  #include &lt;string&gt;
  #include &lt;sstream&gt;//Used to int to string, and string to int operations
  #include &lt;stdlib.h&gt;
  #include &lt;fstream&gt;//Used for file opening, appending and writing operations
  #include &lt;iostream&gt;
  #include &lt;Windows.h&gt;//Used for sleep command, and window "clearwindow" function
  
  #include &lt;sqlext.h&gt;     // Used for writing to SQL database
  #include &lt;sqltypes.h&gt; 
  #include &lt;sql.h&gt;    
  
  using namespace std;
  
  
  void show_error(unsigned int handletype, const SQLHANDLE&amp; handle){
      SQLWCHAR sqlstate[1024];
      SQLWCHAR message[1024];
      cout &lt;&lt; "In show_error" &lt;&lt; endl;
      if (SQL_SUCCESS == SQLGetDiagRec(handletype, handle, 1, sqlstate, NULL, message, 1024, NULL)){
          cout &lt;&lt; "Message: ";
          wcout &lt;&lt; message;    
          cout &lt;&lt; endl &lt;&lt; "nSQLSTATE: ";
          wcout &lt;&lt; sqlstate;
          cout &lt;&lt; endl;
      }
  }
  
  bool write_to_database(/*string dbconnection, string fields, string values*/){
  
      SQLHANDLE sqlenvhandle;
      SQLHANDLE sqlconnectionhandle;
      SQLHANDLE sqlstatementhandle;
      SQLRETURN retcode;
  
      if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &amp;sqlenvhandle))
          goto UNFIN;
  
      if (SQL_SUCCESS != SQLSetEnvAttr(sqlenvhandle, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0))
          goto UNFIN;
  
      if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_DBC, sqlenvhandle, &amp;sqlconnectionhandle))
          goto UNFIN;
  
      SQLWCHAR retconstring[1024];
      cout &lt;&lt; "Made it this far at least" &lt;&lt; endl;
      switch (SQLDriverConnect(sqlconnectionhandle,
          NULL,
          (SQLWCHAR*)"DRIVER={SQL Server};SERVER=sqlserver.myhost.com, 1433;DATABASE=MyDatabase;UID=xxxxx;PWD=xxxxx",
          SQL_NTS,
          retconstring,
          1024,
          NULL,
          SQL_DRIVER_NOPROMPT)){
      case SQL_SUCCESS_WITH_INFO:
          show_error(SQL_HANDLE_DBC, sqlconnectionhandle);
          break;
      case SQL_INVALID_HANDLE:
      case SQL_ERROR:
          cout &lt;&lt; "Now we're in SQL_ERROR" &lt;&lt; endl;
          show_error(SQL_HANDLE_DBC, sqlconnectionhandle);
          goto FINISHED;
      default:
          break;
      }
  
      if (SQL_SUCCESS != SQLAllocHandle(SQL_HANDLE_STMT, sqlconnectionhandle, &amp;sqlstatementhandle))
          goto FINISHED;
  
      if (SQL_SUCCESS != SQLExecDirect(sqlstatementhandle, (SQLWCHAR*)"select * from testtable", SQL_NTS)){
          show_error(SQL_HANDLE_STMT, sqlstatementhandle);
          goto FINISHED;
      }
      else{
          char name[64];
          char address[64];
          int id;
          while (SQLFetch(sqlstatementhandle) == SQL_SUCCESS){
              SQLGetData(sqlstatementhandle, 1, SQL_C_ULONG, &amp;id, 0, NULL);
              SQLGetData(sqlstatementhandle, 2, SQL_C_CHAR, name, 64, NULL);
              SQLGetData(sqlstatementhandle, 3, SQL_C_CHAR, address, 64, NULL);
              cout &lt;&lt; id &lt;&lt; " " &lt;&lt; name &lt;&lt; " " &lt;&lt; address &lt;&lt; endl;
          }
      }
  
  FINISHED:
      SQLFreeHandle(SQL_HANDLE_STMT, sqlstatementhandle);
      SQLDisconnect(sqlconnectionhandle);
      SQLFreeHandle(SQL_HANDLE_DBC, sqlconnectionhandle);
      SQLFreeHandle(SQL_HANDLE_ENV, sqlenvhandle);
      goto ALLOVER;
  
  UNFIN:
      cout &lt;&lt; "Everything is unfinished" &lt;&lt; endl;
  ALLOVER:
  
      return true;
  }
  
  
  int _tmain(int argc, _TCHAR* argv[])
  {
  
      write_to_database();
  
      return 0;
  }
  </code></pre>
  
  <hr>
  
  <h3>EDIT/UPDATE:</h3>
  
  <p>Continuing to try and figure out where the error is.  Using code based off the tutorial at <a href="http://www.easysoft.com/developer/languages/c/odbc_tutorial.html" rel="nofollow noreferrer">EasySoft</a> to get the list of DSN available feels a little bit like progress. Here's the updated program and result:</p>
  
  <pre><code>// SQLTest.cpp : Defines the entry point for the console application.
  //
  
  #include "stdafx.h"
  #include &lt;stdio.h&gt;
  #include &lt;string&gt;
  #include &lt;iostream&gt;
  #include &lt;Windows.h&gt;//Used for sleep command, and window "clearwindow" function
  
  #include &lt;sql.h&gt;    
  #include &lt;sqltypes.h&gt; 
  #include &lt;sqlext.h&gt;     // Used for writing to SQL database
  
  using namespace std;
  
  
  
  static void extract_error(char *fn, SQLHANDLE handle, SQLSMALLINT handletype){
  
      SQLWCHAR sqlstate[1024];
      SQLWCHAR message[1024];
  
      if (SQL_SUCCESS == SQLGetDiagRec(handletype, handle, 1, sqlstate, NULL, message,     1024, NULL)){
          cout &lt;&lt; "Message: ";
          wcout &lt;&lt; message;
          cout &lt;&lt; " nSQLSTATE: ";
          wcout &lt;&lt; sqlstate;
          cout &lt;&lt; endl;
      }
  }
  
  
  static void do_sql(){
  
      SQLHENV env;
      SQLWCHAR dsn[256];
      SQLWCHAR desc[256];
      SQLSMALLINT dsn_ret;
      SQLSMALLINT desc_ret;
      SQLUSMALLINT direction;
      SQLRETURN ret;
  
      SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &amp;env);
      SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
  
      direction = SQL_FETCH_FIRST;
  
      cout &lt;&lt; "SQL DATA SOURCES:" &lt;&lt; endl;
  
      while (SQL_SUCCEEDED(ret = SQLDataSources(env, direction,
          dsn, sizeof(dsn), &amp;dsn_ret,
          desc, sizeof(desc), &amp;desc_ret))) {
          direction = SQL_FETCH_NEXT;
          wcout &lt;&lt; dsn &lt;&lt; " | " &lt;&lt; desc &lt;&lt; endl;
          if (ret == SQL_SUCCESS_WITH_INFO) printf("\tdata truncation\n");
      }
  
  
      SQLHDBC dbc;
      SQLHSTMT stmt;
      SQLWCHAR outstr[1024];
      SQLSMALLINT outstrlen;
  
      /* Allocate an environment handle */
      SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &amp;env);
          /* We want ODBC 3 support */
          SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (void *)SQL_OV_ODBC3, 0);
          /* Allocate a connection handle */
          SQLAllocHandle(SQL_HANDLE_DBC, env, &amp;dbc);
  
  
          /* Connect to the DSN mydsn */
          string connstr = "DSN=EnglobalConn";
      cout &lt;&lt; endl &lt;&lt; endl &lt;&lt; "ATTEMPTING TO CONNECT TO DATA SOURCE USING:" &lt;&lt; endl         &lt;&lt;connstr &lt;&lt; endl &lt;&lt; endl;
  
  
      ret = SQLDriverConnect(dbc, NULL, (SQLWCHAR*)connstr.c_str(), SQL_NTS,
          outstr, sizeof(outstr), &amp;outstrlen,
          SQL_DRIVER_NOPROMPT);
      if (SQL_SUCCEEDED(ret)) {
          printf("Connected\n");
          printf("Returned connection string was:\n\t%s\n", outstr);
          if (ret == SQL_SUCCESS_WITH_INFO) {
              printf("Driver reported the following diagnostics\n");
              extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
          }
          SQLDisconnect(dbc);     /* disconnect from driver */
      }
      else {
          fprintf(stderr, "Failed to connect\n");
          extract_error("SQLDriverConnect", dbc, SQL_HANDLE_DBC);
      }
      /* free up allocated handles */
      SQLFreeHandle(SQL_HANDLE_DBC, dbc);
      SQLFreeHandle(SQL_HANDLE_ENV, env);
  
  }
  
  
  
  int _tmain(int argc, _TCHAR* argv[])
  {
      do_sql();
  
      return 0;
  }
  </code></pre>
  
  <p>The program gives the following output. Error is the same for both 'EnglobalConn' and 'Englobal2'</p>
  
  <pre>
  SQL DATA SOURCES:
  dBASE Files | Microsoft Access dBASE Driver (*dbf, *.ndx, *.mdx)
  Excel Files | Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)
  MS Access Database | Microsoft Access Driver (*.mdb, *.accdb)
  Englobal2 | SQL Server
  EnglobalConn | SQL Server
  
  ATTEMPTING TO CONNECT TO DATA SOURCE USING:
  DSN=EnglobalConn
  
  Failed to connect
  Message: [Miscrosoft][ODBC Driver Manager] Data source name not found and no default driver specified nSQLSTATE: IM002
  </pre>
  
  <p>One piece of advice I found while Googling was that a 64-bit Windows install has 2 ODBC sets, one in System32 and one in SysWOW64.  I've run both and set the DSNs to be the same:
  In C:\Windows\SysWOW64\odbcad32.exe:
  User Data Sources: Englobal2 - SQL Server
  System DSN: EnglobalConn - SQL Server</p>
  
  <p>In C:\Windows\System32\odbcad32.exe:
  User Data Sources: Englobal2 - SQL Server
  System DSN: EnglobalConn - SQL Server</p>