CNAS取数仪器端升级
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

530 行
22KB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Data;
  6. using MySql.Data.MySqlClient;
  7. using CnasSynchronousCommon;
  8. using CnasSynchrousModel;
  9. using System.Reflection;
  10. namespace CnasSynchronusDAL
  11. {
  12. public class MySQLDAL
  13. {
  14. public void CreateConnectString(string strIP,string strPort,string strName, string strUser, string strPwd)
  15. {
  16. MySQLHelper.InitConnectionString(strIP,strPort,strName,strUser,strPwd);
  17. }
  18. //获取所有表单名称
  19. public DataTable GetTableNames(string strName)
  20. {
  21. DataTable dt = new DataTable();
  22. string strSql = string.Format("SELECT table_name as TABNAME FROM information_schema.TABLES WHERE table_schema='{0}'", strName);
  23. try
  24. {
  25. dt = MySQLHelper.ExecuteDataSet(strSql).Tables[0];
  26. }
  27. catch (Exception ex)
  28. {
  29. AppLog.Error(ex.Message);
  30. }
  31. return dt;
  32. }
  33. /// <summary>
  34. /// 获取某表的表结构
  35. /// </summary>
  36. /// <param name="strTableName"></param>
  37. /// <returns></returns>
  38. public DataTable GetTableStruct(string strTableName,string strViewName,string strViewSql)
  39. {
  40. DataTable dt = new DataTable();
  41. if (strTableName.Length <= 0) return dt;
  42. string strSql = "";
  43. if (strViewName == strTableName && string.IsNullOrWhiteSpace(strViewName))
  44. strSql = strViewSql + " where 0=1";
  45. else
  46. strSql = string.Format("SELECT * FROM {0} Where 0=1", strTableName);
  47. try
  48. {
  49. dt = MySQLHelper.ExecuteDataSet(strSql).Tables[0];
  50. }
  51. catch (Exception ex)
  52. {
  53. AppLog.Error(ex.Message);
  54. }
  55. return dt;
  56. }
  57. /// <summary>
  58. /// 获取某表的表结构和类型长度
  59. /// </summary>
  60. /// <param name="strTableName"></param>
  61. /// <returns></returns>
  62. public DataTable GetTableTypeAndLenth(string strTableName)
  63. {
  64. DataTable dt = new DataTable();
  65. string strSql = string.Format("select COLUMN_NAME AS 'ColumnName',IS_NULLABLE AS 'IsNullable',DATA_TYPE AS 'DataType',CHARACTER_MAXIMUM_LENGTH AS 'CharMaxLenth',CHARACTER_OCTET_LENGTH AS 'CharOcterLenth',NUMERIC_PRECISION AS 'NumericPrecision',NUMERIC_SCALE AS 'NumericScale' FROM information_schema.COLUMNS WHERE TABLE_NAME LIKE '{0}'", strTableName);
  66. try
  67. {
  68. dt = MySQLHelper.ExecuteDataSet(strSql).Tables[0];
  69. }
  70. catch (Exception ex)
  71. {
  72. AppLog.Error(ex.Message);
  73. }
  74. return dt;
  75. }
  76. /// <summary>
  77. /// 逐行批量插入数据
  78. /// </summary>
  79. /// <param name="dt"></param>
  80. /// <returns></returns>
  81. public int InsertCnasData(DataTable dt, List<SyncParamasInfo> syncParamasInfos, List<CnasConditionMapValue> lstFixedValue,string strInsumentColumn)
  82. {
  83. int iReturn = 0;
  84. if (dt.Rows.Count <= 0) return 0;
  85. try
  86. {
  87. //获取唯一健组(关键字段)
  88. var query = from p in syncParamasInfos
  89. where p.IfPrimaryKey == true
  90. select new
  91. {
  92. p.TargetField
  93. };
  94. List<string> lstKeyColumns = new List<string>();
  95. foreach (var item in query)
  96. {
  97. lstKeyColumns.Add(item.TargetField);
  98. }
  99. //构建SQL语句
  100. string strSql_part1 = "";
  101. string strSql_part2 = "";
  102. List<string> lstColumnName = new List<string>();
  103. foreach (var item in syncParamasInfos)
  104. {
  105. if (!lstColumnName.Contains(item.TargetField.ToLower()))
  106. {
  107. strSql_part1 += item.TargetField + ",";
  108. strSql_part2 += string.Format("@{0},", item.TargetField.ToLower());
  109. lstColumnName.Add(item.TargetField.ToLower());
  110. }
  111. }
  112. //如果映射列中不包含固定列,则需要将这些列添加到SQL语句中
  113. if (lstFixedValue != null)
  114. {
  115. foreach (var cnasfield in lstFixedValue)
  116. {
  117. if (cnasfield.TableName != syncParamasInfos[0].TargetTable) continue;
  118. if (!lstColumnName.Contains(cnasfield.ColumnName.ToLower()))
  119. {
  120. strSql_part1 += cnasfield.ColumnName + ",";
  121. strSql_part2 += string.Format("@{0},", cnasfield.ColumnName.ToLower());
  122. lstColumnName.Add(cnasfield.ColumnName.ToLower());
  123. }
  124. }
  125. }
  126. //增加仪器编号数据
  127. if (!string.IsNullOrWhiteSpace(strInsumentColumn) && !lstColumnName.Contains(strInsumentColumn.ToLower()))
  128. {
  129. strSql_part1 += strInsumentColumn + ",";
  130. strSql_part2 += string.Format("@{0},", strInsumentColumn);
  131. lstColumnName.Add(strInsumentColumn.ToLower());
  132. }
  133. string strInsertSql = string.Format("insert into {0}({1}) values({2})", syncParamasInfos[0].TargetTable, strSql_part1.Substring(0, strSql_part1.Length - 1), strSql_part2.Substring(0, strSql_part2.Length - 1));
  134. string strUpdateSql = "";
  135. DataTable dtSelect = new DataTable();
  136. foreach (DataRow dr in dt.Rows)
  137. {
  138. //插入参数值
  139. MySqlParameter[] parameters = new MySqlParameter[lstColumnName.Count];
  140. int i = 0;
  141. foreach (var item in lstColumnName)
  142. {
  143. parameters[i++] = new MySqlParameter(item, dr[item]);
  144. }
  145. //插入时发现已经在数据库中存在该值,则进行更新操作
  146. if (ExistSingleCnasData(lstKeyColumns, syncParamasInfos[0].TargetTable, dr,ref dtSelect))
  147. {
  148. if (dtSelect.Rows.Count == 1)
  149. {
  150. //比对获取的数据跟准备更新的数据是否一样
  151. if (!CompareObjectOperation.DataRowCompare(dtSelect.Rows[0], dr, lstColumnName))
  152. {
  153. //构造更新语句
  154. strUpdateSql = GetUpdateSql(lstColumnName, lstKeyColumns, syncParamasInfos[0].TargetTable, dr);
  155. //执行UpdateSql语句
  156. iReturn += MySQLHelper.ExecuteNonQuery(strUpdateSql, parameters);
  157. }
  158. else
  159. {
  160. iReturn = -2;
  161. AppLog.Info("更新时发现在数据库中相同关键字段数据一致。");
  162. }
  163. }
  164. else
  165. {
  166. AppLog.Error("更新时发现在数据库中多条相同关键字段数据,请重新配置关键字段。");
  167. }
  168. }
  169. else
  170. {
  171. //执行InsertSQL语句
  172. iReturn += MySQLHelper.ExecuteNonQuery(strInsertSql, parameters);
  173. }
  174. }
  175. }
  176. catch (Exception ex)
  177. {
  178. if (!LinkCnasTest())
  179. {
  180. iReturn = -1; //用于表示插入时无法正常数据库连接问题
  181. }
  182. //此处添加错误日志
  183. AppLog.Error(ex.Message);
  184. }
  185. return iReturn;
  186. }
  187. /// <summary>
  188. /// 拼接Update语句
  189. /// </summary>
  190. /// <param name="lstColumnName"></param>
  191. /// <param name="lstPrimaryColumn"></param>
  192. /// <param name="dr"></param>
  193. private string GetUpdateSql(List<string> lstColumnName,List<string> lstPrimaryColumn, string strTableName,DataRow dr)
  194. {
  195. //构造关键字段条件
  196. string strsql_partial = "";
  197. foreach (var item in lstPrimaryColumn)
  198. {
  199. if (dr.Table.Columns.Contains(item.ToString()))
  200. if (dr[item.ToString()].ToString() != "")
  201. strsql_partial += $"{item.ToString()}='{dr[item.ToString()].ToString()}' and ";
  202. else
  203. strsql_partial += $"({item.ToString()}='{dr[item.ToString()].ToString()}' or {item.ToString()} is null) and ";
  204. }
  205. //构造Update语句
  206. string strUpdateSql = "";
  207. string strsql_partial2 = "";
  208. foreach (var item in lstColumnName)
  209. {
  210. strsql_partial2 += $"{item}=@{item},";
  211. }
  212. if(strsql_partial.Length > 3&&strsql_partial2.Length>0)
  213. strUpdateSql = $"update {strTableName} set {strsql_partial2.Substring(0,strsql_partial2.Length-1)} where {strsql_partial.Substring(0, strsql_partial.Length - 4)}";
  214. return strUpdateSql;
  215. }
  216. internal bool CheckMacMessage(string strMac)
  217. {
  218. bool bIfChecked = false;
  219. string strSql = string.Format("select * FROM macaddress WHERE MAC_ADDRESS='{0}'", strMac);
  220. try
  221. {
  222. DataTable dt = MySQLHelper.ExecuteDataSet(strSql).Tables[0];
  223. if (dt != null && dt.Rows.Count > 0)
  224. {
  225. bIfChecked = true;
  226. }
  227. }
  228. catch (Exception ex)
  229. {
  230. AppLog.Error(ex.Message);
  231. }
  232. return bIfChecked;
  233. }
  234. private bool ExistSingleCnasData(List<string> lstPrimaryColumn, string strTableName, DataRow dr,ref DataTable dtSelect)
  235. {
  236. bool bIfHaveValue = false;
  237. string strsql_partial = "";
  238. string strSql = "";
  239. foreach (var item in lstPrimaryColumn)
  240. {
  241. if (dr.Table.Columns.Contains(item.ToString()))
  242. if (dr[item.ToString()].ToString() != "")
  243. strsql_partial += $"{item.ToString()}='{dr[item.ToString()].ToString()}' and ";
  244. else
  245. strsql_partial += $"({item.ToString()}='{dr[item.ToString()].ToString()}' or {item.ToString()} is null) and ";
  246. }
  247. if (strsql_partial.Length > 3)
  248. strSql = $"select * from {strTableName} where {strsql_partial.Substring(0, strsql_partial.Length - 4)}";
  249. if (strSql != "")
  250. {
  251. DataTable dt = MySQLHelper.ExecuteDataTable(strSql,new MySqlParameter[] { });
  252. if (dt != null && dt.Rows.Count > 0)
  253. {
  254. bIfHaveValue = true;
  255. dtSelect = dt;
  256. AppLog.Info($"插入时存在重复数据:{strSql}");
  257. }
  258. }
  259. return bIfHaveValue;
  260. }
  261. internal DataTable GetLoginNameByPwd(string strUserName, string strPwd)
  262. {
  263. DataTable dt = new DataTable();
  264. string strSql = string.Format("select * FROM user WHERE userid='{0}' and password='{1}'", strUserName,strPwd);
  265. try
  266. {
  267. dt = MySQLHelper.ExecuteDataSet(strSql).Tables[0];
  268. }
  269. catch (Exception ex)
  270. {
  271. AppLog.Error(ex.Message);
  272. }
  273. return dt;
  274. }
  275. public bool LinkCnasTest()
  276. {
  277. return MySQLHelper.TestConnectMySql();
  278. }
  279. /// <summary>
  280. /// 获得表中该列中最大时间
  281. /// </summary>
  282. /// <param name="dt"></param>
  283. /// <returns></returns>
  284. public string GetMaxTimeByTableName(string strTableName,string strDateColumn, string strInstrumentColumn, string strInstrumentValue)
  285. {
  286. string strReturnTime = "";
  287. //因为数据库用varchar存储日期字段,从而格式不固定,需要使用多种格式读取
  288. try
  289. {
  290. #region 旧的获取时间方法
  291. ////string strSql_1 = string.Format("SELECT max(STR_TO_DATE({0},'%Y-%m-%d %H:%i:%s')) FROM {1} ", strDateColumn, strTableName);
  292. ////string strSql_2 = string.Format("SELECT max(STR_TO_DATE({0},'%Y/%m/%d %H:%i:%s')) FROM {1} ", strDateColumn, strTableName);
  293. //string strSql_2 = string.Format("SELECT max(Convert({0},datetime)) FROM {1} ", strDateColumn, strTableName);
  294. ////string strDateTime_1 = GetMaxTimeByTableName(strSql_1);
  295. //string strDateTime_2= GetMaxTimeByTableName(strSql_2);
  296. ////AppLog.Info($"读取到最大的时间(1):表-{strTableName},列-{strDateColumn},值-{strDateTime_1}");
  297. //AppLog.Info($"读取到最大的时间(2):表-{strTableName},列-{strDateColumn},值-{strDateTime_2}");
  298. //List<DateTime> lstTime = new List<DateTime>();
  299. ////DateTime dateTime_1 = DateTime.Now;
  300. //DateTime dateTime_2 = DateTime.Now;
  301. ////if (DateTime.TryParse(strDateTime_1, out dateTime_1))
  302. ////{
  303. //// lstTime.Add(dateTime_1);
  304. ////}
  305. //if (DateTime.TryParse(strDateTime_2, out dateTime_2))
  306. //{
  307. // if (!lstTime.Contains(dateTime_2))
  308. // lstTime.Add(dateTime_2);
  309. //}
  310. //if (lstTime.Count > 0)
  311. //{
  312. // strReturnTime = lstTime.Max<DateTime>().ToString();
  313. // AppLog.Info($"返回最大的时间(3):表-{strTableName},列-{strDateColumn},值-{strReturnTime}");
  314. //}
  315. # endregion
  316. string strSql = string.Format("SELECT Convert(max(Convert({0},datetime)) using utf8) FROM {1}", strDateColumn, strTableName, strInstrumentColumn, strInstrumentValue);
  317. if(!string.IsNullOrWhiteSpace(strInstrumentColumn)&& !string.IsNullOrWhiteSpace(strInstrumentValue))
  318. strSql+= string.Format(" where {0}='{1}'", strInstrumentColumn,strInstrumentValue);
  319. string strDateTime = GetMaxTimeByTableName(strSql);
  320. DateTime dateTime = DateTime.Now;
  321. if (DateTime.TryParse(strDateTime, out dateTime))
  322. {
  323. strReturnTime = strDateTime;
  324. }
  325. }
  326. catch (Exception ex)
  327. {
  328. if (!LinkCnasTest())
  329. {
  330. strReturnTime = "1899-1-1"; //用于表示插入时无法正常数据库连接问题
  331. }
  332. AppLog.Error(ex.Message);
  333. }
  334. return strReturnTime;
  335. }
  336. internal DataTable GetDataByDateColumn(string strDBName,string strViewName,string strViewSql,string strTableName, string strDateColumn, string strDate)
  337. {
  338. DataTable dtReturn = new DataTable();
  339. try
  340. {
  341. string strSql = "";
  342. if (strViewName == strTableName && string.IsNullOrWhiteSpace(strViewName))
  343. strSql = strViewSql + $" where {strDateColumn} >convert( '{strDate}',datetime)";
  344. else
  345. strSql = $"select * from {strDBName}.{strTableName} where {strDateColumn} >convert( '{strDate}',datetime)";
  346. DataTable dt = MySQLHelper.ExecuteDataSet(strSql).Tables[0];
  347. Dictionary<string, string> dictFiled = GetSpecialOperaField(strDBName,strTableName);
  348. if (dictFiled.Count > 0)
  349. dtReturn = DateAndTimeTypeOpera(dt, dictFiled);
  350. else
  351. dtReturn = dt;
  352. }
  353. catch (Exception ex)
  354. {
  355. //发生异常,写入日志
  356. AppLog.Error(ex.Message);
  357. throw ex;
  358. }
  359. return dtReturn;
  360. }
  361. internal Dictionary<string, DataTable> GetAllTableNameAndStructure(string strDBName)
  362. {
  363. Dictionary<string, DataTable> dictTables = new Dictionary<string, DataTable>();
  364. try
  365. {
  366. DataTable TablesName = GetTableNames(strDBName);//得到所有表
  367. foreach (DataRow dr in TablesName.Rows)
  368. {
  369. string strTableName = dr[0].ToString();
  370. dictTables.Add(strTableName.ToUpper(), GetTableStruct(strTableName,"",""));
  371. }
  372. }
  373. catch (Exception ex)
  374. {
  375. //发生异常,写入日志
  376. AppLog.Error(ex.Message);
  377. //throw ex;
  378. }
  379. return dictTables;
  380. }
  381. public string GetMaxTimeByTableName(string strSql)
  382. {
  383. string strDateTime = "";
  384. try
  385. {
  386. DataTable dt = MySQLHelper.ExecuteDataSet(strSql).Tables[0];
  387. AppLog.Info($"执行语句获得最晚时间:{strSql}");
  388. if (dt != null && dt.Rows.Count == 1)
  389. {
  390. strDateTime = dt.Rows[0][0].ToString();
  391. AppLog.Info($"执行语句获得最晚时间:行数-({dt.Rows.Count}),列数-({dt.Columns.Count}),值-({strDateTime})");
  392. }
  393. }
  394. catch (Exception ex)
  395. {
  396. if (!LinkCnasTest())
  397. {
  398. strDateTime = "1899-1-1"; //用于表示插入时无法正常数据库连接问题
  399. }
  400. AppLog.Error(ex.Message);
  401. }
  402. return strDateTime;
  403. }
  404. /// <summary>
  405. /// 获取所有数据字段,然后记录其中是否存在需要特殊处理的字段
  406. /// </summary>
  407. /// <returns></returns>
  408. private static Dictionary<string, string> GetSpecialOperaField(string strDBName,string strTableName)
  409. {
  410. Dictionary<string, string> DictFiled = new Dictionary<string, string>();
  411. DataTable dt = new DataTable();
  412. try
  413. {
  414. string sql = string.Format("SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='{0}' and table_schema='{1}'", strTableName, strDBName); //查询字符串
  415. dt = MySQLHelper.ExecuteDataSet(sql).Tables[0];
  416. foreach (DataRow dr in dt.Rows)
  417. {
  418. if (dr["data_type"].ToString().ToLower() == "date" || dr["data_type"].ToString().ToLower() == "time")
  419. {
  420. DictFiled.Add(dr["column_name"].ToString(), dr["data_type"].ToString());
  421. }
  422. }
  423. }
  424. catch (Exception ex)
  425. {
  426. //发生异常,写入日志
  427. AppLog.Error(ex.Message);
  428. }
  429. return DictFiled;
  430. }
  431. /// <summary>
  432. /// 获取数据时,单独处理某些(Date和Time)类型数据,并把数据类型转换为字符串类型
  433. /// </summary>
  434. private static DataTable DateAndTimeTypeOpera(DataTable dt, Dictionary<string, string> DictSpecialField)
  435. {
  436. DataTable dtNewFormat = new DataTable();
  437. //添加列
  438. foreach (DataColumn dc in dt.Columns)
  439. {
  440. if (DictSpecialField.ContainsKey(dc.ColumnName))
  441. {
  442. string strDateType = DictSpecialField[dc.ColumnName];
  443. switch (strDateType.ToUpper())
  444. {
  445. case "DATE":
  446. case "TIME":
  447. dtNewFormat.Columns.Add(dc.ColumnName, typeof(string)); //使用字符串来存储该字段,而不是采用它的数据库格式(C#无法区分Date, Time,DateTime,前两种格式会自动补充数据,导致数据的不准确)
  448. break;
  449. default:
  450. dtNewFormat.Columns.Add(dc.ColumnName, dc.DataType);
  451. break;
  452. }
  453. }
  454. else
  455. {
  456. dtNewFormat.Columns.Add(dc.ColumnName, dc.DataType);
  457. }
  458. }
  459. //添加数据行
  460. foreach (DataRow dr in dt.Rows)
  461. {
  462. DataRow drNewRow = dtNewFormat.NewRow();
  463. foreach (DataColumn dc in dtNewFormat.Columns)
  464. {
  465. if (!DictSpecialField.ContainsKey(dc.ColumnName))
  466. drNewRow[dc.ColumnName] = dr[dc.ColumnName];
  467. else
  468. {
  469. switch (DictSpecialField[dc.ColumnName].ToUpper())
  470. {
  471. case "DATE":
  472. if (dr[dc.ColumnName] != null && dr[dc.ColumnName].ToString() != "")
  473. drNewRow[dc.ColumnName] = Convert.ToDateTime(dr[dc.ColumnName]).ToString("yyyy-MM-dd");
  474. break;
  475. case "TIME":
  476. if (dr[dc.ColumnName] != null && dr[dc.ColumnName].ToString() != "")
  477. drNewRow[dc.ColumnName] = Convert.ToDateTime(dr[dc.ColumnName].ToString()).ToString("HH:mm:ss");
  478. break;
  479. default:
  480. drNewRow[dc.ColumnName] = dr[dc.ColumnName];
  481. break;
  482. }
  483. }
  484. }
  485. dtNewFormat.Rows.Add(drNewRow);
  486. }
  487. //返回数据
  488. return dtNewFormat;
  489. }
  490. }
  491. }