You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
3.8 KiB
156 lines
3.8 KiB
// OracleDB.cpp
|
|
#include "OracleDB.h"
|
|
#include <cstring>
|
|
#include <cstdlib>
|
|
#include <cstdio>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
OracleDB::OracleDB() : conn(nullptr), stmt(nullptr), isConnected(false) {}
|
|
|
|
OracleDB::~OracleDB() {
|
|
disconnect();
|
|
}
|
|
|
|
bool OracleDB::connect(const char* user, const char* pwd, const char* host) {
|
|
if (isConnected) return true;
|
|
|
|
|
|
|
|
// 创建连接
|
|
conn = OCI_ConnectionCreate(host, user, pwd, OCI_SESSION_DEFAULT);
|
|
if (!conn) {
|
|
printf("连接数据库失败: %s\n", OCI_GetLastError() ? OCI_ErrorGetString(OCI_GetLastError()) : "Unknown error");
|
|
return false;
|
|
}
|
|
|
|
stmt = OCI_StatementCreate(conn);
|
|
if (!stmt) {
|
|
printf("创建语句对象失败\n");
|
|
OCI_ConnectionFree(conn);
|
|
conn = nullptr;
|
|
return false;
|
|
}
|
|
|
|
isConnected = true;
|
|
printf("数据库连接成功\n");
|
|
return true;
|
|
}
|
|
|
|
void OracleDB::disconnect() {
|
|
if (stmt) {
|
|
OCI_StatementFree(stmt);
|
|
stmt = nullptr;
|
|
}
|
|
if (conn) {
|
|
OCI_ConnectionFree(conn);
|
|
conn = nullptr;
|
|
}
|
|
isConnected = false;
|
|
}
|
|
|
|
int OracleDB::executeQuery(
|
|
const char* sql,
|
|
int* outputColumn,
|
|
int* outputRow,
|
|
char**** outputValue
|
|
) {
|
|
// 初始化输出参数
|
|
*outputColumn = 0;
|
|
*outputRow = 0;
|
|
*outputValue = nullptr;
|
|
|
|
printf("初始化输出参数完成\n");
|
|
|
|
if (!isConnected || !stmt) {
|
|
printf("数据库未连接或语句对象无效\n");
|
|
return -1;
|
|
}
|
|
|
|
printf("检查数据库连接成功\n");
|
|
|
|
if (!OCI_ExecuteStmt(stmt, sql)) {
|
|
printf("SQL执行失败: %s\n", OCI_ErrorGetString(OCI_GetLastError()));
|
|
return -1;
|
|
}
|
|
|
|
printf("SQL语句执行成功\n");
|
|
|
|
OCI_Resultset* rs = OCI_GetResultset(stmt);
|
|
if (!rs) {
|
|
printf("无法获取结果集\n");
|
|
return -1;
|
|
}
|
|
|
|
printf("获取结果集成功\n");
|
|
|
|
int colCount = (int)OCI_GetColumnCount(rs);
|
|
printf("列数: %d\n", colCount);
|
|
|
|
// 使用 vector 临时存储所有数据
|
|
std::vector<std::vector<std::string>> tempData;
|
|
|
|
int rowCount = 0;
|
|
while (OCI_FetchNext(rs)) {
|
|
std::vector<std::string> row;
|
|
for (int j = 0; j < colCount; j++) {
|
|
const char* val = OCI_GetString(rs, j + 1);
|
|
if (val) {
|
|
row.push_back(std::string(val));
|
|
}
|
|
else {
|
|
row.push_back("NULL");
|
|
}
|
|
}
|
|
tempData.push_back(row);
|
|
rowCount++;
|
|
}
|
|
|
|
printf("遍历结果集完成,行数: %d\n", rowCount);
|
|
|
|
// 分配 outputValue
|
|
char*** result = (char***)calloc(rowCount, sizeof(char**));
|
|
if (!result) {
|
|
printf("内存分配失败\n");
|
|
return -1;
|
|
}
|
|
printf("为结果分配内存完成\n");
|
|
|
|
for (int i = 0; i < rowCount; i++) {
|
|
result[i] = (char**)calloc(colCount, sizeof(char*));
|
|
if (!result[i]) {
|
|
// 清理已分配内存
|
|
for (int j = 0; j < i; j++) {
|
|
for (int k = 0; k < colCount; k++) {
|
|
free(result[j][k]);
|
|
}
|
|
free(result[j]);
|
|
}
|
|
free(result);
|
|
printf("内存分配失败\n");
|
|
return -1;
|
|
}
|
|
printf("为第 %d 行分配内存完成\n", i + 1);
|
|
|
|
for (int j = 0; j < colCount; j++) {
|
|
const std::string& val = tempData[i][j];
|
|
result[i][j] = (char*)malloc(val.length() + 1);
|
|
if (result[i][j]) {
|
|
strcpy(result[i][j], val.c_str());
|
|
printf("复制第 %d 行第 %d 列的数据: %s\n", i + 1, j + 1, result[i][j]);
|
|
}
|
|
else {
|
|
result[i][j] = nullptr;
|
|
printf("内存分配失败,设置第 %d 行第 %d 列为空指针\n", i + 1, j + 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 设置输出参数
|
|
*outputColumn = colCount;
|
|
*outputRow = rowCount;
|
|
*outputValue = result;
|
|
|
|
printf("executeQuery 成功返回\n");
|
|
return 0; // 成功
|
|
} |