21xrx.com
2024-12-27 06:13:55 Friday
登录
文章检索 我的文章 写文章
如何在C++中调用SQL Server存储过程?
2023-06-27 22:01:16 深夜i     --     --
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语句调用存储过程,并获取执行结果。如果遇到问题可以参考以上代码,或查阅相关文档进行学习。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复