#ODBC用户程序说明

ODBC基本调用流程请参考官方文档基本 ODBC 应用程序 - ODBC API Reference | Microsoft Docs (opens new window)

ODBC官方Demo见C/C++ ODBC 应用程序访问 SQL 数据库 - ODBC Driver for SQL Server | Microsoft Docs (opens new window)

# YashanDB ODBC驱动示例

本示例以visual studio作为工具进行编译和运行:

1.创建一个新项目:

2.创建OdbcExample.c文件:

3.编写用户程序代码,如下:(YashanDB_Default_DSN为安装说明中已配置的ODBC数据源名称)

#include <windows.h>

#include <sql.h>
#include <sqlext.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

void HandleDiagnosticRecord(SQLHANDLE hHandle, SQLSMALLINT hType, RETCODE RetCode)
{
    SQLSMALLINT iRec = 0;
    SQLINTEGER  iError;
    CHAR        wszMessage[1000];
    CHAR        wszState[SQL_SQLSTATE_SIZE + 1];

    if (RetCode == SQL_INVALID_HANDLE) {
        printf("Invalid handle!\n");
        return;
    }

    while (SQLGetDiagRec(hType, hHandle, ++iRec, wszState, &iError, wszMessage,
        (SQLSMALLINT)(sizeof(wszMessage) / sizeof(CHAR)), (SQLSMALLINT*)NULL) == SQL_SUCCESS) {
        // Hide data truncated..
        if (strcmp(wszState, "01004")) {
            printf("[%5.5s] %s (%d)\n", wszState, wszMessage, iError);
        }
    }
}

#define ODBC_TEST_CALL(yocFunc)                                             \
    do {                                                                    \
        SQLRETURN r = yocFunc;                                              \
        if (r == SQL_ERROR || r == SQL_NO_DATA_FOUND) {                     \
            HandleDiagnosticRecord(gTestHandles.hStmt, SQL_HANDLE_STMT, r); \
            return r;                                                       \
        }                                                                   \
    } while (0)

#define CI_DATA_SOURCE "YashanDB_Default_DSN"

typedef struct {
    SQLHENV  hEnv;
    SQLHDBC  hDbc;
    SQLHSTMT hStmt;
} SQLHandles;

SQLHandles gTestHandles;

int main(int argc, char** argv)
{
    if (SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &gTestHandles.hEnv) != SQL_SUCCESS) {
        printf("Unable to allocate an environment handle\n");
        return SQL_ERROR;
    }

    SQLSetEnvAttr(gTestHandles.hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);

    if (SQLAllocHandle(SQL_HANDLE_DBC, gTestHandles.hEnv, &gTestHandles.hDbc) != SQL_SUCCESS) {
        printf("Unable to allocate an connection handle\n");
        return SQL_ERROR;
    }

    if (SQLConnect(gTestHandles.hDbc, CI_DATA_SOURCE, SQL_NTS, NULL, SQL_NTS, NULL, SQL_NTS) != SQL_SUCCESS) {
        printf("Unable to connect\n");
        return SQL_ERROR;
    }

    //或者可以使用有图形化界面的SQLDriverConnect代替SQLConnect连接
    // SQLCHAR driverConnStr[100] = "DSN=";
    // strcat(driverConnStr, CI_DATA_SOURCE);
    // strcat(driverConnStr, ";");

    // if (SQLDriverConnect(gTestHandles.hDbc, NULL, driverConnStr, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_PROMPT) !=
    //     SQL_SUCCESS) {
    //     printf("Unable to Dirver connect\n");
    //     return SQL_ERROR;
    // }

    if (SQLAllocHandle(SQL_HANDLE_STMT, gTestHandles.hDbc, &gTestHandles.hStmt) != SQL_SUCCESS) {
        printf("Unable to allocate an connection handle\n");
        return SQL_ERROR;
    }

    // 简单的绑定入参和取数据
    // 以产品信息表product为例,遵循以下示例将获得product_no等于11001的product_name
    ODBC_TEST_CALL(SQLPrepare(gTestHandles.hStmt, "select product_name from product where product_no = ?", SQL_NTS));
    SQLINTEGER productNo = 11001;
    SQLLEN     indicator = sizeof(SQLINTEGER);
    ODBC_TEST_CALL(SQLBindParameter(gTestHandles.hStmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &productNo,
        indicator, &indicator));
    ODBC_TEST_CALL(SQLExecute(gTestHandles.hStmt));
    SQLCHAR productName[100];
    ODBC_TEST_CALL(SQLBindCol(gTestHandles.hStmt, 1, SQL_C_CHAR, &productName, 100, NULL));
    ODBC_TEST_CALL(SQLFetch(gTestHandles.hStmt));
    ODBC_TEST_CALL(SQLCloseCursor(gTestHandles.hStmt));  //此步骤为必须步骤,否则之后调用其他函数会返回SQL_ERROR
    printf("product_no %d's product_name is \"%s\"\n", productNo, productName);

    // 释放资源
    if (SQLFreeHandle(SQL_HANDLE_STMT, gTestHandles.hStmt) != SQL_SUCCESS) {
        printf("Unable to free stmt\n");
        return SQL_ERROR;
    }

    if (SQLDisconnect(gTestHandles.hDbc) != SQL_SUCCESS) {
        printf("Unable to disconnect\n");
        return SQL_ERROR;
    }

    if (SQLFreeHandle(SQL_HANDLE_DBC, gTestHandles.hDbc) != SQL_SUCCESS) {
        printf("Unable to free conn\n");
        return SQL_ERROR;
    }

    if (SQLFreeHandle(SQL_HANDLE_ENV, gTestHandles.hEnv) != SQL_SUCCESS) {
        printf("Unable to free env\n");
        return SQL_ERROR;
    }

    return SQL_SUCCESS;
}
Copied!

4.生成解决方案。(请注意visual studio的解决方案配置中平台须为x64,调试属性中的字符集须为使用多字节字符集)

5.执行解决方案,输出如下:

pdf-btn 下载文档
copy-btn 复制链接