#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
#include <sqltypes.h>
#include <sql.h>
#include <sqlext.h>
#include <ctime>
#include <iomanip>
#include <thread>
int previousRowCount = 0;
std::string getTimePrefix() {
std::time_t current_time;
std::time(¤t_time);
std::tm current_time_info;
localtime_s(¤t_time_info, ¤t_time);
char timeBuffer[22];
int ret = strftime(timeBuffer, sizeof(timeBuffer), "[%Y-%m-%d %T]", ¤t_time_info);
return std::string(timeBuffer) + " ";
}
int executeSQLQuery(SQLHDBC dbc, const std::string& query) {
SQLHSTMT stmt;
SQLRETURN ret;
SQLCHAR outstr[4096];
SQLSMALLINT outstrlen;
int rowCount = 0;
SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
ret = SQLExecDirectA(stmt, (SQLCHAR*)query.c_str(), SQL_NTS);
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
SQLGetDiagRecA(SQL_HANDLE_STMT, stmt, 1, NULL, NULL, outstr, sizeof(outstr), &outstrlen);
std::cerr << getTimePrefix() << "执行 SQL 查询时出错:" << outstr << std::endl;
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
return -1;
}
SQLSMALLINT numCols;
SQLNumResultCols(stmt, &numCols);
while (SQLFetch(stmt) == SQL_SUCCESS) {
rowCount++;
if (rowCount > previousRowCount) {
std::cout << getTimePrefix() << "发现新增数据:";
for (int i = 1; i <= numCols; ++i) {
SQLCHAR columnName[256];
SQLCHAR columnData[256];
SQLLEN indicator;
ret = SQLDescribeColA(stmt, i, columnName, sizeof(columnName), NULL, NULL, NULL, NULL, NULL);
if (ret == SQL_SUCCESS) {
ret = SQLGetData(stmt, i, SQL_C_CHAR, columnData, sizeof(columnData), &indicator);
if (ret == SQL_SUCCESS) {
std::cout << (i > 1 ? ", " : "") << (char*)columnName << ": " << (char*)columnData;
}
}
}
std::cout << std::endl;
}
}
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
return rowCount;
}
void performDetection(SQLHDBC dbc, const std::string& query) {
int currentRowCount = executeSQLQuery(dbc, query);
if (currentRowCount > previousRowCount) {
std::cout << getTimePrefix() << "发现新增行数:" << currentRowCount - previousRowCount << std::endl;
Beep(1000, 500);
Beep(2000, 500);
Beep(3000, 500);
Beep(4000, 500);
}
else {
std::cout << getTimePrefix() << "查询到的行数:" << currentRowCount << std::endl;
}
previousRowCount = currentRowCount;
}
int main() {
std::ifstream file("conn.txt");
if (!file.is_open()) {
std::cerr << "无法打开文件 conn.txt" << std::endl;
return 1;
}
std::string connectionString;
std::getline(file, connectionString);
file.close();
if (connectionString.empty()) {
std::cerr << "连接字符串为空" << std::endl;
return 1;
}
SQLHENV env;
SQLHDBC dbc;
SQLRETURN ret;
ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
ret = SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
ret = SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
ret = SQLDriverConnectA(dbc, NULL, (SQLCHAR*)connectionString.c_str(), connectionString.size(), NULL, 0, NULL, SQL_DRIVER_COMPLETE);
if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
SQLCHAR outstr[4096];
SQLSMALLINT outstrlen;
SQLGetDiagRecA(SQL_HANDLE_DBC, dbc, 1, NULL, NULL, outstr, sizeof(outstr), &outstrlen);
std::cerr << getTimePrefix() << "连接到数据库时出错:" << outstr << std::endl;
return 1;
}
std::string query = "SELECT * FROM myserver.dbo.alarmevent";
performDetection(dbc, query);
std::cout << "\n";
std::cout << "\t _ _ _ _ _ _ __\n";
std::cout << "\t| | | | / \\ | \\ | | |/ /\n";
std::cout << "\t| |_| | / _ \\ | \\| | ' /\n";
std::cout << "\t| _ |/ ___ \\| |\\ | . \\\n";
std::cout << "\t|_| |_/_/ \\_\\_| \\_|_|\\_\\\n";
std::cout << "\n";
while (true) {
std::time_t current_time;
std::time(¤t_time);
std::tm current_time_info;
localtime_s(¤t_time_info, ¤t_time);
if (current_time_info.tm_min % 5 == 0) {
performDetection(dbc, query);
Sleep(1000*60);
}
Sleep(1000);
}
SQLDisconnect(dbc);
SQLFreeHandle(SQL_HANDLE_DBC, dbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);
return 0;
}