21xrx.com
2025-06-30 05:21:18 Monday
文章检索 我的文章 写文章
如何在C++中调用SQL Server存储过程?
2023-06-27 22:01:16 深夜i     29     0
C++ SQL Server 存储过程 调用

在C++开发中,使用SQL Server存储过程可以提高程序执行效率,并且可以减少对数据库的频繁访问。但是,如何在C++中调用SQL Server存储过程呢?本文将为您详细介绍。

一、连接SQL Server数据库

首先,我们需要在C++程序中连接SQL Server数据库,这可以使用ODBC(Open Database Connectivity)实现。可以使用ODBC连接数据库的原因在于,ODBC是一个标准的API,支持多种数据库,包括SQL Server、MySQL等。连接SQL Server数据库的代码示例如下:

#include <sqltypes.h>
#include <sql.h>
#include <sqlext.h>
#include <string>
using namespace std;
// 定义连接句柄
SQLHENV env;
SQLHDBC dbc;
// 连接数据库
SQLRETURN connect() {
  // 创建环境句柄
  SQLRETURN retcode;
  retcode = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO)
    cout << "环境句柄创建失败" << endl;
    return retcode;
  
  // 设置ODBC版本及行为
  retcode = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
    SQLFreeHandle(SQL_HANDLE_ENV, env);
    cout << "ODBC版本设置失败" << endl;
    return retcode;
  }
  // 分配数据库连接句柄
  SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
  // 连接数据库
  std::string driver = "DRIVER={SQL Server Native Client 11.0};SERVER=127.0.0.1;UID=sa;PWD=123456;DATABASE=test;";
  char* connstr = new char[driver.length() + 1];
  strcpy_s(connstr, driver.length() + 1, driver.c_str());
  retcode = SQLDriverConnect(dbc, NULL, (SQLCHAR*)connstr, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
    SQLFreeHandle(SQL_HANDLE_DBC, dbc);
    SQLFreeHandle(SQL_HANDLE_ENV, env);
    delete[] connstr;
    cout << "连接数据库失败" << endl;
    return retcode;
  }
  delete[] connstr;
  return retcode;
}

上面的代码创建了一个连接句柄env和一个数据库连接句柄dbc,然后通过SQLAllocHandle函数分配连接句柄env和数据库连接句柄dbc,最后使用SQLDriverConnect函数连接数据库,其中的连接字符串可以根据具体情况进行修改。

二、调用存储过程

连接数据库成功后,我们可以使用SQL语句调用存储过程,代码示例如下:

// 调用存储过程
SQLRETURN call_proc() {
  // 准备调用存储过程的SQL语句
  std::string sqlstr = "{CALL my_proc(?,?)}";
  SQLCHAR* sql = new SQLCHAR[sqlstr.length() + 1];
  strcpy_s((char*)sql, sqlstr.length() + 1, sqlstr.c_str());
  // 定义参数
  SQLCHAR* inparam1 = new SQLCHAR[10];
  strcpy_s((char*)inparam1, 10, "hello");
  SQLCHAR* outparam2 = new SQLCHAR[11];
  SQLLEN outparam2len;
  // 准备执行存储过程的语句
  SQLHSTMT stmt;
  SQLRETURN retcode;
  retcode = SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
    delete[] sql;
    delete[] inparam1;
    delete[] outparam2;
    cout << "分配语句句柄失败" << endl;
    return retcode;
  }
  // 绑定输入参数
  retcode = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 5, 0, inparam1, 0, NULL);
  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
    delete[] sql;
    delete[] inparam1;
    delete[] outparam2;
    cout << "绑定输入参数失败" << endl;
    return retcode;
  }
  // 绑定输出参数
  retcode = SQLBindParameter(stmt, 2, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, 11, 0, outparam2, 0, &outparam2len);
  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
    delete[] sql;
    delete[] inparam1;
    delete[] outparam2;
    cout << "绑定输出参数失败" << endl;
    return retcode;
  }
  // 执行存储过程的语句
  retcode = SQLExecDirect(stmt, sql, SQL_NTS);
  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
    delete[] sql;
    delete[] inparam1;
    delete[] outparam2;
    cout << "调用存储过程失败" << endl;
    return retcode;
  }
  // 获取输出参数
  SQLFetch(stmt);
  if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
    SQLFreeHandle(SQL_HANDLE_STMT, stmt);
    delete[] sql;
    delete[] inparam1;
    delete[] outparam2;
    cout << "获取输出参数失败" << endl;
    return retcode;
  }
  cout << "调用存储过程成功,输出:" << outparam2 << endl;
  SQLFreeHandle(SQL_HANDLE_STMT, stmt);
  delete[] sql;
  delete[] inparam1;
  delete[] outparam2;
  return retcode;
}

上面的代码准备了两个参数inparam1、outparam2,其中inparam1为输入参数,outparam2为输出参数,使用SQLBindParameter函数进行参数绑定,然后使用SQLExecDirect函数执行存储过程的语句,最后使用SQLFetch函数获取输出参数。

总结

以上就是在C++中调用SQL Server存储过程的方法,通过ODBC连接数据库,使用SQL语句调用存储过程,并获取执行结果。如果遇到问题可以参考以上代码,或查阅相关文档进行学习。

  
  

评论区