Beispiel #1
0
bool DoDirect(HSTMT	lpStmt, SQLCHAR* input)
{
	RETCODE		RetCode;
	SQLSMALLINT	sNumResults;

	RetCode = SQLExecDirect(lpStmt, (SQLCHAR*) input, SQL_NTS);

	switch (RetCode)
	{
	case	SQL_SUCCESS_WITH_INFO:
	{
		HandleError(lpStmt, SQL_HANDLE_STMT, RetCode);
		// fall through
	}
	case	SQL_SUCCESS:
	{
		// If this is a row-returning query, display
		// results
		TRYODBC(lpStmt,
		        SQL_HANDLE_STMT,
		        SQLNumResultCols(lpStmt, &sNumResults));

		if (sNumResults > 0)
		{
			DisplayResults(lpStmt, sNumResults);
		} else
		{
			SQLLEN		siRowCount;

			TRYODBC(lpStmt,
			        SQL_HANDLE_STMT,
			        SQLRowCount(lpStmt, &siRowCount));

			if (siRowCount >= 0)
			{
				_tprintf(TEXT("%ld %s affected\n"),
				         static_cast<long>(siRowCount),
				         siRowCount == 1 ? TEXT("row") : TEXT("rows"));
			}
		}
		break;
	}

	case	SQL_ERROR:
	{
		_tprintf(TEXT("going to call handle error\n"));
		HandleError(lpStmt, SQL_HANDLE_STMT, RetCode);
		break;
	}

	default:
		fprintf(stderr, "Unexpected return code %d!\n", RetCode);
	}

	return true;
Exit:
	return false;
}
Beispiel #2
0
void DisplayResults(HSTMT       hStmt,
                    SQLSMALLINT cCols,
		    bool        silent)
{
  SQLSMALLINT     cDisplaySize;
  RETCODE         RetCode = SQL_SUCCESS;
  int             iCount = 0;
  long long numReceived = 0;

  // Allocate memory for each column 
  SQLCHAR buffer[MAXCOLS][BUFFERLEN];
  SQLLEN indPtr[MAXCOLS];
  int iCol;

  for (iCol = 0; iCol < cCols; iCol++) {
    TRYODBC(hStmt,
	    SQL_HANDLE_STMT,
	    SQLBindCol(hStmt,
		       iCol+1,
		       SQL_C_CHAR,
		       (SQLPOINTER) buffer[iCol],
		       (BUFFERLEN) * sizeof(char),
		       &indPtr[iCol]));    
  }

  // Fetch and display the data

  bool fNoData = false;

  do {
    // Fetch a row

    TRYODBC(hStmt, SQL_HANDLE_STMT, RetCode = SQLFetch(hStmt));

    if (RetCode == SQL_NO_DATA_FOUND)
      {
	fNoData = true;
      }
    else
      {
	if (!silent) {
	  // Display the data.   Ignore truncations	
	  printf("%s", buffer[0]);
	  for (iCol = 1; iCol < cCols; iCol++) {
	    printf(",%s", buffer[iCol]);
	  }
	  printf("\n");
	}

	numReceived++;
      }
  } while (!fNoData);

 Exit:
  printf("numRecieved = %lld\n", numReceived);
}
Beispiel #3
0
void	DisplayTitles(HSTMT		lpStmt,
                    DWORD		siDisplaySize,
                    BINDING	*pBinding)
{
	TCHAR			szTitle[DISPLAY_MAX];
	SQLSMALLINT		iCol = 1;

	SetConsole(siDisplaySize + 2, TRUE);


	for (; pBinding; pBinding = pBinding->sNext)
	{
		TRYODBC(lpStmt,
		        SQL_HANDLE_STMT,
		        SQLColAttribute(lpStmt,
		                        iCol++,
		                        SQL_DESC_NAME,
		                        szTitle,
		                        sizeof(szTitle),	// Note count of bytes!
		                        NULL,
		                        NULL));

		_tprintf(TEXT(DISPLAY_FORMAT_C), PIPE,
		         pBinding->siDisplaySize,
		         pBinding->siDisplaySize,
		         szTitle);

	}

Exit:

	_tprintf(TEXT(" %c"), PIPE);
	SetConsole(siDisplaySize + 2, FALSE);
	_tprintf(TEXT("\n"));
}
Beispiel #4
0
void DisplayTitles(HSTMT     hStmt,
                   DWORD     cDisplaySize,
                   BINDING   *pBinding)
{
    WCHAR           wszTitle[DISPLAY_MAX];
    SQLSMALLINT     iCol = 1;

    SetConsole(cDisplaySize+2, TRUE);

    for (; pBinding; pBinding = pBinding->sNext)
    {
        TRYODBC(hStmt,
                SQL_HANDLE_STMT,
                SQLColAttribute(hStmt,
                    iCol++,
                    SQL_DESC_NAME,
                    wszTitle,
                    sizeof(wszTitle), // Note count of bytes!
                    NULL,
                    NULL));

        wprintf(DISPLAY_FORMAT_C,
                 PIPE,
                 pBinding->cDisplaySize,
                 pBinding->cDisplaySize,
                 wszTitle);
    }

Exit:

    wprintf(L" %c", PIPE);
    SetConsole(cDisplaySize+2, FALSE);
    wprintf(L"\n");

}
Beispiel #5
0
void AllocateBindings(HSTMT			lpStmt,
                      SQLSMALLINT	cCols,
                      BINDING		**lppBinding,
                      SQLSMALLINT	*lpDisplay)
{
	SQLSMALLINT		iCol;
	BINDING			*lpThisBinding, *lpLastBinding;
	SQLSMALLINT		cchColumnNameLength;
	SQLLEN          cchDisplay, ssType;

	*lpDisplay = 0;

	for (iCol = 1; iCol <= cCols; iCol++)
	{
		lpThisBinding = (BINDING *)(malloc(sizeof(BINDING)));
		if (!(lpThisBinding))
		{
			fprintf(stderr, "Out of memory!\n");
			exit(-100);
		}

		if (iCol == 1)
		{
			*lppBinding = lpThisBinding;
		}
		else
		{
			lpLastBinding->sNext = lpThisBinding;
		}
		lpLastBinding = lpThisBinding;


		// Figure out the display length of the column (we will
		// bind to char since we are only displaying data, in general
		// you should bind to the appropriate C type if you are going
		// to manipulate data since it is much faster...)

		TRYODBC(lpStmt,
		        SQL_HANDLE_STMT,
		        SQLColAttribute(lpStmt,
		                        iCol,
		                        SQL_DESC_DISPLAY_SIZE,
		                        NULL,
		                        0,
		                        NULL,
		                        &cchDisplay));


		// Figure out if this is a character or numeric column; this is
		// used to determine if we want to display the data left- or right-
		// aligned.

		// !! Note a bug in the 3.x documentation.  We claim that
		// SQL_DESC_TYPE is a 1.x feature.   That is not true, SQL_DESC_TYPE
		// is a 3.x feature.   SQL_DESC_CONCISE_TYPE maps to the 1.x
		// SQL_COLUMN_TYPE.   This is what you must use if you want to work
		// against a 2.x driver.  Sorry for the inconvenience...

		TRYODBC(lpStmt,
		        SQL_HANDLE_STMT,
		        SQLColAttribute(lpStmt,
		                        iCol,
		                        SQL_DESC_CONCISE_TYPE,
		                        NULL,
		                        0,
		                        NULL,
		                        &ssType));


		lpThisBinding->fChar = (ssType == SQL_CHAR ||
		                        ssType == SQL_VARCHAR ||
		                        ssType == SQL_LONGVARCHAR);

		lpThisBinding->sNext = NULL;

		// Arbitrary limit on display size
		if (cchDisplay > DISPLAY_MAX)
			cchDisplay = DISPLAY_MAX;

		// Allocate a buffer big enough to hold the text representation
		// of the data.  Add one character for the null terminator

		lpThisBinding->szBuffer = (TCHAR *)malloc((cchDisplay + 1) * sizeof(TCHAR));

		if (!(lpThisBinding->szBuffer))
		{
			fprintf(stderr, "Out of memory!\n");
			exit(-100);
		}

		// Map this buffer to the driver's buffer.   At Fetch time,
		// the driver will fill in this data.  Note that the size is
		// count of bytes (for Unicode).  All ODBC functions that take
		// SQLPOINTER use count of bytes; all functions that take only
		// strings use count of characters.


		SQLLEN lenInd;
		TRYODBC(lpStmt,
		        SQL_HANDLE_STMT,
		        SQLBindCol(lpStmt,
		                   iCol,
		                   SQL_C_TCHAR,
		                   (SQLPOINTER) lpThisBinding->szBuffer,
		                   (cchDisplay + 1) * sizeof(TCHAR),
		                   &lenInd));
		lpThisBinding->indPtr = lenInd;

		// Now set the display size that we will use to display
		// the data.   Figure out the length of the column name

		TRYODBC(lpStmt,
		        SQL_HANDLE_STMT,
		        SQLColAttribute(lpStmt,
		                        iCol,
		                        SQL_DESC_NAME,
		                        NULL,
		                        0,
		                        &cchColumnNameLength,
		                        NULL));

		lpThisBinding->siDisplaySize = cchDisplay > cchColumnNameLength ? cchDisplay : cchColumnNameLength;
		if (lpThisBinding->siDisplaySize < NULL_SIZE)
			lpThisBinding->siDisplaySize = NULL_SIZE;

		*lpDisplay += lpThisBinding->siDisplaySize + DISPLAY_FORMAT_EXTRA;

	}

Exit:
	// Not really a good error exit handler, we should free
	// up any memory that we allocated.   But this is a sample...

	return;
}
Beispiel #6
0
void DisplayResults(HSTMT		lpStmt,
                    SQLSMALLINT	cCols)
{
	BINDING			*pFirstBinding, *pThisBinding;
	SQLSMALLINT		siDisplaySize;
	RETCODE			RetCode;
	int				iCount = 0;

	// Allocate memory for each column

	AllocateBindings(lpStmt, cCols, &pFirstBinding, &siDisplaySize);

	// Set the display mode and write the titles

	DisplayTitles(lpStmt, siDisplaySize, pFirstBinding);


	// Fetch and display the data

	do {
		// Fetch a row

		if (iCount++ >= gHeight - 2)
		{
			char	szInput[100];
			printf("              ");
			SetConsole(siDisplaySize + 2, TRUE);
			printf("   Press ENTER to continue, Q to quit");
			printf("%d", gHeight);
			SetConsole(siDisplaySize + 2, FALSE);
			gets(szInput);
			if ((*szInput == 'Q') || (*szInput == 'q'))
				goto Exit;

			iCount = 1;
			DisplayTitles(lpStmt, siDisplaySize, pFirstBinding);
		}

		TRYODBC(lpStmt, SQL_HANDLE_STMT, RetCode = SQLFetch(lpStmt));

		if (RetCode == SQL_NO_DATA_FOUND)
			break;

		if (RetCode == SQL_NO_DATA)
			break;


		// Display the data.   Ignore truncations
		for (pThisBinding = pFirstBinding;
		     pThisBinding;
		     pThisBinding = pThisBinding->sNext)
		{
			if (pThisBinding->indPtr != SQL_NULL_DATA)
			{
				_tprintf(pThisBinding->fChar ? TEXT(DISPLAY_FORMAT_C) :
				         TEXT(DISPLAY_FORMAT),
				         PIPE,
				         pThisBinding->siDisplaySize,
				         pThisBinding->siDisplaySize,
				         pThisBinding->szBuffer);
			} else
			{
				_tprintf(TEXT(DISPLAY_FORMAT_C),
				         PIPE,
				         pThisBinding->siDisplaySize,
				         pThisBinding->siDisplaySize,
				         "<NULL>");
			}
		}
		_tprintf(TEXT(" %c\n"), PIPE);


	} while ( 1);

	SetConsole(siDisplaySize + 2, TRUE);
	printf("%*.*s", siDisplaySize + 2, siDisplaySize + 2, " ");
	SetConsole(siDisplaySize + 2, FALSE);
	printf("\n");

Exit:
	// Clean up the allocated buffers

	while (pFirstBinding)
	{
		pThisBinding = pFirstBinding->sNext;
		free(pFirstBinding->szBuffer);
		free(pFirstBinding);
		pFirstBinding = pThisBinding;
	}

}
Beispiel #7
0
int _tmain(int argc, TCHAR **argv)
{
	HENV	lpEnv = NULL;
	HDBC	lpDbc = NULL;
	HSTMT	lpStmt = NULL;
	TCHAR	*pszConnStr;
	TCHAR	szInput[SQL_QUERY_SIZE];
	TCHAR *szLoc = NULL;

	// Allocate an environment

	if (SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &lpEnv) == SQL_ERROR)
	{
		fprintf(stderr, "Unable to allocate an environment handle\n");
		exit(-1);
	}

	// Register this as an application that expects 2.x behavior,
	// you must register something if you use AllocHandle

	TRYODBC(lpEnv,
	        SQL_HANDLE_ENV,
	        SQLSetEnvAttr(lpEnv,
	                      SQL_ATTR_ODBC_VERSION,
	                      (SQLPOINTER)SQL_OV_ODBC2,
	                      0));

	// Allocate a connection

	TRYODBC(lpEnv,
	        SQL_HANDLE_ENV,
	        SQLAllocHandle(SQL_HANDLE_DBC, lpEnv, &lpDbc));



	if (argc > 1)
	{
		pszConnStr = *++argv;
	} else
	{
		pszConnStr = NULL;
	}

	// Connect to the driver.  Use the connection string if supplied
	// on the input, otherwise let the driver manager prompt for input.
	_tprintf("calling connect\n");
	TRYODBC(lpDbc,
	        SQL_HANDLE_DBC,
	        SQLDriverConnect(lpDbc,
	                         GetDesktopWindow(),
	                         (SQLCHAR*) pszConnStr,
	                         SQL_NTS,
	                         NULL,
	                         0,
	                         NULL,
	                         SQL_DRIVER_COMPLETE));

	fprintf(stderr, "Connected!\n");


	TRYODBC(lpDbc,
	        SQL_HANDLE_DBC,
	        SQLAllocHandle(SQL_HANDLE_STMT, lpDbc, &lpStmt));


	printf("Enter SQL commands, type (control)Z to exit\nSQL COMMAND>");

	// Loop to get input and execute queries

	while (_fgetts(szInput, SQL_QUERY_SIZE - 1, stdin))
	{
		// Execute the query

		if (!(*szInput))
		{
			printf("SQL COMMAND>");
			continue;
		}

		if ('!' == szInput[0]) {
			int len = strlen(szInput);
			szInput[len] = '\0';
			if (0 == strcmp("tables", szInput)) {
				DoTables(lpStmt);
			} else {
				_tprintf("unknown command\n");
			}
		} else {
			szLoc = strstr(szInput, "?");
			if (NULL == szLoc) {
				if (!DoDirect(lpStmt, (SQLCHAR*) szInput)) {
					goto Exit;
				}
			} else {
				if (!DoPrepared(lpDbc, szInput)) {
					goto Exit;
				}
			}
		}

		TRYODBC(lpStmt,
		        SQL_HANDLE_STMT,
		        SQLFreeStmt(lpStmt, SQL_CLOSE));

		printf("SQL COMMAND>");
	}

Exit:

	// Free ODBC handles and exit

	if (lpDbc)
	{
		SQLDisconnect(lpDbc);
		SQLFreeConnect(lpDbc);
	}
	if (lpEnv)
		SQLFreeEnv(lpEnv);

	printf("\nDisconnected.");

	return 0;

}
Beispiel #8
0
int main(int argc, char **argv)
{
  SQLHENV     hEnv = NULL;
  SQLHDBC     hDbc = NULL;
  SQLHSTMT    hStmt = NULL;
  char*       pConnStr;
  char        pQuery[1000];
  bool        silent = true;

  if (argc != 5) {
    fprintf(stderr, "Usage: %s <ConnString> <pkey range> <ccol range> <rand seed>\n", argv[0]);
    return 1;
  }
  pConnStr = argv[1];
  char *endptr;
  long long numkeys = strtoll(argv[2], &endptr, 10);
  long long rowsperkey = strtoll(argv[3], &endptr, 10);
  int seed = atoi(argv[4]);
  struct drand48_data lcg;
  srand48_r(seed, &lcg);

  // Allocate an environment
  if (!silent)
    fprintf(stderr, "Allocating Handle Enviroment\n");
  if (SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv) == SQL_ERROR)
    {
      fprintf(stderr, "Unable to allocate an environment handle\n");
      exit(-1);
    }

  // Register this as an application that expects 3.x behavior,
  // you must register something if you use AllocHandle
  if (!silent)
    fprintf(stderr, "Setting to ODBC3\n");
  TRYODBC(hEnv,
	  SQL_HANDLE_ENV,
	  SQLSetEnvAttr(hEnv,
			SQL_ATTR_ODBC_VERSION,
			(SQLPOINTER)SQL_OV_ODBC3,
			0));

  // Allocate a connection
  if (!silent)
    fprintf(stderr, "Allocating Handle\n");
  TRYODBC(hEnv,
	  SQL_HANDLE_ENV,
	  SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc));

  // Connect to the driver.  Use the connection string if supplied
  // on the input, otherwise let the driver manager prompt for input.
  if (!silent)
    fprintf(stderr, "Connecting to driver\n");
  TRYODBC(hDbc,
	  SQL_HANDLE_DBC,
	  SQLDriverConnect(hDbc,
			   NULL,
			   pConnStr,
			   SQL_NTS,
			   NULL,
			   0,
			   NULL,
			   SQL_DRIVER_COMPLETE));

  fprintf(stderr, "Connected!\n");

  if (!silent)
    fprintf(stderr, "Allocating statement\n");
  TRYODBC(hDbc,
	  SQL_HANDLE_DBC,
	  SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt));

  RETCODE     RetCode;
  SQLSMALLINT sNumResults;

  // Execute the query
  if (!silent)
    fprintf(stderr, "Executing query\n");
  long long i;
  double rval;
  for (i = 0; i < 100000; i++) {
    drand48_r(&lcg, &rval);
    sprintf(pQuery, "SELECT MAX(col1) FROM otest.test10 WHERE ccol = %lld", (long long)(rval * numkeys));
    RetCode = SQLExecDirect(hStmt, pQuery, SQL_NTS);

    switch(RetCode)
      {
      case SQL_SUCCESS_WITH_INFO:
	{
	  HandleDiagnosticRecord(hStmt, SQL_HANDLE_STMT, RetCode);
	  // fall through
	}
      case SQL_SUCCESS:
	{
	  // If this is a row-returning query, display
	  // results
	  TRYODBC(hStmt,
		  SQL_HANDLE_STMT,
		  SQLNumResultCols(hStmt,&sNumResults));
	  
	  if (sNumResults > 0)
	    {
	      DisplayResults(hStmt,sNumResults, silent);
	    } 
	  else
	    {
	      SQLLEN cRowCount;
	      
	      TRYODBC(hStmt,
		      SQL_HANDLE_STMT,
		      SQLRowCount(hStmt,&cRowCount));
	      
	      if (cRowCount >= 0)
		{
		  printf("%d %s returned\n",
			 (int)cRowCount,
			 (cRowCount == 1) ? "row" : "rows");
		}
	    }
	  break;
	}
	
      case SQL_ERROR:
	{
	  HandleDiagnosticRecord(hStmt, SQL_HANDLE_STMT, RetCode);
	  break;
	}
	
      default:
	fprintf(stderr, "Unexpected return code %hd!\n", RetCode);
	
      }
  }

  TRYODBC(hStmt,
	  SQL_HANDLE_STMT,
	  SQLFreeStmt(hStmt, SQL_CLOSE));

 Exit:

  // Free ODBC handles and exit

  if (hStmt)
    {
      SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
    }

  if (hDbc)
    {
      SQLDisconnect(hDbc);
      SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
    }

  if (hEnv)
    {
      SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
    }

  return 0;

}
int _tmain(int argc, TCHAR **argv)
{
	SQLHENV		lpEnv = NULL;
	SQLHDBC		lpDbc = NULL;
	SQLHSTMT	lpStmt = NULL;
	TCHAR		*pszConnStr;
	TCHAR		szInput[SQL_QUERY_SIZE];

	// Allocate an environment

	if (SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&lpEnv) == SQL_ERROR)
	{
		fprintf(stderr,"Unable to allocate an environment handle\n");
		exit(-1);
	}

	// Register this as an application that expects 2.x behavior,
	// you must register something if you use AllocHandle

	TRYODBC(lpEnv,
			SQL_HANDLE_ENV,
			SQLSetEnvAttr(lpEnv,
						  SQL_ATTR_ODBC_VERSION,
						  (SQLPOINTER)SQL_OV_ODBC2,
						  0));

	// Allocate a connection

	TRYODBC(lpEnv,
			SQL_HANDLE_ENV,
			SQLAllocHandle(SQL_HANDLE_DBC,lpEnv,&lpDbc));

	

	if (argc > 1)
	{
		pszConnStr = *++argv;
	} else
	{
		pszConnStr = NULL;
	}

	// Connect to the driver.  Use the connection string if supplied
	// on the input, otherwise let the driver manager prompt for input.

	TRYODBC(lpDbc,
			SQL_HANDLE_DBC,
			SQLDriverConnect(lpDbc,
							 GetDesktopWindow(),
							 pszConnStr,
							 SQL_NTS,
							 NULL,
							 0,
							 NULL,
							 SQL_DRIVER_COMPLETE));

	fprintf(stderr,"Connected!\n");

	TRYODBC(lpDbc,
			SQL_HANDLE_DBC,
			SQLAllocHandle(SQL_HANDLE_STMT,lpDbc,&lpStmt));


	printf("Enter SQL commands, type (control)Z to exit\nSQL COMMAND>");

	// Loop to get input and execute queries

	while(_fgetts(szInput, SQL_QUERY_SIZE-1, stdin))
	{
		RETCODE		RetCode;
		SQLSMALLINT	sNumResults;

		// Execute the query

		if (!(*szInput))
		{
			printf("SQL COMMAND>");
			continue;
		}
		RetCode = SQLExecDirect(lpStmt,szInput,SQL_NTS);

		switch(RetCode)
		{
			case	SQL_SUCCESS_WITH_INFO:
			{
				HandleError(lpStmt,SQL_HANDLE_STMT,RetCode);
				// fall through
			}
			case	SQL_SUCCESS:
			{
				// If this is a row-returning query, display
				// results
				TRYODBC(lpStmt,
						SQL_HANDLE_STMT,
						SQLNumResultCols(lpStmt,&sNumResults));

				if (sNumResults > 0)
				{
					DisplayResults(lpStmt,sNumResults);
				} else
				{
					SQLLEN		siRowCount;

					TRYODBC(lpStmt,
							SQL_HANDLE_STMT,
							SQLRowCount(lpStmt,&siRowCount));

					if (siRowCount >= 0)
					{
						_tprintf(TEXT("%d %s affected\n"),
								siRowCount,
								siRowCount == 1 ? TEXT("row") : TEXT("rows"));
					}
				}
				break;
			}

			case	SQL_ERROR:
			{
				HandleError(lpStmt,SQL_HANDLE_STMT,RetCode);
				break;
			}

			default:
					fprintf(stderr,"Unexpected return code %d!\n",RetCode);

		}
		TRYODBC(lpStmt,
				SQL_HANDLE_STMT,
				SQLFreeStmt(lpStmt,SQL_CLOSE));

		printf("SQL COMMAND>");
	}

Exit:

	// Free ODBC handles and exit

	if (lpDbc)
	{
		SQLDisconnect(lpDbc);
		SQLFreeConnect(lpDbc);
	}
	if (lpEnv)
		SQLFreeEnv(lpEnv);

	printf("\nDisconnected.");

	return 0;

}
Beispiel #10
0
void AllocateBindings(HSTMT         hStmt,
                      SQLSMALLINT   cCols,
                      BINDING       **ppBinding,
                      SQLSMALLINT   *pDisplay)
{
    SQLSMALLINT     iCol;
    BINDING         *pThisBinding, *pLastBinding = NULL;
    SQLLEN          cchDisplay, ssType;
    SQLSMALLINT     cchColumnNameLength;

    *pDisplay = 0;

    for (iCol = 1; iCol <= cCols; iCol++)
    {
        pThisBinding = (BINDING *)(malloc(sizeof(BINDING)));
        if (!(pThisBinding))
        {
            fwprintf(stderr, L"Out of memory!\n");
            exit(-100);
        }

        if (iCol == 1)
        {
            *ppBinding = pThisBinding;
        }
        else
        {
            pLastBinding->sNext = pThisBinding;
        }
        pLastBinding = pThisBinding;


        // Figure out the display length of the column (we will
        // bind to char since we are only displaying data, in general
        // you should bind to the appropriate C type if you are going
        // to manipulate data since it is much faster...)

        TRYODBC(hStmt,
                SQL_HANDLE_STMT,
                SQLColAttribute(hStmt,
                    iCol,
                    SQL_DESC_DISPLAY_SIZE,
                    NULL,
                    0,
                    NULL,
                    &cchDisplay));


        // Figure out if this is a character or numeric column; this is
        // used to determine if we want to display the data left- or right-
        // aligned.

        // SQL_DESC_CONCISE_TYPE maps to the 1.x SQL_COLUMN_TYPE. 
        // This is what you must use if you want to work
        // against a 2.x driver.

        TRYODBC(hStmt,
                SQL_HANDLE_STMT,
                SQLColAttribute(hStmt,
                    iCol,
                    SQL_DESC_CONCISE_TYPE,
                    NULL,
                    0,
                    NULL,
                    &ssType));


        pThisBinding->fChar = (ssType == SQL_CHAR ||
                                ssType == SQL_VARCHAR ||
                                ssType == SQL_LONGVARCHAR);

        pThisBinding->sNext = NULL;

        // Arbitrary limit on display size
        if (cchDisplay > DISPLAY_MAX)
            cchDisplay = DISPLAY_MAX;

        // Allocate a buffer big enough to hold the text representation
        // of the data.  Add one character for the null terminator

        pThisBinding->wszBuffer = (WCHAR *)malloc((cchDisplay+1) * sizeof(WCHAR));

        if (!(pThisBinding->wszBuffer))
        {
            fwprintf(stderr, L"Out of memory!\n");
            exit(-100);
        }

        // Map this buffer to the driver's buffer.   At Fetch time,
        // the driver will fill in this data.  Note that the size is 
        // count of bytes (for Unicode).  All ODBC functions that take
        // SQLPOINTER use count of bytes; all functions that take only
        // strings use count of characters.

        TRYODBC(hStmt,
                SQL_HANDLE_STMT,
                SQLBindCol(hStmt,
                    iCol,
                    SQL_C_TCHAR,
                    (SQLPOINTER) pThisBinding->wszBuffer,
                    (cchDisplay + 1) * sizeof(WCHAR),
                    &pThisBinding->indPtr));


        // Now set the display size that we will use to display
        // the data.   Figure out the length of the column name

        TRYODBC(hStmt,
                SQL_HANDLE_STMT,
                SQLColAttribute(hStmt,
                    iCol,
                    SQL_DESC_NAME,
                    NULL,
                    0,
                    &cchColumnNameLength,
                    NULL));

        pThisBinding->cDisplaySize = max((SQLSMALLINT)cchDisplay, cchColumnNameLength);
        if (pThisBinding->cDisplaySize < NULL_SIZE)
            pThisBinding->cDisplaySize = NULL_SIZE;

        *pDisplay += pThisBinding->cDisplaySize + DISPLAY_FORMAT_EXTRA;

    }

    return;

Exit:

    exit(-1);

    return;
}
Beispiel #11
0
void DisplayResults(HSTMT       hStmt,
                    SQLSMALLINT cCols)
{
    BINDING         *pFirstBinding, *pThisBinding;          
    SQLSMALLINT     cDisplaySize;
    RETCODE         RetCode = SQL_SUCCESS;
    int             iCount = 0;

    // Allocate memory for each column 

    AllocateBindings(hStmt, cCols, &pFirstBinding, &cDisplaySize);

    // Set the display mode and write the titles

    DisplayTitles(hStmt, cDisplaySize+1, pFirstBinding);


    // Fetch and display the data

    bool fNoData = false;

    do {
        // Fetch a row

        if (iCount++ >= gHeight - 2)
        {
            int     nInputChar;
            bool    fEnterReceived = false;

            while(!fEnterReceived)
            {   
                wprintf(L"              ");
                SetConsole(cDisplaySize+2, TRUE);
                wprintf(L"   Press ENTER to continue, Q to quit (height:%hd)", gHeight);
                SetConsole(cDisplaySize+2, FALSE);

                nInputChar = _getch();
                wprintf(L"\n");
                if ((nInputChar == 'Q') || (nInputChar == 'q'))
                {
                    goto Exit;
                }
                else if ('\r' == nInputChar)
                {
                    fEnterReceived = true;
                }
                // else loop back to display prompt again
            }

            iCount = 1;
            DisplayTitles(hStmt, cDisplaySize+1, pFirstBinding);
        }

        TRYODBC(hStmt, SQL_HANDLE_STMT, RetCode = SQLFetch(hStmt));

        if (RetCode == SQL_NO_DATA_FOUND)
        {
            fNoData = true;
        }
        else
        {

            // Display the data.   Ignore truncations

            for (pThisBinding = pFirstBinding;
                pThisBinding;
                pThisBinding = pThisBinding->sNext)
            {
                if (pThisBinding->indPtr != SQL_NULL_DATA)
                {
                    wprintf(pThisBinding->fChar ? DISPLAY_FORMAT_C:DISPLAY_FORMAT,
                        PIPE,
                        pThisBinding->cDisplaySize,
                        pThisBinding->cDisplaySize,
                        pThisBinding->wszBuffer);
                } 
                else
                {
                    wprintf(DISPLAY_FORMAT_C,
                        PIPE,
                        pThisBinding->cDisplaySize,
                        pThisBinding->cDisplaySize,
                        L"<NULL>");
                }
            }
            wprintf(L" %c\n",PIPE);
        }
    } while (!fNoData);

    SetConsole(cDisplaySize+2, TRUE);
    wprintf(L"%*.*s", cDisplaySize+2, cDisplaySize+2, L" ");
    SetConsole(cDisplaySize+2, FALSE);
    wprintf(L"\n");

Exit:
    // Clean up the allocated buffers

    while (pFirstBinding)
    {
        pThisBinding = pFirstBinding->sNext;
        free(pFirstBinding->wszBuffer);
        free(pFirstBinding);
        pFirstBinding = pThisBinding;
    }
}
Beispiel #12
0
//int __cdecl wmain(int argc, _In_reads_(argc) WCHAR **argv)
//int __cdecl wmain(int argc, WCHAR **argv)
int __cdecl wmain2(int argc, WCHAR **argv)
{
    SQLHENV     hEnv = NULL;
    SQLHDBC     hDbc = NULL;
    SQLHSTMT    hStmt = NULL;
    WCHAR*      pwszConnStr;
    WCHAR       wszInput[SQL_QUERY_SIZE];

    // Allocate an environment

    if (SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv) == SQL_ERROR)
    {
        fwprintf(stderr, L"Unable to allocate an environment handle\n");
        exit(-1);
    }

    // Register this as an application that expects 3.x behavior,
    // you must register something if you use AllocHandle

    TRYODBC(hEnv,
            SQL_HANDLE_ENV,
            SQLSetEnvAttr(hEnv,
                SQL_ATTR_ODBC_VERSION,
                (SQLPOINTER)SQL_OV_ODBC3,
                0));

    // Allocate a connection
    TRYODBC(hEnv,
            SQL_HANDLE_ENV,
            SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc));

    if (argc > 1)
    {
        pwszConnStr = *++argv;
    } 
    else
    {
        pwszConnStr = L"";
    }

    // Connect to the driver.  Use the connection string if supplied
    // on the input, otherwise let the driver manager prompt for input.

    TRYODBC(hDbc,
        SQL_HANDLE_DBC,
        SQLDriverConnect(hDbc,
                         GetDesktopWindow(),
                         pwszConnStr,
                         SQL_NTS,
                         NULL,
                         0,
                         NULL,
                         SQL_DRIVER_COMPLETE));

    fwprintf(stderr, L"Connected!\n");

    TRYODBC(hDbc,
            SQL_HANDLE_DBC,
            SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt));

    wprintf(L"Enter SQL commands, type (control)Z to exit\nSQL COMMAND>");

    // Loop to get input and execute queries

    while(_fgetts(wszInput, SQL_QUERY_SIZE-1, stdin))
    {
        RETCODE     RetCode;
        SQLSMALLINT sNumResults;

        // Execute the query

        if (!(*wszInput))
        {
            wprintf(L"SQL COMMAND>");
            continue;
        }
        RetCode = SQLExecDirect(hStmt,wszInput, SQL_NTS);

        switch(RetCode)
        {
        case SQL_SUCCESS_WITH_INFO:
            {
                HandleDiagnosticRecord(hStmt, SQL_HANDLE_STMT, RetCode);
                // fall through
            }
        case SQL_SUCCESS:
            {
                // If this is a row-returning query, display
                // results
                TRYODBC(hStmt,
                        SQL_HANDLE_STMT,
                        SQLNumResultCols(hStmt,&sNumResults));

                if (sNumResults > 0)
                {
                    DisplayResults(hStmt,sNumResults);
                } 
                else
                {
                    SQLLEN cRowCount;

                    TRYODBC(hStmt,
                        SQL_HANDLE_STMT,
                        SQLRowCount(hStmt,&cRowCount));

                    if (cRowCount >= 0)
                    {
                        wprintf(L"%Id %s affected\n",
                                 cRowCount,
                                 cRowCount == 1 ? L"row" : L"rows");
                    }
                }
                break;
            }

        case SQL_ERROR:
            {
                HandleDiagnosticRecord(hStmt, SQL_HANDLE_STMT, RetCode);
                break;
            }

        default:
            fwprintf(stderr, L"Unexpected return code %hd!\n", RetCode);

        }
        TRYODBC(hStmt,
                SQL_HANDLE_STMT,
                SQLFreeStmt(hStmt, SQL_CLOSE));

        wprintf(L"SQL COMMAND>");
    }

Exit:

    // Free ODBC handles and exit

    if (hStmt)
    {
        SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
    }

    if (hDbc)
    {
        SQLDisconnect(hDbc);
        SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
    }

    if (hEnv)
    {
        SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
    }

    wprintf(L"\nDisconnected.");

    return 0;

}