static t_sql_field* sql_odbc_fetch_fields(t_sql_res *result) { int i; t_odbc_res *res; int fieldCount; t_sql_field *fields; if(!result) { eventlog(eventlog_level_error, __FUNCTION__, "Got NULL result."); return NULL; } res = (t_odbc_res*)result; fieldCount = sql_odbc_num_fields(result); fields = xcalloc(sizeof *fields, fieldCount+1); if(!fields) { return NULL; } fields[fieldCount] = NULL; for(i=0; i<fieldCount; i++) { TCHAR *fName; TCHAR *tmp; SQLSMALLINT fNameSz; SQLColAttribute(res->stmt, i+1, SQL_DESC_NAME, NULL, 0, &fNameSz, NULL); fName = xmalloc(fNameSz); if(!fName) { return NULL; } SQLColAttribute(res->stmt, i+1, SQL_DESC_NAME, fName, fNameSz, &fNameSz, NULL); tmp = fName; for ( ; *tmp; ++tmp) *tmp = toupper(*tmp); fields[i] = fName; } return fields; }
void OdbcQuery::execQuery(const char *sql) { pOdbc->execDML(sql); SQLSMALLINT cols = 0; struct COL { char *name; int name_size; char *buffer; int buffer_size; SQLSMALLINT dataType; } *pCol; SQLNumResultCols(pOdbc->sqlstatementhandle, &cols); pCol = new COL[cols]; for (int i = 0; i < cols; i++) { pCol[i].name = new char[128]; SQLColAttribute(pOdbc->sqlstatementhandle, (SQLUSMALLINT) i + 1, SQL_DESC_LABEL, pCol[i].name, 128, (SQLSMALLINT *) &pCol[i].name_size, NULL); SQLColAttribute(pOdbc->sqlstatementhandle, (SQLUSMALLINT) i + 1, SQL_COLUMN_TYPE, NULL, 0, NULL, (SQLLEN *) &pCol[i].dataType); pCol[i].buffer = new char[MAX_BUFFER_SIZE]; SQLBindCol(pOdbc->sqlstatementhandle, (SQLUSMALLINT) i + 1, SQL_C_CHAR, pCol[i].buffer, MAX_BUFFER_SIZE, (SQLLEN *) &pCol[i].buffer_size); // printf("%s\t", pCol[i].name); } // printf("\n"); }
int classISQL::getResultsHeader( SQLHSTMT hStmt, SWORD nColumns, QString *pqsHorizSep ) { QString qsColumnHeader = ""; QString qsColumn = ""; QString qsColumnName = ""; int nCol; SQLLEN nMaxLength = 10; SQLCHAR szColumnName[101] = ""; *pqsHorizSep = ""; for ( nCol = 1; nCol <= nColumns; nCol++ ) { int nWidth; SQLColAttribute( hStmt, nCol, SQL_DESC_DISPLAY_SIZE, 0, 0, 0, &nMaxLength ); SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), 0, 0 ); qsColumnName = (const char *)szColumnName; nWidth = max( nMaxLength, qsColumnName.length() ); nWidth = min( nWidth, MAX_COLUMN_WIDTH ); qsColumn.fill( '-', nWidth ); qsColumn += "-"; *pqsHorizSep += ( "+" + qsColumn ); qsColumn.sprintf( "| %-*s", nWidth, szColumnName ); qsColumnHeader += qsColumn; } *pqsHorizSep += "+\n"; qsColumnHeader += "|\n"; txtResults->append( *pqsHorizSep ); txtResults->append( qsColumnHeader ); txtResults->append( *pqsHorizSep ); return qsColumnHeader.length(); }
int classISQL::getResultsBody( SQLHSTMT hStmt, SWORD nColumns ) { QString qsLine; QString qsColumn; QString qsColumnName = ""; int iRC = 0; SQLUSMALLINT nCol = 0; SQLLEN nIndicator; char szColumn[MAX_COLUMN_WIDTH+1]; int nRow = 0; SQLLEN nMaxLength = 10; SQLCHAR szColumnName[101]; // PROCESS ALL ROWS while ( SQL_SUCCESS == (iRC=SQLFetch(hStmt)) || SQL_SUCCESS_WITH_INFO == iRC ) { int nWidth; nRow++; qsLine = ""; // PROCESS ALL COLUMNS for ( nCol = 1; nCol <= nColumns; nCol++ ) { SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), 0, 0 ); SQLColAttribute( hStmt, nCol, SQL_DESC_DISPLAY_SIZE, 0, 0, 0, &nMaxLength ); qsColumnName = (const char *)szColumnName; iRC = SQLGetData( hStmt, nCol, SQL_C_CHAR, (SQLPOINTER)szColumn, sizeof(szColumn), &nIndicator ); /* * this is to handle a broken driver not null terminated * truncated strings */ szColumn[MAX_COLUMN_WIDTH] = '\0'; nWidth = max( nMaxLength, qsColumnName.length() ); nWidth = min( nWidth, MAX_COLUMN_WIDTH ); if ( iRC == SQL_SUCCESS && nIndicator != SQL_NULL_DATA ) qsColumn.sprintf( "| %-*s", nWidth, szColumn ); else // Print a dash to represent NULL data as opposed to real blanks qsColumn.sprintf( "| %-*s", nWidth, "-" ); qsLine += qsColumn; } qsLine += "|\n"; txtResults->append( qsLine ); } return nRow ; }
/************************************************************************* * * Function: sql_fetch_row * * Purpose: database specific fetch_row. Returns a SQL_ROW struct * with all the data for the query in 'sqlsocket->row'. Returns * 0 on success, -1 on failure, SQL_DOWN if 'database is down' * *************************************************************************/ static int sql_fetch_row(SQLSOCK * sqlsocket, SQL_CONFIG *config) { int c, i; SQLINTEGER len, slen; SQL_ROW retval; rlm_sql_db2_sock *sock; sock = sqlsocket->conn; c = sql_num_fields(sqlsocket, config); retval = (SQL_ROW)rad_malloc(c*sizeof(char*)+1); /* advance cursor */ if(SQLFetch(sock->stmt) == SQL_NO_DATA_FOUND) { sqlsocket->row = NULL; return 0; } for(i = 0; i < c; i++) { /* get column length */ SQLColAttribute(sock->stmt, i+1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &len); retval[i] = (char*)rad_malloc(len+1); /* get the actual column */ SQLGetData(sock->stmt, i+1, SQL_C_CHAR, retval[i], len+1, &slen); if(slen == SQL_NULL_DATA) retval[i][0] = '\0'; } sqlsocket->row = retval; return 0; }
static t_sql_row* odbc_alloc_row(t_odbc_res *result, SQLINTEGER *sizes) { int i, fieldCount; HSTMT stmt = result->stmt; t_sql_row *row; fieldCount = sql_odbc_num_fields(result); /* Create a new row. */ row = xcalloc(sizeof *row, fieldCount+1); if(!row) { return NULL; } row[fieldCount] = NULL; sizes = xcalloc(sizeof *sizes, fieldCount); for(i=0; i<fieldCount; i++) { TCHAR *cell; SQLLEN cellSz; SQLColAttribute(stmt, i+1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &cellSz); cell = xcalloc(sizeof *cell, ++cellSz); if(!cell) { return NULL; } SQLBindCol(stmt, i+1, SQL_C_CHAR, cell, cellSz, &sizes[i]); row[i] = cell; } return row; }
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")); }
static int get_result_columns(ZBX_ODBC_DBH *dbh, char **buffer) { int ret = SUCCEED, i, j; char str[MAX_STRING_LEN]; SQLRETURN rc; SQLSMALLINT len; for (i = 0; i < dbh->col_num; i++) { rc = SQLColAttribute(dbh->hstmt, i + 1, SQL_DESC_LABEL, str, sizeof(str), &len, NULL); if (SQL_SUCCESS != rc || sizeof(str) <= len || '\0' == *str) { for (j = 0; j < i; j++) zbx_free(buffer[j]); ret = FAIL; break; } buffer[i] = zbx_strdup(NULL, str); } return ret; }
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"); }
SQLRETURN unixodbc_backend_debug::do_column_attribute(SQLHSTMT statement_handle, SQLUSMALLINT column_id, SQLUSMALLINT field_identifier, SQLPOINTER character_attribute_ptr, SQLSMALLINT buffer_length, SQLSMALLINT * string_length_ptr, SQLLEN * numeric_attribute_ptr) const { std::cout << " *DEBUG* column_attribute"; auto const return_code = SQLColAttribute(statement_handle, column_id, field_identifier, character_attribute_ptr, buffer_length, string_length_ptr, numeric_attribute_ptr); std::cout << " (return code " << return_code << ")" << std::endl; return return_code; }
/**************************** * WRITE HTML ***************************/ static void WriteHeaderHTMLTable( SQLHSTMT hStmt ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLCHAR szColumnName[MAX_DATA_WIDTH+1]; *szColumnName = '\0'; printf( "<table BORDER>\n" ); printf( "<tr BGCOLOR=#000099>\n" ); if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; for ( nCol = 1; nCol <= nColumns; nCol++ ) { SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); printf( "<td>\n" ); printf( "<font face=Arial,Helvetica><font color=#FFFFFF>\n" ); printf( "%s\n", szColumnName ); printf( "</font></font>\n" ); printf( "</td>\n" ); } printf( "</tr>\n" ); }
OGRMSSQLSpatialSelectLayer::OGRMSSQLSpatialSelectLayer( OGRMSSQLSpatialDataSource *poDSIn, CPLODBCStatement * poStmtIn ) { poDS = poDSIn; iNextShapeId = 0; nSRSId = -1; poFeatureDefn = NULL; poStmt = poStmtIn; pszBaseStatement = CPLStrdup( poStmtIn->GetCommand() ); /* identify the geometry column */ pszGeomColumn = NULL; for ( int iColumn = 0; iColumn < poStmt->GetColCount(); iColumn++ ) { if ( EQUAL(poStmt->GetColTypeName( iColumn ), "image") ) { SQLCHAR szTableName[256]; SQLSMALLINT nTableNameLength = 0; SQLColAttribute(poStmt->GetStatement(), (SQLSMALLINT)(iColumn + 1), SQL_DESC_TABLE_NAME, szTableName, sizeof(szTableName), &nTableNameLength, NULL); if (nTableNameLength > 0) { OGRLayer *poBaseLayer = poDS->GetLayerByName((const char*)szTableName); if (poBaseLayer != NULL && EQUAL(poBaseLayer->GetGeometryColumn(), poStmt->GetColName(iColumn))) { nGeomColumnType = MSSQLCOLTYPE_BINARY; pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn)); /* copy spatial reference */ if (!poSRS && poBaseLayer->GetSpatialRef()) poSRS = poBaseLayer->GetSpatialRef()->Clone(); break; } } } else if ( EQUAL(poStmt->GetColTypeName( iColumn ), "geometry") ) { nGeomColumnType = MSSQLCOLTYPE_GEOMETRY; pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn)); break; } else if ( EQUAL(poStmt->GetColTypeName( iColumn ), "geography") ) { nGeomColumnType = MSSQLCOLTYPE_GEOGRAPHY; pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn)); break; } } BuildFeatureDefn( "SELECT", poStmt ); if ( GetSpatialRef() && poFeatureDefn->GetGeomFieldCount() == 1) poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef( poSRS ); }
static isc_result_t odbc_getManyFields(SQLHSTMT *stmnt, SQLSMALLINT startField, SQLSMALLINT endField, char **retData) { isc_result_t result; SQLLEN size; int totSize = 0; SQLSMALLINT i; int j = 0; char *data; REQUIRE(retData != NULL && *retData == NULL); REQUIRE(startField > 0 && startField <= endField); /* determine how large the data is */ for (i=startField; i <= endField; i++) if (sqlOK(SQLColAttribute(stmnt, i, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &size)) && size > 0) { /* always allow for a " " (space) character */ totSize += (size + 1); /* after the data item */ } if (totSize < 1) return ISC_R_FAILURE; /* allow for a "\n" at the end of the string/ */ data = isc_mem_allocate(ns_g_mctx, ++totSize); if (data == NULL) return ISC_R_NOMEMORY; result = ISC_R_FAILURE; /* get the data and concat all fields into a large string */ for (i=startField; i <= endField; i++) { if (sqlOK(SQLGetData(stmnt, i, SQL_C_CHAR, &(data[j]), totSize - j, &size))) { if (size > 0) { j += size; data[j++] = ' '; data[j] = '\0'; result = ISC_R_SUCCESS; } } else { isc_mem_free(ns_g_mctx, data); return ISC_R_FAILURE; } } if (result != ISC_R_SUCCESS) { isc_mem_free(ns_g_mctx, data); return result; } *retData = data; return ISC_R_SUCCESS; }
static void check_attr_ird(ATTR_PARAMS) { SQLLEN i; SQLRETURN ret; if (attr->type == type_CHARP) { char buf[128]; SQLSMALLINT len; ret = SQLColAttribute(odbc_stmt, 1, attr->value, buf, sizeof(buf), &len, NULL); if (!SQL_SUCCEEDED(ret)) fatal("Line %u: failure not expected\n", line_num); buf[sizeof(buf)-1] = 0; if (strcmp(buf, expected_value) != 0) { g_result = 1; fprintf(stderr, "Line %u: invalid %s got %s expected %s\n", line_num, attr->name, buf, expected_value); } return; } i = 0xdeadbeef; ret = SQLColAttribute(odbc_stmt, 1, attr->value, NULL, SQL_IS_INTEGER, NULL, &i); if (!SQL_SUCCEEDED(ret)) fatal("Line %u: failure not expected\n", line_num); /* SQL_DESC_LENGTH is the same of SQLDescribeCol len */ if (attr->value == SQL_DESC_LENGTH) { SQLSMALLINT si; SQLULEN li; CHKDescribeCol(1, NULL, 0, NULL, &si, &li, &si, &si, "S"); if (i != li) fatal("Line %u: attr %s SQLDescribeCol len %ld != SQLColAttribute len %ld\n", line_num, attr->name, (long) li, (long) i); } if (i != lookup(expected_value, attr->lookup)) { g_result = 1; fprintf(stderr, "Line %u: invalid %s got %ld expected %s\n", line_num, attr->name, (long int) i, expected_value); } }
/**************************** * OptimalDisplayWidth ***************************/ static SQLUINTEGER OptimalDisplayWidth( SQLHSTMT hStmt, SQLINTEGER nCol, int nUserWidth ) { SQLUINTEGER nLabelWidth = 10; SQLULEN nDataWidth = 10; SQLUINTEGER nOptimalDisplayWidth = 10; SQLCHAR szColumnName[MAX_DATA_WIDTH+1]; *szColumnName = '\0'; SQLColAttribute( hStmt, nCol, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, (SQLLEN*)&nDataWidth ); SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); nLabelWidth = strlen((char*) szColumnName ); nOptimalDisplayWidth = max( nLabelWidth, nDataWidth ); if ( nUserWidth > 0 ) nOptimalDisplayWidth = min( nOptimalDisplayWidth, nUserWidth ); if ( nOptimalDisplayWidth > MAX_DATA_WIDTH ) nOptimalDisplayWidth = MAX_DATA_WIDTH; return nOptimalDisplayWidth; }
SQLRETURN SQLColAttributeA( SQLHSTMT statement_handle, SQLSMALLINT column_number, SQLSMALLINT field_identifier, SQLPOINTER character_attribute, SQLSMALLINT buffer_length, SQLSMALLINT *string_length, SQLPOINTER numeric_attribute ) { return SQLColAttribute( statement_handle, (SQLUSMALLINT) column_number, (SQLUSMALLINT) field_identifier, character_attribute, buffer_length, string_length, numeric_attribute ); }
/**************************** * WRITE NORMAL ***************************/ static void WriteHeaderNormal( SQLHSTMT hStmt, SQLCHAR *szSepLine ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLCHAR szColumn[MAX_DATA_WIDTH+20]; SQLCHAR szColumnName[MAX_DATA_WIDTH+1]; /*SQLCHAR szHdrLine[32001] = ""; */ SQLCHAR *szHdrLine; SQLUINTEGER nOptimalDisplayWidth = 10; szHdrLine = calloc(1, 32001); *szColumn = '\0'; *szColumnName = '\0'; if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; for ( nCol = 1; nCol <= nColumns; nCol++ ) { int sret; nOptimalDisplayWidth = OptimalDisplayWidth( hStmt, nCol, nUserWidth ); SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); /* SEP */ memset( szColumn, '\0', sizeof(szColumn) ); memset( szColumn, '-', nOptimalDisplayWidth + 1 ); strcat((char*) szSepLine, "+" ); strcat((char*) szSepLine,(char*) szColumn ); /* HDR */ sret = sprintf( (char*)szColumn, "| %-*.*s", (int)nOptimalDisplayWidth, (int)nOptimalDisplayWidth, szColumnName ); if (sret < 0) sprintf((char *)szColumn, "| %-*.*s", (int)nOptimalDisplayWidth, (int)nOptimalDisplayWidth, "**ERROR**"); strcat( (char*)szHdrLine,(char*) szColumn ); } strcat((char*) szSepLine, "+\n" ); strcat((char*) szHdrLine, "|\n" ); fputs((char*) szSepLine, stdout ); fputs((char*) szHdrLine, stdout ); fputs((char*) szSepLine, stdout ); free(szHdrLine); }
SQLRETURN SQL_API SQLColAttributeA(SQLHSTMT StatementHandle, SQLSMALLINT ColumnNumber, SQLSMALLINT FieldIdentifier, SQLPOINTER CharacterAttributePtr, SQLSMALLINT BufferLength, SQLSMALLINT *StringLengthPtr, LENP_OR_POINTER_T NumericAttributePtr) { return SQLColAttribute(StatementHandle, (SQLUSMALLINT) ColumnNumber, (SQLUSMALLINT) FieldIdentifier, CharacterAttributePtr, BufferLength, StringLengthPtr, NumericAttributePtr); }
int OdbcStatement::GetColCount() { SQLINTEGER colcount; SQLRETURN result = SQLColAttribute(mSqlStatementHandle, 1, SQL_DESC_COUNT, 0, 0, 0, &colcount); if (result == SQL_SUCCESS || result == SQL_SUCCESS_WITH_INFO) { return colcount; } else { SQLTCHAR sql_state[7]; SQLTCHAR message_text[1024]; GetDiag(sql_state,message_text,1024); TCHAR szMsg[1200]; _stprintf(szMsg, _T( "OdbcStatement::GetColCount() - SQLColAttribute failed.\n%s"),message_text); throw szMsg; } }
char* bgl_odbc_get_data_as_string(SQLHANDLE stmt, unsigned int colnum) { char* res = NULL; SQLLEN length = 0; SQLLEN resLength = 0; SQLRETURN v; // obtain maximum column width in characters v = SQLColAttribute(stmt, (SQLUSMALLINT)colnum, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &length); if(!SQL_SUCCEEDED(v)) { report_odbc_error("bgl_odbc_get_data_as_string", SQL_HANDLE_STMT, stmt); } res = (char*)GC_MALLOC_ATOMIC(sizeof(char)*length+1); v = SQLGetData(stmt, (SQLUSMALLINT)colnum, SQL_C_CHAR, res, length+1, &resLength); if(!SQL_SUCCEEDED(v)) { report_odbc_error("bgl_odbc_get_data_as_string", SQL_HANDLE_STMT, stmt); } if(resLength <= 0) { res[0] = '\0'; } return res; }
static isc_result_t odbc_getField(SQLHSTMT *stmnt, SQLSMALLINT field, char **data) { SQLLEN size; REQUIRE(data != NULL && *data == NULL); if (sqlOK(SQLColAttribute(stmnt, field, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &size)) && size > 0) { *data = isc_mem_allocate(ns_g_mctx, size + 1); if (data != NULL) { if (sqlOK(SQLGetData(stmnt, field, SQL_C_CHAR, *data, size + 1,&size))) return ISC_R_SUCCESS; isc_mem_free(ns_g_mctx, *data); } } return ISC_R_FAILURE; }
/************************************************************************* * * Function: sql_fetch_row * * Purpose: database specific fetch_row. Returns a rlm_sql_row_t struct * with all the data for the query in 'handle->row'. Returns * 0 on success, -1 on failure, RLM_SQL_RECONNECT if 'database is down' * *************************************************************************/ static sql_rcode_t sql_fetch_row(rlm_sql_handle_t *handle, rlm_sql_config_t *config) { int c, i; SQLINTEGER len, slen; rlm_sql_row_t retval; rlm_sql_db2_conn_t *conn; conn = handle->conn; c = sql_num_fields(handle, config); retval = (rlm_sql_row_t)rad_malloc(c*sizeof(char*)+1); memset(retval, 0, c*sizeof(char*)+1); /* advance cursor */ if(SQLFetch(conn->stmt) == SQL_NO_DATA_FOUND) { handle->row = NULL; goto error; } for(i = 0; i < c; i++) { /* get column length */ SQLColAttribute(conn->stmt, i+1, SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &len); retval[i] = rad_malloc(len+1); /* get the actual column */ SQLGetData(conn->stmt, i + 1, SQL_C_CHAR, retval[i], len+1, &slen); if(slen == SQL_NULL_DATA) { retval[i][0] = '\0'; } } handle->row = retval; return RLM_SQL_OK; error: for(i = 0; i < c; i++) { free(retval[i]); } free(retval); return RLM_SQL_ERROR; }
/**************************** * WRITE DELIMITED * - this output can be used by the ODBC Text File driver * - last column no longer has a delimit char (it is implicit)... * this is consistent with odbctxt ***************************/ static void WriteHeaderDelimited( SQLHSTMT hStmt, char cDelimiter ) { SQLINTEGER nCol = 0; SQLSMALLINT nColumns = 0; SQLCHAR szColumnName[MAX_DATA_WIDTH+1]; *szColumnName = '\0'; if ( SQLNumResultCols( hStmt, &nColumns ) != SQL_SUCCESS ) nColumns = -1; for ( nCol = 1; nCol <= nColumns; nCol++ ) { SQLColAttribute( hStmt, nCol, SQL_DESC_LABEL, szColumnName, sizeof(szColumnName), NULL, NULL ); fputs((char*) szColumnName, stdout ); if ( nCol < nColumns ) putchar( cDelimiter ); } putchar( '\n' ); }
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; }
EWXWEXPORT(wxDbColInf*,wxDb_GetResultColumns)(wxDb* db,int* pnumCols) { #ifndef wxUSE_ODBC if (pnumCols) *pnumCols = 0; return NULL; #else RETCODE retcode = 0; HSTMT hstmt = SQL_NULL_HSTMT; SWORD numCols = 0; UWORD column = 0; wxDbColInf* colInf = NULL; if (pnumCols) *pnumCols = 0; if (db==NULL) return NULL; /* allocate column info's */ hstmt = db->GetHSTMT(); retcode = SQLNumResultCols(hstmt,&numCols); if (retcode != SQL_SUCCESS) { db->DispAllErrors(db->GetHENV(), db->GetHDBC(), hstmt); return NULL; } if (numCols==0) return NULL; colInf = new wxDbColInf[numCols+1]; if (!colInf) return NULL; /* mark the end of the array */ wxStrcpy(colInf[numCols].tableName, wxEmptyString); wxStrcpy(colInf[numCols].colName, wxEmptyString); colInf[numCols].sqlDataType = 0; /* initialize all column infos */ for( column = 0; column < numCols; column++) { SWORD colNameLen = 0; SWORD typeNameLen = 0; UDWORD colSize = 0; /* get the column information */ retcode = SQLDescribeCol(hstmt, column+1, #ifndef wxUSE_UNICODE (SQLCHAR*)colInf[column].colName, #else (SQLWCHAR*)colInf[column].colName, #endif DB_MAX_COLUMN_NAME_LEN+1, &colNameLen, &colInf[column].sqlDataType, &colSize, &colInf[column].decimalDigits, &colInf[column].nullable ); #if (wxVERSION_NUMBER <= 2500) colInf[column].columnSize = colSize; #else /* (wxVERSION_NUMBER <= 2500) */ colInf[column].columnLength = colSize; #endif /* (wxVERSION_NUMBER <= 2500) */ /* check for errors */ if (retcode != SQL_SUCCESS) { db->DispAllErrors(db->GetHENV(), db->GetHDBC(), hstmt); delete [] colInf; return NULL; } #ifdef SQL_DESC_TYPE_NAME /* try to get type name too (errors are no problem) */ SQLColAttribute( hstmt, column+1, SQL_DESC_TYPE_NAME, colInf[column].typeName, 128+1, &typeNameLen, NULL ); #endif /* for compatibilty with the wxWindows GetColumns, we set the dbDataType too */ colInf[column].dbDataType = 0; switch (colInf[column].sqlDataType) { #ifndef wxUSE_UNICODE #if defined(SQL_WVARCHAR) case SQL_WVARCHAR: #endif #if defined(SQL_WCHAR) case SQL_WCHAR: #endif #endif case SQL_VARCHAR: case SQL_CHAR: colInf[column].dbDataType = DB_DATA_TYPE_VARCHAR; break; case SQL_TINYINT: case SQL_SMALLINT: case SQL_INTEGER: #ifdef SQL_BIGINT case SQL_BIGINT: #endif #ifdef SQL_BIT case SQL_BIT: #endif colInf[column].dbDataType = DB_DATA_TYPE_INTEGER; break; case SQL_DOUBLE: case SQL_DECIMAL: case SQL_NUMERIC: case SQL_FLOAT: case SQL_REAL: colInf[column].dbDataType = DB_DATA_TYPE_FLOAT; break; #ifdef SQL_DATE case SQL_DATE: colInf[column].dbDataType = DB_DATA_TYPE_DATE; break; #endif #ifdef SQL_BINARY case SQL_BINARY: colInf[column].dbDataType = DB_DATA_TYPE_BLOB; break; #endif #ifdef __WXDEBUG__ default: wxString errMsg; errMsg.Printf(wxT("SQL Data type %d currently not supported by wxWindows"), colInf[column].sqlDataType); wxLogDebug(errMsg,wxT("ODBC DEBUG MESSAGE")); #endif } } /* for columns */ if (pnumCols) *pnumCols = numCols; return colInf; #endif }
SQLRETURN unixodbc_backend::do_column_attribute(SQLHSTMT statement_handle, SQLUSMALLINT column_id, SQLUSMALLINT field_identifier, SQLPOINTER character_attribute_ptr, SQLSMALLINT buffer_length, SQLSMALLINT * string_length_ptr, SQLLEN * numeric_attribute_ptr) const { return SQLColAttribute(statement_handle, column_id, field_identifier, character_attribute_ptr, buffer_length, string_length_ptr, numeric_attribute_ptr); }
SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier, SQLPOINTER CharacterAttribute, SQLSMALLINT BufferLength, SQLSMALLINT * StringLength, #ifdef _WIN64 SQLLEN * NumericAttribute) #else SQLPOINTER NumericAttribute) #endif { RETCODE ret = ODBC_ERROR; SQLWCHAR *wvalue; OutputDebugString ("SQLColAttributeW called.\n"); ret = SQLColAttribute (StatementHandle, ColumnNumber, FieldIdentifier, CharacterAttribute, BufferLength, StringLength, NumericAttribute); if (CharacterAttribute) { BufferLength /= sizeof (SQLWCHAR); if (StringLength != NULL) { *StringLength = (SQLSMALLINT) (*StringLength) * sizeof (SQLWCHAR); } if (CharacterAttribute && StringLength) { bytes_to_wide_char (CharacterAttribute, *StringLength / 2, &wvalue, 0, NULL, NULL); if(wvalue != NULL) { (void)memcpy ((char *)CharacterAttribute, (const char *)wvalue, *StringLength); ((SQLWCHAR *)CharacterAttribute)[*StringLength / 2] = 0;
OGRDB2SelectLayer::OGRDB2SelectLayer( OGRDB2DataSource *poDSIn, OGRDB2Statement * poStmtIn ) { SQLCHAR szTableName[256]; SQLCHAR szSchemaName[256]; SQLSMALLINT nNameLength = 0; OGRDB2Layer *poBaseLayer = NULL; poDS = poDSIn; iNextShapeId = 0; nSRSId = -1; poFeatureDefn = NULL; m_poStmt = poStmtIn; pszBaseStatement = CPLStrdup( poStmtIn->GetCommand() ); CPLDebug("OGR_DB2SelectLayer::OGRDB2SelectLayer", "SQL: '%s'", pszBaseStatement); pszGeomColumn = NULL; /* get schema and table names for first column, column 1 */ SQLColAttribute(m_poStmt->GetStatement(), (SQLSMALLINT)(1), SQL_DESC_SCHEMA_NAME, szSchemaName, sizeof(szSchemaName), &nNameLength, NULL); /* The schema name is sometimes right padded with blanks */ /* Replace blanks with nulls to terminate string for sprintf below */ for (int i = 0; i < nNameLength; i++) { if (szSchemaName[i] == ' ') szSchemaName[i] = 0; }; SQLColAttribute(m_poStmt->GetStatement(), (SQLSMALLINT)(1), SQL_DESC_TABLE_NAME, szTableName, sizeof(szTableName), &nNameLength, NULL); CPLDebug("OGR_DB2SelectLayer::OGRDB2SelectLayer", "szSchemaName: '%s'; szTableName: '%s'", szSchemaName, szTableName); if (nNameLength > 0) { char szLayerName[512]; sprintf(szLayerName, "%s.%s",szSchemaName, szTableName); poBaseLayer = (OGRDB2Layer *) poDS->GetLayerByName((const char*) szLayerName); if (poBaseLayer != NULL) CPLDebug("OGR_DB2SelectLayer::OGRDB2SelectLayer", "base geom col: '%s'", poBaseLayer->GetGeometryColumn()); else CPLDebug("OGR_DB2SelectLayer::OGRDB2SelectLayer", "base layer not found"); } /* identify the geometry column */ for ( int iColumn = 0; iColumn < m_poStmt->GetColCount(); iColumn++ ) { if ( EQUAL(m_poStmt->GetColTypeName( iColumn ), "CLOB") || EQUAL(m_poStmt->GetColTypeName( iColumn ), "VARCHAR () FOR BIT DATA")) { if (poBaseLayer != NULL && EQUAL(poBaseLayer->GetGeometryColumn(), m_poStmt->GetColName(iColumn))) { pszGeomColumn = CPLStrdup(m_poStmt->GetColName(iColumn)); /* copy spatial reference */ if (!poSRS && poBaseLayer->GetSpatialRef()) poSRS = poBaseLayer->GetSpatialRef()->Clone(); nSRSId = poBaseLayer->GetSRSId(); break; } } } BuildFeatureDefn( "SELECT", m_poStmt ); if ( GetSpatialRef() && poFeatureDefn->GetGeomFieldCount() == 1) poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef( poSRS ); }
/****************************************************************************** * * * Function: zbx_db_vselect * * * * Purpose: execute a select statement * * * * Return value: data, NULL (on error) or (DB_RESULT)ZBX_DB_DOWN * * * ******************************************************************************/ DB_RESULT zbx_db_vselect(const char *fmt, va_list args) { char *sql = NULL; DB_RESULT result = NULL; double sec = 0; #if defined(HAVE_IBM_DB2) int i; SQLRETURN ret = SQL_SUCCESS; #elif defined(HAVE_ORACLE) sword err = OCI_SUCCESS; ub4 counter; #elif defined(HAVE_POSTGRESQL) char *error = NULL; #elif defined(HAVE_SQLITE3) int ret = FAIL; char *error = NULL; #endif if (0 != CONFIG_LOG_SLOW_QUERIES) sec = zbx_time(); sql = zbx_dvsprintf(sql, fmt, args); if (1 == txn_error) { zabbix_log(LOG_LEVEL_DEBUG, "ignoring query [txnlev:%d] [%s] within failed transaction", txn_level, sql); goto clean; } zabbix_log(LOG_LEVEL_DEBUG, "query [txnlev:%d] [%s]", txn_level, sql); #if defined(HAVE_IBM_DB2) result = zbx_malloc(result, sizeof(ZBX_IBM_DB2_RESULT)); memset(result, 0, sizeof(ZBX_IBM_DB2_RESULT)); /* allocate a statement handle */ if (SUCCEED != zbx_ibm_db2_success(ret = SQLAllocHandle(SQL_HANDLE_STMT, ibm_db2.hdbc, &result->hstmt))) goto error; /* directly execute the statement */ if (SUCCEED != zbx_ibm_db2_success(ret = SQLExecDirect(result->hstmt, (SQLCHAR *)sql, SQL_NTS))) goto error; /* identify the number of output columns */ if (SUCCEED != zbx_ibm_db2_success(ret = SQLNumResultCols(result->hstmt, &result->ncolumn))) goto error; if (0 == result->ncolumn) goto error; result->nalloc = 0; result->values = zbx_malloc(result->values, sizeof(char *) * result->ncolumn); result->values_cli = zbx_malloc(result->values_cli, sizeof(char *) * result->ncolumn); result->values_len = zbx_malloc(result->values_len, sizeof(SQLINTEGER) * result->ncolumn); for (i = 0; i < result->ncolumn; i++) { /* get the display size for a column */ if (SUCCEED != zbx_ibm_db2_success(ret = SQLColAttribute(result->hstmt, (SQLSMALLINT)(i + 1), SQL_DESC_DISPLAY_SIZE, NULL, 0, NULL, &result->values_len[i]))) { goto error; } result->values_len[i] += 1; /* '\0'; */ /* allocate memory to bind a column */ result->values_cli[i] = zbx_malloc(NULL, result->values_len[i]); result->nalloc++; /* bind columns to program variables, converting all types to CHAR */ if (SUCCEED != zbx_ibm_db2_success(ret = SQLBindCol(result->hstmt, (SQLSMALLINT)(i + 1), SQL_C_CHAR, result->values_cli[i], result->values_len[i], &result->values_len[i]))) { goto error; } } error: if (SUCCEED != zbx_ibm_db2_success(ret) || 0 == result->ncolumn) { zbx_ibm_db2_log_errors(SQL_HANDLE_DBC, ibm_db2.hdbc); zbx_ibm_db2_log_errors(SQL_HANDLE_STMT, result->hstmt); IBM_DB2free_result(result); result = (SQL_CD_TRUE == IBM_DB2server_status() ? NULL : (DB_RESULT)ZBX_DB_DOWN); } #elif defined(HAVE_MYSQL) if (NULL == conn) { zabbix_errlog(ERR_Z3003); result = NULL; } else { if (0 != mysql_query(conn, sql)) { zabbix_errlog(ERR_Z3005, mysql_errno(conn), mysql_error(conn), sql); switch (mysql_errno(conn)) { case CR_CONN_HOST_ERROR: case CR_SERVER_GONE_ERROR: case CR_CONNECTION_ERROR: case CR_SERVER_LOST: case ER_SERVER_SHUTDOWN: case ER_ACCESS_DENIED_ERROR: /* wrong user or password */ case ER_ILLEGAL_GRANT_FOR_TABLE: /* user without any privileges */ case ER_TABLEACCESS_DENIED_ERROR:/* user without some privilege */ case ER_UNKNOWN_ERROR: result = (DB_RESULT)ZBX_DB_DOWN; break; default: result = NULL; break; } } else result = mysql_store_result(conn); } #elif defined(HAVE_ORACLE) result = zbx_malloc(NULL, sizeof(ZBX_OCI_DB_RESULT)); memset(result, 0, sizeof(ZBX_OCI_DB_RESULT)); err = OCIHandleAlloc((dvoid *)oracle.envhp, (dvoid **)&result->stmthp, OCI_HTYPE_STMT, (size_t)0, (dvoid **)0); if (OCI_SUCCESS == err) { err = OCIStmtPrepare(result->stmthp, oracle.errhp, (text *)sql, (ub4)strlen((char *)sql), (ub4)OCI_NTV_SYNTAX, (ub4)OCI_DEFAULT); } if (OCI_SUCCESS == err) { err = OCIStmtExecute(oracle.svchp, result->stmthp, oracle.errhp, (ub4)0, (ub4)0, (CONST OCISnapshot *)NULL, (OCISnapshot *)NULL, OCI_COMMIT_ON_SUCCESS); } if (OCI_SUCCESS == err) { /* get the number of columns in the query */ err = OCIAttrGet((void *)result->stmthp, OCI_HTYPE_STMT, (void *)&result->ncolumn, (ub4 *)0, OCI_ATTR_PARAM_COUNT, oracle.errhp); } if (OCI_SUCCESS != err) goto error; assert(0 < result->ncolumn); result->values = zbx_malloc(NULL, result->ncolumn * sizeof(char *)); memset(result->values, 0, result->ncolumn * sizeof(char *)); for (counter = 1; OCI_SUCCESS == err && counter <= result->ncolumn; counter++) { OCIParam *parmdp = NULL; OCIDefine *defnp = NULL; ub4 char_semantics; ub2 col_width; /* request a parameter descriptor in the select-list */ err = OCIParamGet((void *)result->stmthp, OCI_HTYPE_STMT, oracle.errhp, (void **)&parmdp, (ub4)counter); if (OCI_SUCCESS == err) { /* retrieve the length semantics for the column */ char_semantics = 0; err = OCIAttrGet((void *)parmdp, (ub4)OCI_DTYPE_PARAM, (void *)&char_semantics, (ub4 *)0, (ub4)OCI_ATTR_CHAR_USED, (OCIError *)oracle.errhp); } if (OCI_SUCCESS == err) { col_width = 0; if (char_semantics) { /* retrieve the column width in characters */ err = OCIAttrGet((void *)parmdp, (ub4)OCI_DTYPE_PARAM, (void *)&col_width, (ub4 *)0, (ub4)OCI_ATTR_CHAR_SIZE, (OCIError *)oracle.errhp); } else { /* retrieve the column width in bytes */ err = OCIAttrGet((void *)parmdp, (ub4)OCI_DTYPE_PARAM, (void *)&col_width, (ub4 *)0, (ub4)OCI_ATTR_DATA_SIZE, (OCIError *)oracle.errhp); } } col_width++; result->values[counter - 1] = zbx_malloc(NULL, col_width); memset(result->values[counter - 1], 0, col_width); if (OCI_SUCCESS == err) { /* represent any data as characters */ err = OCIDefineByPos(result->stmthp, &defnp, oracle.errhp, counter, (dvoid *)result->values[counter - 1], col_width, SQLT_STR, (dvoid *)0, (ub2 *)0, (ub2 *)0, OCI_DEFAULT); } /* free cell descriptor */ OCIDescriptorFree(parmdp, OCI_DTYPE_PARAM); parmdp = NULL; } error: if (OCI_SUCCESS != err) { zabbix_errlog(ERR_Z3005, err, zbx_oci_error(err), sql); OCI_DBfree_result(result); result = (OCI_SERVER_NORMAL == OCI_DBserver_status() ? NULL : (DB_RESULT)ZBX_DB_DOWN); } #elif defined(HAVE_POSTGRESQL) result = zbx_malloc(NULL, sizeof(ZBX_PG_DB_RESULT)); result->pg_result = PQexec(conn, sql); result->values = NULL; result->cursor = 0; result->row_num = 0; if (NULL == result->pg_result) zabbix_errlog(ERR_Z3005, 0, "result is NULL", sql); if (PGRES_TUPLES_OK != PQresultStatus(result->pg_result)) { error = zbx_dsprintf(error, "%s:%s", PQresStatus(PQresultStatus(result->pg_result)), PQresultErrorMessage(result->pg_result)); zabbix_errlog(ERR_Z3005, 0, error, sql); zbx_free(error); PG_DBfree_result(result); result = (CONNECTION_OK == PQstatus(conn) ? NULL : (DB_RESULT)ZBX_DB_DOWN); } else /* init rownum */ result->row_num = PQntuples(result->pg_result); #elif defined(HAVE_SQLITE3) if (0 == txn_level && PHP_MUTEX_OK != php_sem_acquire(&sqlite_access)) { zabbix_log(LOG_LEVEL_CRIT, "ERROR: cannot create lock on SQLite3 database"); exit(FAIL); } result = zbx_malloc(NULL, sizeof(ZBX_SQ_DB_RESULT)); result->curow = 0; lbl_get_table: if (SQLITE_OK != (ret = sqlite3_get_table(conn,sql, &result->data, &result->nrow, &result->ncolumn, &error))) { if (SQLITE_BUSY == ret) goto lbl_get_table; zabbix_errlog(ERR_Z3005, 0, error, sql); sqlite3_free(error); SQ_DBfree_result(result); switch (ret) { case SQLITE_ERROR: /* SQL error or missing database; assuming SQL error, because if we are this far into execution, zbx_db_connect() was successful */ case SQLITE_NOMEM: /* a malloc() failed */ case SQLITE_MISMATCH: /* data type mismatch */ result = NULL; break; default: result = (DB_RESULT)ZBX_DB_DOWN; break; } } if (0 == txn_level) php_sem_release(&sqlite_access); #endif /* HAVE_SQLITE3 */ if (0 != CONFIG_LOG_SLOW_QUERIES) { sec = zbx_time() - sec; if (sec > (double)CONFIG_LOG_SLOW_QUERIES / 1000.0) zabbix_log(LOG_LEVEL_WARNING, "slow query: " ZBX_FS_DBL " sec, \"%s\"", sec, sql); } if (NULL == result && 0 < txn_level) { zabbix_log(LOG_LEVEL_DEBUG, "query [%s] failed, setting transaction as failed", sql); txn_error = 1; } clean: zbx_free(sql); return result; }
OGRMSSQLSpatialSelectLayer::OGRMSSQLSpatialSelectLayer( OGRMSSQLSpatialDataSource *poDSIn, CPLODBCStatement * poStmtIn ) { poDS = poDSIn; iNextShapeId = 0; nSRSId = 0; poFeatureDefn = nullptr; poStmt = poStmtIn; pszBaseStatement = CPLStrdup( poStmtIn->GetCommand() ); /* identify the geometry column */ pszGeomColumn = nullptr; int iImageCol = -1; for ( int iColumn = 0; iColumn < poStmt->GetColCount(); iColumn++ ) { if ( EQUAL(poStmt->GetColTypeName( iColumn ), "image") ) { SQLCHAR szTableName[256]; SQLSMALLINT nTableNameLength = 0; SQLColAttribute(poStmt->GetStatement(), (SQLSMALLINT)(iColumn + 1), SQL_DESC_TABLE_NAME, szTableName, sizeof(szTableName), &nTableNameLength, nullptr); if (nTableNameLength > 0) { OGRLayer *poBaseLayer = poDS->GetLayerByName((const char*)szTableName); if (poBaseLayer != nullptr && EQUAL(poBaseLayer->GetGeometryColumn(), poStmt->GetColName(iColumn))) { nGeomColumnType = MSSQLCOLTYPE_BINARY; pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn)); /* copy spatial reference */ if (!poSRS && poBaseLayer->GetSpatialRef()) poSRS = poBaseLayer->GetSpatialRef()->Clone(); break; } } else if (iImageCol == -1) iImageCol = iColumn; } else if ( EQUAL(poStmt->GetColTypeName( iColumn ), "geometry") ) { nGeomColumnType = MSSQLCOLTYPE_GEOMETRY; pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn)); break; } else if ( EQUAL(poStmt->GetColTypeName( iColumn ), "geography") ) { nGeomColumnType = MSSQLCOLTYPE_GEOGRAPHY; pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn)); break; } else if ( EQUAL(poStmt->GetColTypeName( iColumn ), "udt") ) { SQLCHAR szUDTTypeName[256]; SQLSMALLINT nUDTTypeNameLength = 0; SQLColAttribute(poStmt->GetStatement(), (SQLSMALLINT)(iColumn + 1), SQL_CA_SS_UDT_TYPE_NAME, szUDTTypeName, sizeof(szUDTTypeName), &nUDTTypeNameLength, nullptr); // For some reason on unixODBC, a UCS2 string is returned if ( EQUAL((char*)szUDTTypeName, "geometry") || (nUDTTypeNameLength == 16 && memcmp(szUDTTypeName, "g\0e\0o\0m\0e\0t\0r\0y", 16) == 0) ) { nGeomColumnType = MSSQLCOLTYPE_GEOMETRY; pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn)); } else if ( EQUAL((char*)szUDTTypeName, "geography") || (nUDTTypeNameLength == 18 && memcmp(szUDTTypeName, "g\0e\0o\0g\0r\0a\0p\0h\0y", 18) == 0) ) { nGeomColumnType = MSSQLCOLTYPE_GEOGRAPHY; pszGeomColumn = CPLStrdup(poStmt->GetColName(iColumn)); } break; } } if (pszGeomColumn == nullptr && iImageCol >= 0) { /* set the image col as geometry column as the last resort */ nGeomColumnType = MSSQLCOLTYPE_BINARY; pszGeomColumn = CPLStrdup(poStmt->GetColName(iImageCol)); } BuildFeatureDefn( "SELECT", poStmt ); if ( GetSpatialRef() && poFeatureDefn->GetGeomFieldCount() == 1) poFeatureDefn->GetGeomFieldDefn(0)->SetSpatialRef( poSRS ); }