首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言 ODBC 實戰:參數綁定與數據插入完整教程

     編輯:關於C語言

使用 ODBC API 在 C 中向 SQL Server 插入數據

ODBC (Open Database Connectivity) 是 C/C++ 訪問關係數據庫的標準接口。本文通過完整示例演示如何使用 SQLBindParameter 綁定參數、執行參數化 INSERT 語句,實現結構體數組到數據庫的高效寫入。

一、核心 API:SQLBindParameter 詳細解析

SQLRETURN SQLBindParameter(
    SQLHSTMT       StatementHandle,   // 語句句柄
    SQLUSMALLINT   ParameterNumber,   // 參數序號(從 1 開始,對應 SQL 中 ? 位置)
    SQLSMALLINT    InputOutputType,   // SQL_PARAM_INPUT / OUTPUT / INPUT_OUTPUT
    SQLSMALLINT    ValueType,         // C 數據類型標識(如 SQL_C_LONG, SQL_C_CHAR)
    SQLSMALLINT    ParameterType,     // SQL 數據類型標識(如 SQL_INTEGER, SQL_CHAR)
    SQLULEN        ColumnSize,        // 列大小(字符類型為最大長度)
    SQLSMALLINT    DecimalDigits,     // 小數位數(數值類型)
    SQLPOINTER     ParameterValuePtr, // 參數緩衝區地址(輸入參數需取地址 &)
    SQLLEN         BufferLength,      // 緩衝區字節長度
    SQLLEN *       StrLen_or_IndPtr   // 長度/指示器指針(SQL_NTS 表示以空字符結尾)
);

二、關鍵類型映射表(易錯點)

三、完整插入示例:員工信息批量入庫

#include <sql.h>
#include <sqlext.h>
#include <stdio.h>

typedef struct {
    long num;
    char name[21];
    char sex[11];
    long age;
    char shenfennum[21];
    char xueli[11];
    char mianmao[11];
    char mima[21];
    char quanxian[11];
    char born[21];
} Worker;

Worker gong[100]; // 假設已填充數據

void workertianjiashuju(int i) {
    SQLHENV henv; SQLHDBC hdbc; SQLHSTMT hstmt;
    SQLRETURN ret;
    SQLINTEGER cb = SQL_NTS; // 長度指示器

    // 1. 環境、連接、語句句柄分配
    SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
    SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
    SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);

    // 2. 連接數據庫(DSN=phonesql, 用戶=sa, 密碼=123456)
    ret = SQLConnect(hdbc, (SQLCHAR*)"phonesql", SQL_NTS,
                     (SQLCHAR*)"sa", SQL_NTS, (SQLCHAR*)"123456", SQL_NTS);
    if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
        printf("連接失敗\\n"); goto cleanup;
    }

    // 3. 準備參數化 SQL
    SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
    SQLCHAR *sql = (SQLCHAR*)"INSERT INTO worker VALUES (?,?,?,?,?,?,?,?,?,?)";
    SQLPrepare(hstmt, sql, SQL_NTS);

    // 4. 綁定 10 個參數(順序必須與建表一致!)
    SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &gong[i].num, 0, &cb);
    SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 20, 0, gong[i].name, 20, &cb);
    SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 10, 0, gong[i].sex, 10, &cb);
    SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &gong[i].age, 0, &cb);
    SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 20, 0, gong[i].shenfennum, 20, &cb);
    SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 10, 0, gong[i].xueli, 10, &cb);
    SQLBindParameter(hstmt, 7, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 10, 0, gong[i].mianmao, 10, &cb);
    SQLBindParameter(hstmt, 8, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 20, 0, gong[i].mima, 20, &cb);
    SQLBindParameter(hstmt, 9, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 10, 0, gong[i].quanxian, 10, &cb);
    SQLBindParameter(hstmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 20, 0, gong[i].born, 20, &cb);

    // 5. 執行插入
    ret = SQLExecute(hstmt);
    if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
        printf("第 %d 條插入成功\\n", i+1);
    else
        printf("插入失敗\\n");

    SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
cleanup:
    SQLDisconnect(hdbc);
    SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
    SQLFreeHandle(SQL_HANDLE_ENV, henv);
}

四、關鍵注意事項總結

  1. 參數序號從 1 開始,且必須與建表列順序、SQL 中 ? 位置一一對應。
  2. 整型參數必須取地址:&gong[i].num,字符數組名本身即地址。
  3. 字符緩衝區大小:BufferLength 應 ≥ 實際最大長度 + 1(留給 \0)。
  4. 錯誤處理:生產代碼中每個 ODBC 調用後應檢查返回值,失敗時調用 SQLError 獲取詳細信息。
  5. 事務控制:默認自動提交;批量插入建議關閉自動提交(SQLSetConnectAttr(..., SQL_AUTOCOMMIT_OFF)),循環綁定執行後統一 SQLEndTran(SQL_COMMIT)。

五、資源清理順序

語句句柄 → 連接句柄 → 環境句柄,嚴格按相反分配順序釋放,防止資源洩漏。

掌握 SQLBindParameter 的類型映射、參數序號對應、緩衝區管理,即可構建高效、安全的 C 語言數據庫應用。參數化查詢不僅防止 SQL 注入,還能讓數據庫複用執行計劃,大幅提升批量操作性能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
SQL 類型ODBC C 類型標識備註
INT / INTEGERSQL_C_LONG⚠️ 無 SQL_C_INT,必須用 LONG
VARCHAR(n)SQL_C_CHAR緩衝區大小 ≥ n+1,含結束符
CHAR(n)SQL_C_CHAR固定長度,不足補空格