#include "StdAfx.h" #include "CellExecSql.h" #include "IvrFlow.h" #include "FlowDataProvider.h" #include "DBInterface.h" #include #include #include "OtlConn.h" using namespace std; IMPLEMENT_CELL_AUTOCREATE(CCellExecSql, CELL_NAME_SQL) CCellExecSql::CCellExecSql(void) { m_IsSaveRs = 0; m_SuccessPos = 0; m_FailPos = 0; m_Sql = ""; m_Connect = ""; } CCellExecSql::CCellExecSql(CCellExecSql & cellExeSql) : CCellBase(cellExeSql) { m_IsSaveRs = cellExeSql.m_IsSaveRs; m_Connect = cellExeSql.m_Connect; m_SuccessPos = cellExeSql.m_SuccessPos; m_FailPos = cellExeSql.m_FailPos; m_Sql = cellExeSql.m_Sql; } CCellExecSql::~CCellExecSql(void) { } /***************************************************************** **【函数名称】 Operate **【函数功能】 节点执行函数 **【参数】 **【返回值】 下一个节点编号 ****************************************************************/ int CCellExecSql::operate(void) { if (m_pIvrFlow == NULL) return CELL_OP_ERROR; CString Info; _getCellInfo(Info); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}: 开始执行[%s]"), Info); CString SQL; // 替换SQL语句中的变量 if (!m_pIvrFlow->replaceVar(m_Sql, SQL)) { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错, 替换SQL语句中变量失败, SQL = %s"), Info, SQL); return m_FailPos; } // 初始化数据库 CString strErrMessage = _T(""); DataSet& RS = m_pIvrFlow->recordSet(); RS.RemoveAll(); int nRet = CELL_OP_ERROR; // 执行的返回值 boost::timer t; // 2022-05-30 计算sql执行时间 auto pOtlDB = new COtlConn(); std::string strConn = m_Connect.GetBuffer(0); m_Connect.ReleaseBuffer(); // 解密 判断是否是密文 if (m_Connect.Find("Provider=SQLOLEDB.1") <= -1 && m_Connect.Find("DRIVER") <= -1) { auto mingwen = Crypto::aes_decrypt_ecb_base64(strConn, (std::uint8_t*)"GHYU80DV3465QSFG", 16); m_Connect.Format("%s", mingwen.c_str()); } // 连接数据库 if (m_Connect.Find("Provider=SQLOLEDB.1") > -1 || m_Connect.Find("DRIVER") > -1) { m_Connect.Replace("Provider=SQLOLEDB.1", "DRIVER={SQL Server}"); m_Connect.Replace("Data Source", "Server"); m_Connect.Replace("User ID", "UID"); m_Connect.Replace("Password", "PWD"); m_Connect.Replace("Initial Catalog", "Database"); } // 数据源连接方式 dsn/用户名@密码 DSN=middle; UID=root; PWD=800100; if (pOtlDB->ConnectDataBase(m_Connect, strErrMessage)) { // 执行SQL 语句 if (pOtlDB->GetRecordSet(SQL, strErrMessage, m_IsSaveRs)) { nRet = m_SuccessPos; if (m_IsSaveRs) { auto it = pOtlDB->GetAllValues(strErrMessage); if (it.second) { ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}: 执行[%s]时间[%lf]结束, SQL = %s, 数据库中有记录"), Info, t.elapsed(), SQL); if (!it.first.empty()) { auto row = it.first.front(); for (auto cloVal : row) { RS.AddTail(cloVal); } } else { auto nField = pOtlDB->GetFields(); for (auto i = 0; i < nField; ++i) { RS.AddTail(""); } } } else { // 空结果集 ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}: 执行[%s]时间[%lf]结束, SQL = %s, 数据库中无记录"), Info, t.elapsed(), m_Sql); nRet = m_FailPos; } } else { // 不需要结果 ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_NORMAL, _T("{Cell}: 执行[%s]时间[%lf]结束, SQL = %s"), Info, t.elapsed(), m_Sql); //nRet = m_FailPos; 2024-01-11 按照sql是否成功 } } else { // SQL执行失败 ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]失败, SQL = %s, Error = %s"), Info, m_Sql, strErrMessage); nRet = m_FailPos; /*2022-03-30 如果执行失败暂停1秒再次执行*/ bool bIsSuccess = false; if (SQL.Find("update") >= 0) { Sleep(1000); strErrMessage = ""; auto bResult = pOtlDB->GetRecordSet(SQL, strErrMessage, m_IsSaveRs); bIsSuccess = bResult; ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 重新执行[%s]%s, SQL = %s, Error = %s"), Info, bResult ? "成功" : "失败", m_Sql, strErrMessage); } // SQL 执行失败时,推送到钉钉 if (!bIsSuccess) { GetDingDing()->PushFailSQL(SQL.GetBuffer(0), strErrMessage.GetBuffer(0)); SQL.ReleaseBuffer(); strErrMessage.ReleaseBuffer(); } else { nRet = m_SuccessPos; } } } else { // sql连接失败 ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_WARNING, _T("{Cell}: 执行[%s]出错, 连接数据库失败, Error = %s"), Info, strErrMessage); nRet = m_FailPos; } // 2023-03-30 普通指针申请之后要手动释放内存 if (pOtlDB != nullptr) { delete pOtlDB; pOtlDB = nullptr; } // 返回执行结果 return nRet; } /***************************************************************** **【函数名称】 copy **【函数功能】 拷贝自身 **【参数】 **【返回值】 拷贝副本 ****************************************************************/ CCellBase * CCellExecSql::copy(void) { CCellBase *pCellBase = new CCellExecSql(*this); return pCellBase; } /***************************************************************** **【函数名称】 fillData **【函数功能】 节点解析,填充数据 **【参数】 Provider:数据提供器 **【返回值】 成功true,失败false ****************************************************************/ bool CCellExecSql::fillData(IFlowDataProvider& Provider) { CString Data; do { if (!Provider.getData(CELL_ATTRIBUTE_POS, Data)) { Data = _T("节点号"); break; } else { sscanf_s(Data, _T("%d"), &m_Pos); if (m_Pos < 1) { Data = _T("节点号"); break; } } if (!Provider.getData(CELL_ATTRIBUTE_CONN_STR, m_Connect)) { Data = _T("连接字符串"); break; } if (!Provider.getData(CELL_ATTRIBUTE_SQL_STR, m_Sql)) { Data = _T("SQL语句"); break; } if (!Provider.getData(CELL_ATTRIBUTE_SAVE_FLAG, Data)) { Data = _T("保存标志"); break; } else { if (Data == DATA_BOOL_YES) m_IsSaveRs = true; else m_IsSaveRs = false; } if (!Provider.getData(CELL_ATTRIBUTE_SUCCESS_POS, Data)) { Data = _T("成功跳转节点"); break; } else { sscanf_s(Data, _T("%d"), &m_SuccessPos); if (m_SuccessPos < 0) { Data = _T("成功跳转节点"); break; } } if (!Provider.getData(CELL_ATTRIBUTE_FAIL_POS, Data)) { Data = _T("失败跳转节点"); break; } else { sscanf_s(Data, _T("%d"), &m_FailPos); if (m_FailPos < 0) { Data = _T("失败跳转节点"); break; } } Provider.getData(CELL_ATTRIBUTE_NOTE, m_Note); return true; } while (false); ILogger::getInstance().log(LOG_CLASS_BUSI, LOG_LEVEL_ERROR, _T("{Cell}: 节点[%s]解析失败, '%s'错误"), CELL_NAME_SQL, Data); return false; }