This topic introduces how to build an application by using OceanBase Connector/ODBC and OceanBase Database. It also covers the use of the application for fundamental database operations, including table creation, data insertion, and data query.
Prerequisites
You have installed OceanBase Database and created an Oracle tenant. For more information about how to install OceanBase Database, see Deployment overview.
You have installed Visual Studio.
You have installed the OceanBase Connector/ODBC driver.
Note
You can download the installation package of OceanBase Connector/ODBC for Windows from OceanBase Download Center. To install OceanBase Connector/ODBC for Windows, follow the default instructions.
Procedure
Note
The steps outlined in this topic are for the Windows environment. If you are using a different operating system or compiler, the steps may vary slightly.
- Open the
c-oceanbase-odbcproject. - Configure the properties for the
c-oceanbase-odbcproject. - Obtain the connection information of OceanBase Database.
- Modify the database connection information in the
c-oceanbase-odbcproject. - Build the project.
- Run the application.
- Check the output.
Step 1: Open the c-oceanbase-odbc project
Start Visual Studio Community 2019.
Open an existing project.
In the start window of Visual Studio Community 2019, click Open a project or solution under Get started. Alternatively, click Continue without code in the lower right corner, and choose File > Open > Project/Solution in the menu bar of the page that appears.
Browse to the c-oceanbase-odbc folder, select the project file
c-oceanbase-odbc.slnorc-oceanbase-odbc.vcxproj, and click Open.
Step 2: Configure properties for the c-oceanbase-odbc project
Go to the property page of the project.
Right-click the selected project in Solution Explorer and choose Properties from the menu, or choose Project > Properties from the top menu bar, or use the shortcut key Alt + Enter.
Set the configuration manager.
Select Debug from the Configuration drop-down list.
Select x64 from the Platform drop-down list.
Set the character set.
Click the Advanced tab and find the Character Set field. Select Use Multi-Byte Character Set from the drop-down list.
Step 3: Obtain the connection information of OceanBase Database
Contact the deployment personnel or administrator of OceanBase Database to obtain the database connection string.
Here is an example:
obclient -hxxx.xxx.xxx.xxx -P2881 -usys@oracle001 -p******
where
-hspecifies the IP address for connecting to OceanBase Database. For connection through OceanBase Database Proxy (ODP), this parameter is the IP address of an ODP. For direct connection, this parameter is the IP address of an OBServer node.-Pspecifies the port for connecting to OceanBase Database. For connection through ODP, the default value is2883, which can be customized when ODP is deployed. For direct connection, the default value is2881, which can be customized when OceanBase Database is deployed.-uspecifies the tenant account. For connection through ODP, the tenant account can be in theusername@tenant name#cluster nameorcluster name:tenant name:usernameformat. For direct connection, the tenant account is in theusername@tenant nameformat.-pspecifies the account password.
For more information about connection strings, see Connect to an OceanBase tenant by using OBClient.
Step 4: Modify the database connection information in the c-oceanbase-odbc project
Modify the database connection information in the test_tbl1.cpp file based on the information obtained in Step 3: Obtain the connection information of OceanBase Database.
Here is an example:
char* mydriver = (char*)"Driver={OceanBase ODBC 2.0 Driver};Server=xxx.xxx.xxx.xxx;Port=2881;Database=sys;User=sys@oracle001;Password=******;Option=3;";
Step 5: Build the project
Choose Build > Build Solution. The output of the compiler and errors or warning messages if any are displayed during the build process.
Step 6: Run the application
Choose Debug > Start Debugging or choose Debug > Start Without Debugging to run the application.
Step 7: View the output
The output is displayed in the debug console. You can determine how to handle the output based on the design logic and code of the program.
Project code introduction
Click c-oceanbase-odbc to download the project code, which is a compressed file named c-oceanbase-odbc.zip.
After decompressing it, you will find a folder named c-oceanbase-odbc. The directory structure is as follows:
c-oceanbase-odbc
├─ c-oceanbase-odbc.sln
├─ c-oceanbase-odbc.vcxproj
├─ c-oceanbase-odbc.vcxproj.filters
├─ c-oceanbase-odbc.vcxproj.user
└─ test_tbl1.cpp
Here is a breakdown of the files and directories:
c-oceanbase-odbc.sln: the solution file in Visual Studio that manages one or more projects.c-oceanbase-odbc.vcxproj: the project file in Visual Studio that describes the structure and configuration of a C/C++ project.c-oceanbase-odbc.vcxproj.filters: the project filter file in Visual Studio that defines the directory structure and organization of files in the project.c-oceanbase-odbc.vcxproj.user: the file that stores user-specific project settings.test_tbl1.cpp: the source code file that defines a data table and implements data table operations.
Code in test_tbl1.cpp
The test_tbl1.cpp file defines and creates a data table named test_tbl1 and implements the operations to insert data into and query data from the table.
To configure the test_tbl1.cpp file, perform the following steps:
Reference header files.
Reference header files
stdio.h,assert.h,windows.h,sql.h, andsqlext.h.The sample code is as follows:
#include <stdio.h> #include <assert.h> #include <windows.h> #include <sql.h> #include <sqlext.h>Define the
odbc_print_errorfunction.This function is called to print error messages for ODBC-related errors that occur during the running process of the program. The steps are as follows:
- Set the function name to
odbc_print_error. Specify the parametersSQLSMALLINT HandleTypeandSQLHANDLE Handleto indicate the handle type and handle corresponding to an error message. - Define the variables that store error messages obtained from ODBC. The types and names of these variables are defined in the ODBC API.
- Call
SQLGetDiagRec()to get the last generated error message in ODBC. TheSQLState,NativeError, andSQLMessagearrays then store the relevant content of the error message. - Call the
fprintffunction to print the error message to the standard output stream.[%s] (%d) %s\nis the print format, which uses a formatted string similar to that in theprintffunction. Here,%sis used to print data of the string type,%dis used to print integer data, and\nrepresents a line break.SQLState,NativeError, andSQLMessagecorrespond to the three parameters in the formatted string, and provide the content of the error message to print.
The sample code is as follows:
static void odbc_print_error(SQLSMALLINT HandleType, SQLHANDLE Handle) { SQLCHAR SQLState[6]; SQLINTEGER NativeError; SQLCHAR SQLMessage[SQL_MAX_MESSAGE_LENGTH] = { 0 }; SQLSMALLINT TextLengthPtr; SQLGetDiagRec(HandleType, Handle, 1, SQLState, &NativeError, SQLMessage, SQL_MAX_MESSAGE_LENGTH, &TextLengthPtr); fprintf(stdout, "[%s] (%d) %s\n", SQLState, NativeError, SQLMessage); }- Set the function name to
Define the
ASSERT_CHECKfunction.This function is used to check and process the return value of an ODBC function call. It checks whether the return value of the ODBC API function has an error, and prints the error message and exits the program if there is an error. The steps are as follows:
- Set the macro name to
ASSERT_CHECK. Specify the parametersSQLSMALLINT HandleType,SQLHANDLE Handle, andSQLRETURN rcodeto indicate the ODBC handle type, the ODBC handle, and the return value of an ODBC API function call, respectively. - Use the
ifstatement to judge the return value of an ODBC API function. If the return value is not equal toSQL_SUCCESSorSQL_SUCCESS_WITH_INFO, an error occurs in the function call. - Call the
odbc_print_errorfunction to print the ODBC error message. - Call the
assertfunction during the running of the program. When an error occurs in an ODBC function call,assertaborts the program.
The sample code is as follows:
static void ASSERT_CHECK(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLRETURN rcode) { if (rcode != SQL_SUCCESS && rcode != SQL_SUCCESS_WITH_INFO) { odbc_print_error(HandleType, Handle); assert(0); } }- Set the macro name to
Define the
mainfunction.Define the entry function
mainfor the program and return an integer value. In themainfunction, write the code related to database connection and data operations.The sample code is as follows:
int main() { // Apply for an environment handle. // Set the version (an environment attribute) of ODBC. // Allocate a connection handle. // Connect to the data source. // Create a table. // Insert data. // Query data. // Release resource handles. }Define variables.
Define the
henvvariable, which is an ODBC environment handle object that manages ODBC connections and resource allocation.OutConnStrandOutConnStrLenstore the connection string and the string length respectively. These parameters are passed to theSQLDriverConnectfunction when the application connects to the database to obtain the return value and some other connection information.The sample code is as follows:
HENV henv; SQLCHAR OutConnStr[255]; SQLSMALLINT OutConnStrLen;Apply for an environment handle.
Call the
SQLAllocHandlefunction to allocate an ODBC environment handle, and call theASSERT_CHECKfunction to check the allocation result. The steps are as follows:Return a value of the
SQLRETURNtype after theSQLAllocHandlefunction is executed to indicate the execution result. Store this return value in thercodevariable. The parameters of theSQLAllocHandlefunction are as follows:SQL_HANDLE_ENV: the type of the handle to allocate. In this example, it is set toSQL_HANDLE_ENV, indicating that an environment handle is to be allocated.SQL_NULL_HANDLE: the parent handle. In this example, it is set toSQL_NULL_HANDLE, indicating that there is no parent handle.&henv: a pointer to the variable that stores the allocated handle. In this example, it is the pointer to thehenvvariable that stores the environment handle.
Call the
ASSERT_CHECKfunction to check thercodevalue returned by theSQLAllocHandlefunction. If thercodevalue is notSQL_SUCCESSorSQL_SUCCESS_WITH_INFO, handle allocation fails, and theASSERT_CHECKfunction calls theodbc_print_errorfunction to print the error message and uses theassertmacro to terminate the program.
The sample code is as follows:
SQLRETURN rcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv); ASSERT_CHECK(SQL_HANDLE_ENV, henv, rcode);Set the version (an environment attribute) of ODBC.
Call the
SQLSetEnvAttrfunction to set the environment attributes of ODBC to influence the behavior of the database connection and the driver. Call theASSERT_CHECKfunction to check the attribute setting result. The steps are as follows:Return a value of the
SQLRETURNtype after theSQLSetEnvAttrfunction is executed to indicate the execution result. Store this return value in thercodevariable. The parameters of theSQLSetEnvAttrfunction are as follows:henv: the ODBC environment handle that specifies the environment object for which the attribute is set.SQL_ATTR_ODBC_VERSION: the type of the environment attribute to be set. In this example, it is set toSQL_ATTR_ODBC_VERSION, indicating that the ODBC version is to be set.(void*)SQL_OV_ODBC3: a pointer to the attribute value. In this example, it is set toSQL_OV_ODBC3, indicating that the new ODBC version is ODBC V3.x.0: the length of the attribute value. In this example, the attribute value is an enumerated constant, and therefore the length is set to0.
Call the
ASSERT_CHECKfunction to check thercodevalue returned by theSQLSetEnvAttrfunction. If thercodevalue is notSQL_SUCCESSorSQL_SUCCESS_WITH_INFO, attribute setting fails, and theASSERT_CHECKfunction calls theodbc_print_errorfunction to print the error message and uses theassertmacro to terminate the program.
The sample code is as follows:
rcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0); ASSERT_CHECK(SQL_HANDLE_ENV, henv, rcode);Allocate a connection handle.
Call the
SQLAllocHandlefunction to allocate aODBCconnection handle, and call theASSERT_CHECKfunction to check the allocation result for successful handle allocation. The steps are as follows:Return a value of the
SQLRETURNtype after theSQLAllocHandlefunction is executed to indicate the execution result. Store this return value in thercodevariable. The parameters of theSQLAllocHandlefunction are as follows:SQL_HANDLE_DBC: the type of handle to be allocated, which is set toSQL_HANDLE_DBC, indicating a connection handle.henv: the allocated ODBC environment handle that acts as a parent handle to associate with the connection handle.&hdbc: the pointer to the variable that stores the allocated connection handle.
Call the
ASSERT_CHECKfunction to check thercodevalue returned by theSQLAllocHandlefunction. If thercodevalue is notSQL_SUCCESSorSQL_SUCCESS_WITH_INFO, handle allocation fails, and theASSERT_CHECKfunction calls theodbc_print_errorfunction to print the error message and uses theassertmacro to terminate the program.
The sample code is as follows:
SQLHDBC hdbc; rcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); ASSERT_CHECK(SQL_HANDLE_DBC, hdbc, rcode);Connect to the data source.
Call the
SQLDriverConnectfunction to connect to the specified ODBC data source. Call theASSERT_CHECKfunction to check the connection result. The steps are as follows:Define the connection string
mydriverthat describes the information required to connect to the database. The string contains the following parts:Driver={OceanBase ODBC 2.0 Driver}: specifies thatOceanBase ODBC 2.0 Driveris used as the driver.Server=your_ip: the IP address of the database server.Port=your_port: the port used to connect to the database.Database=your_schema: the name of the database.User=your_use: the username used to connect to the database.Password=your_password: the password used to connect to the database.Option=3: the connection option, which is set to3, indicating a TCP/IP connection.
Call the
SQLDriverConnectfunction to connect to the specified ODBC data source. Return a value of theSQLRETURNtype after the function is executed to indicate the execution result. Store this return value in thercodevariable. The parameters of the function are as follows:hdbc: the ODBC connection handle for establishing a connection with the data source.NULL: a reserved parameter, which is not used.mydriver: the connection string that contains all the information needed to connect to the database, such as the driver name, database IP address, port number, database name, username, and password.strlen((char*)mydriver) +1: the length of the connection string.OutConnStr: the buffer of theSQLCHARtype, which stores the connection string.255: the length of the buffer.&OutConnStrLen: the pointer to the variable that stores the actual length of the connection string.SQL_DRIVER_NOPROMPT: a connection flag that specifies not to display any prompt for a connection.
Call the
ASSERT_CHECKfunction to check thercodevalue returned by theSQLDriverConnectfunction. If thercodevalue is notSQL_SUCCESSorSQL_SUCCESS_WITH_INFO, the connection fails, and theASSERT_CHECKfunction calls theodbc_print_errorfunction to print the error message and uses theassertmacro to terminate the program.
The sample code is as follows:
char* mydriver = (char*)"Driver={OceanBase ODBC 2.0 Driver};Server=your_ip;Port=your_port;Database=your_schema;User=your_use;Password=your_password;Option=3;"; rcode = SQLDriverConnect(hdbc, NULL, (SQLCHAR*)mydriver, strlen((char*)mydriver) + 1, OutConnStr, 255, &OutConnStrLen, SQL_DRIVER_NOPROMPT); ASSERT_CHECK(SQL_HANDLE_DBC, hdbc, rcode);Parameters required to connect to OceanBase Database are described as follows:
your_ip: the IP address for connecting to OceanBase Database. For connection through ODP, this parameter is the IP address of an ODP. For direct connection, this parameter is the IP address of an OBServer node.your_port: the port for connecting to OceanBase Database. For connection through ODP, the default value is2883, which can be customized when ODP is deployed. For direct connection, the default value is2881, which can be customized when OceanBase Database is deployed.your_schema: the name of the schema to access.your_user: the tenant account. For connection through ODP, the tenant account can be in theusername@tenant name#cluster nameorcluster name:tenant name:usernameformat. For direct connection, the tenant account is in theusername@tenant nameformat.your_password: the account password.
Create a table.
Call the
SQLAllocHandlefunction to allocate an ODBC statement handle, and then call theSQLExecDirectfunction to execute an SQL statement to create a table. Use theASSERT_CHECKfunction to check the results of handle allocation and statement execution. Call theSQLFreeHandlefunction to release the statement handle to free resources. The steps are as follows:Declare an ODBC statement handle
stmt.Call the
SQLAllocHandlefunction to allocate an ODBC statement handle.Call the
ASSERT_CHECKfunction to check thercodevalue returned by theSQLAllocHandlefunction.Call the
SQLExecDirectfunction to execute an SQL statement. Here, theCREATE TABLEstatement is executed to create a table namedtest_tbl1.Call the
ASSERT_CHECKfunction to check thercodevalue returned by theSQLExecDirectfunction.Call the
SQLFreeHandlefunction to release the ODBC statement handle.
The sample code is as follows:
SQLHSTMT stmt; rcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &stmt); ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode); rcode = SQLExecDirect(stmt, (SQLCHAR*)"CREATE TABLE test_tbl1(id NUMBER PRIMARY KEY, name VARCHAR2(50),age NUMBER NOT NULL)", SQL_NTS); ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode); SQLFreeHandle(SQL_HANDLE_STMT, stmt);Insert data.
Call the
SQLAllocHandlefunction to allocate an ODBC statement handle, and then call theSQLExecDirectfunction to execute an SQL statement that inserts data into a database table. Use theASSERT_CHECKfunction to check the results of handle allocation and statement execution. Call theSQLFreeHandlefunction to release the statement handle to free resources. The steps are as follows:Call the
SQLAllocHandlefunction to allocate an ODBC statement handle.Call the
ASSERT_CHECKfunction to check thercodevalue returned by theSQLAllocHandlefunction.Call the
SQLExecDirectfunction to execute an SQL statement. Here, theINSERT INTOstatement is executed to insert three records into thetest_tbl1table.Call the
ASSERT_CHECKfunction to check thercodevalue returned by theSQLExecDirectfunction.Call the
SQLFreeHandlefunction to release the ODBC statement handle.
The sample code is as follows:
rcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &stmt); ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode); rcode = SQLExecDirect(stmt, (SQLCHAR*)"INSERT INTO test_tbl1 (id,name,age) VALUES (1,'Tom', 18),(2,'Jerry', 20),(3,'Bob', 22)", SQL_NTS); ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode); SQLFreeHandle(SQL_HANDLE_STMT, stmt);Query data.
Call the
SQLAllocHandlefunction to allocate an ODBC statement handle, and then call theSQLExecDirectfunction to execute an SQL statement that obtains the result set. Call theSQLBindColfunction to bind the columns of the result set to variables, and then call theSQLFetchfunction to get the result set row by row. In thewhileloop, print the data in the result set based on the value ofrcode. Call theSQLFreeHandlefunction to release the statement handle to free resources. The steps are as follows:Call the
SQLAllocHandlefunction to allocate an ODBC statement handle.Call the
ASSERT_CHECKfunction to check thercodevalue returned by theSQLAllocHandlefunction.Call the
SQLExecDirectfunction to execute an SQL statement. Here, theSELECTstatement is executed to retrieve all rows from thetest_tbl1table.Call the
ASSERT_CHECKfunction to check thercodevalue returned by theSQLExecDirectfunction.Declare the
resvariable of theSQLLENtype to store the result of the column binding operation.Declare two variables of the
SQLINTEGERtype:idandage, to store the values of the corresponding columns in the result set.Declare the
namearray of theSQLCHARtype to store the values of the corresponding column in the result set.Call the
SQLBindColfunction to bind the first column in the result set to the variableid.Call the
SQLBindColfunction to bind the second column in the result set to the arrayname.Call the
SQLBindColfunction to bind the third column in the result set to the variableage.Call the
SQLFetchfunction to get the rows in the result set and save data in the rows to the bound variables. Thewhileloop iterates until all rows are fetched.In the
whileloop, print the data of the corresponding row based on the value ofrcode. If thercodevalue isSQL_ERROR, print an error message.Call the
SQLFreeHandlefunction to release the ODBC statement handle.
The sample code is as follows:
rcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &stmt); ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode); rcode = SQLExecDirect(stmt, (SQLCHAR*)"SELECT * FROM test_tbl1", SQL_NTS); ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode); SQLLEN res = SQL_NTS; SQLINTEGER id, age; SQLCHAR name[255]; SQLBindCol(stmt, 1, SQL_C_SLONG, &id, sizeof(id), &res); SQLBindCol(stmt, 2, SQL_C_CHAR, name, sizeof(name), &res); SQLBindCol(stmt, 3, SQL_C_SLONG, &age, sizeof(age), &res); while ((rcode = SQLFetch(stmt)) != SQL_NO_DATA_FOUND) { if (rcode == SQL_ERROR) { printf("sql error!\n"); } else { printf("id:%d, name:%s, age:%ld\n", id, name, age); } } SQLFreeHandle(SQL_HANDLE_STMT, stmt);Disconnect from the database and release resource handles.
Close the database connection, and release the ODBC connection handle and environment handle to free resources. Call the
SQLDisconnectandSQLFreeHandlefunctions to correctly close the connection to the database and release relevant handles. Return0to indicate that the program execution is successful. The steps are as follows:Call the
SQLDisconnectfunction to disconnect from the database.Call the
SQLFreeHandlefunction to release the ODBC connection handle.Call the
SQLFreeHandlefunction to release the ODBC environment handle.Return
0to indicate that the program execution is successful.
The sample code is as follows:
SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); SQLFreeHandle(SQL_HANDLE_ENV, henv); return 0;
Complete code examples
#include <stdio.h>
#include <assert.h>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
static void odbc_print_error(SQLSMALLINT HandleType, SQLHANDLE Handle)
{
SQLCHAR SQLState[6];
SQLINTEGER NativeError;
SQLCHAR SQLMessage[SQL_MAX_MESSAGE_LENGTH] = { 0 };
SQLSMALLINT TextLengthPtr;
SQLGetDiagRec(HandleType, Handle, 1, SQLState, &NativeError, SQLMessage, SQL_MAX_MESSAGE_LENGTH, &TextLengthPtr);
fprintf(stdout, "[%s] (%d) %s\n", SQLState, NativeError, SQLMessage);
}
static void ASSERT_CHECK(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLRETURN rcode)
{
if (rcode != SQL_SUCCESS && rcode != SQL_SUCCESS_WITH_INFO) {
odbc_print_error(HandleType, Handle);
assert(0);
}
}
int main()
{
HENV henv;
SQLCHAR OutConnStr[255];
SQLSMALLINT OutConnStrLen;
SQLRETURN rcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
ASSERT_CHECK(SQL_HANDLE_ENV, henv, rcode);
rcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
ASSERT_CHECK(SQL_HANDLE_ENV, henv, rcode);
SQLHDBC hdbc;
rcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
ASSERT_CHECK(SQL_HANDLE_DBC, hdbc, rcode);
char* mydriver = (char*)"Driver={OceanBase ODBC 2.0 Driver};Server=your_ip;Port=your_port;Database=your_schema;User=your_use;Password=your_password;Option=3;";
rcode = SQLDriverConnect(hdbc, NULL, (SQLCHAR*)mydriver, strlen((char*)mydriver) + 1, OutConnStr, 255, &OutConnStrLen, SQL_DRIVER_NOPROMPT);
ASSERT_CHECK(SQL_HANDLE_DBC, hdbc, rcode);
SQLHSTMT stmt;
rcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &stmt);
ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode);
rcode = SQLExecDirect(stmt, (SQLCHAR*)"CREATE TABLE test_tbl1(id NUMBER PRIMARY KEY, name VARCHAR2(50),age NUMBER NOT NULL)", SQL_NTS);
ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
rcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &stmt);
ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode);
rcode = SQLExecDirect(stmt, (SQLCHAR*)"INSERT INTO test_tbl1 (id,name,age) VALUES (1,'Tom', 18),(2,'Jerry', 20),(3,'Bob', 22)", SQL_NTS);
ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode);
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
rcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &stmt);
ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode);
rcode = SQLExecDirect(stmt, (SQLCHAR*)"SELECT * FROM test_tbl1", SQL_NTS);
ASSERT_CHECK(SQL_HANDLE_STMT, stmt, rcode);
SQLLEN res = SQL_NTS;
SQLINTEGER id, age;
SQLCHAR name[255];
SQLBindCol(stmt, 1, SQL_C_SLONG, &id, sizeof(id), &res);
SQLBindCol(stmt, 2, SQL_C_CHAR, name, sizeof(name), &res);
SQLBindCol(stmt, 3, SQL_C_SLONG, &age, sizeof(age), &res);
while ((rcode = SQLFetch(stmt)) != SQL_NO_DATA_FOUND)
{
if (rcode == SQL_ERROR) {
printf("sql error!\n");
}
else {
printf("id:%d, name:%s, age:%ld\n", id, name, age);
}
}
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
SQLDisconnect(hdbc);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
return 0;
}
References
For more information about how to connect to OceanBase Database, see Overview of connection methods.
For more information about OceanBase Connector/ODBC, see OceanBase Connector/ODBC.
Download the c-oceanbase-odbc sample project