C# 调用 Oracle 是如此尴尬

>System.Data.OracleClient.dll —— .Net 自带的 已经 过时作废。

>要链接 Oracle 服务器,必须在 本机安装 Oracle 客户端 —— 而 SQLServer 不需要安装客户端。

win32_11gR2_client.zip(652M)

win64_11gR2_client.zip(587M)

>Oracle.DataAccess.dll—— Oracle 官方 提供的.Net 程序集【在安装目录 ODP.NET 中】。

Oracle.DataAccess.dll  严格区分 x32、x64 —— 程序集 不是 AnyCPU。

x32 客户端 只包括 x32 的 Oracle.DataAccess.dll。

x64 客户端 只包括 x64 的 Oracle.DataAccess.dll。

发布程序的时候,就很容易在这个地方 出现问题。

>Oracle.ManagedDataAccess.dll —— Oracle 官方 提供的.Net  程序集

支持 AnyCPU

不需要安装 600M 的客户端

Oracle.ManagedDataAccess —— 你值得拥有。

>Oracle.DataAccess.dll  和  Oracle.ManagedDataAccess.dll  用法完全一样。

支持的 SQL脚本语法一样。

SQL 脚本 不能以 分号 结尾。

一样的:这也不支持,那也不支持。

C# 调用 Oracle 语法限制

>Oracle 不支持 自增主键 —— 自增主键 需要使用 触发器。

>Oracle 表名,字段名 不能超过30个字符。

>脚本 参数化,    关键符为 : —— SQLServer 关键符为 @

>脚本 名称区域, 关键符为 "表名"."字段名" —— SQLServer 关键符为 [表名].[字段名]

警告:脚本中 不建议 将 数据库名、表名、字段名 用 引号括起来 —— 后果很严重。

>支持 多条 修改语句 同时执行:

  1. BEGIN
  2.  
  3. UPDATE TB_Test SET Name='INK';
  4.  
  5. DELETE TB_Test WHERE Name='INK';
  6.  
  7. INSERT INTO TB_Test(Name) VALUES('INK');
  8.  
  9. END;

>不支持 多条 查询语句,得到 DataSet —— 支持 单一查询得到 DataSet。

>支持 ExecuteScalar —— 但是 执行脚本 必须是 单条脚本。

>不支持 插入&查询 自增列—— SQLServer 支持 INSERT INTO…. SELECT@@IDENTITY

警告:即使使用 触发器 实现 自增ID,以下语法也 无法执行

  1. BEGIN
  2.  
  3. INSERT INTO TB_Test(Name) VALUES('INK'); --先执行 插入
  4.  
  5. SELECT MAX(ID) FROMTB_Test; --再执行 查询 最大ID
  6.  
  7. END

C# 调用 Oracle 的死结 在于:不支持 多条 非影响SQL脚本同时执行。

有鉴于此,自己随手写了一个OracleHelper.cs

>之前 Oracle 脚本, 自然是 支持的。

>多条 Oracle 脚本,用 ; 分割 —— 即能支持 多条SQL脚本。

>避开了 SQLServer 迁移 Oracle 过程中,出现的脚本不兼容。

>多条SQL脚本将自动开启 数据库事务,确保 绝对正确。

>支持 多条SELECT返回 多DataTable的 DataSet。

>支持 插入&查询自增列(触发器实现的 自增列)

Oracle 全托管程序集 Oracle.ManagedDataAccess.dll 

>不再需要安装 600M 的客户端,只需要 单纯引用程序集 就行。

>Oracle.ManagedDataAccess.dll  只是简化了 安装部署,支持 AnyCPU。

>测试通过,但是 功能和 Oracle.DataAccess.dll 功能一样:

我这次死定了 

>近来 公司的项目 SQLServer  要 改写 Oracle。

>但是 很多 SQLServer 的 语法 移植到 Oracle 很纠结,如果 多条SQL 都转换成 存储过程 —— 这工作量 太大,而且 存储过程数目都会 报表。

>为了 让 SQLServer 语法 兼容到 Oracle  才在工作中 花了 两小时 写了这个 OracleHelper.cs

>我只是一个 Oracle 的 采购,我只是 看了 http://www.cnblogs.com/dusmos/p/4451456.html 这篇文章之后,出于 探讨学习 的态度 发出来的 —— 文章也只是用的 很普通的前缀 『片段』

>这篇文章 上了 博客园的首页,我一点准备都没有 —— 我这浅薄的 Oracle 功底,根本经不起考验,更经不起 博客园园友 潮水般 的 狂批猛踩。

>这次,我死定了。。。。

代码如下:

  1. 1 public static class OracleHelper
  2. 2 {
  3. 3
  4. 4
  5. 5
  6. 6 public static List<T> ExecuteReaderList<T>(string connString, string cmdText, Func<OracleDataReader, T> funcReader) where T : new()
  7. 7 {
  8. 8 return ExecuteReaderList(connString, cmdText, null, funcReader);
  9. 9 }
  10. 10 public static T ExecuteReaderEntity<T>(string connString, string cmdText, Func<OracleDataReader, T> funcReader) where T : new()
  11. 11 {
  12. 12 return ExecuteReaderEntity(connString, cmdText, null, funcReader);
  13. 13 }
  14. 14 public static int ExecuteNonQuery(string connString, string cmdText)
  15. 15 {
  16. 16 return ExecuteNonQuery(connString, cmdText, null);
  17. 17 }
  18. 18 public static object ExecuteScalar(string connString, string cmdText)
  19. 19 {
  20. 20 return ExecuteScalar(connString, cmdText, null);
  21. 21 }
  22. 22 public static DataSet ExecuteFillDataSet(string connString, string cmdText)
  23. 23 {
  24. 24 return ExecuteFillDataSet(connString, cmdText, null);
  25. 25 }
  26. 26
  27. 27
  28. 28 public static List<T> ExecuteReaderList<T>(string connString, string cmdText, Action<OracleCommand> cmdAction, Func<OracleDataReader, T> funcReader) where T : new()
  29. 29 {
  30. 30 using (OracleConnection conn = new OracleConnection(connString))
  31. 31 {
  32. 32 TryOpenSqlConnection(conn);
  33. 33 return ExecuteReaderList<T>(conn, null, cmdText, cmdAction, funcReader);
  34. 34 }
  35. 35 }
  36. 36 public static T ExecuteReaderEntity<T>(string connString, string cmdText, Action<OracleCommand> cmdAction, Func<OracleDataReader, T> funcReader) where T : new()
  37. 37 {
  38. 38 using (OracleConnection conn = new OracleConnection(connString))
  39. 39 {
  40. 40 TryOpenSqlConnection(conn);
  41. 41 return ExecuteReaderEntity<T>(conn, null, cmdText, cmdAction, funcReader);
  42. 42 }
  43. 43 }
  44. 44 public static int ExecuteNonQuery(string connString, string cmdText, Action<OracleCommand> cmdAction)
  45. 45 {
  46. 46 using (OracleConnection conn = new OracleConnection(connString))
  47. 47 {
  48. 48 TryOpenSqlConnection(conn);
  49. 49 return ExecuteNonQuery(conn, null, cmdText, cmdAction);
  50. 50 }
  51. 51 }
  52. 52 public static object ExecuteScalar(string connString, string cmdText, Action<OracleCommand> cmdAction)
  53. 53 {
  54. 54 using (OracleConnection conn = new OracleConnection(connString))
  55. 55 {
  56. 56 TryOpenSqlConnection(conn);
  57. 57 return ExecuteScalar(conn, null, cmdText, cmdAction);
  58. 58 }
  59. 59 }
  60. 60 public static DataSet ExecuteFillDataSet(string connString, string cmdText, Action<OracleCommand> cmdAction)
  61. 61 {
  62. 62 using (OracleConnection conn = new OracleConnection(connString))
  63. 63 {
  64. 64 TryOpenSqlConnection(conn);
  65. 65 return ExecuteFillDataSet(conn, null, cmdText, cmdAction);
  66. 66 }
  67. 67 }
  68. 68
  69. 69
  70. 70 public static List<T> ExecuteReaderList<T>(OracleConnection conn, OracleTransaction tran, string cmdText, Action<OracleCommand> cmdAction, Func<OracleDataReader, T> funcReader) where T : new()
  71. 71 {
  72. 72 List<OracleSingleScript> listScript = SplitOracleScript(cmdText);
  73. 73 if (listScript == null || listScript.Count <= 0 || listScript.Count == 1)
  74. 74 {
  75. 75 return SingleExecuteReaderList<T>(conn, tran, cmdText, cmdAction, funcReader);
  76. 76 }
  77. 77 else
  78. 78 {
  79. 79 OracleBatchResult<T> result = ExecuteBatchScript<T>(conn, tran, listScript, false, cmdAction, funcReader);
  80. 80 return result.ExecuteReaderList();
  81. 81 }
  82. 82 }
  83. 83 public static T ExecuteReaderEntity<T>(OracleConnection conn, OracleTransaction tran, string cmdText, Action<OracleCommand> cmdAction, Func<OracleDataReader, T> funcReader) where T : new()
  84. 84 {
  85. 85 List<OracleSingleScript> listScript = SplitOracleScript(cmdText);
  86. 86 if (listScript == null || listScript.Count <= 0 || listScript.Count == 1)
  87. 87 {
  88. 88 return SingleExecuteReaderEntity<T>(conn, tran, cmdText, cmdAction, funcReader);
  89. 89 }
  90. 90 else
  91. 91 {
  92. 92 OracleBatchResult<T> result = ExecuteBatchScript<T>(conn, tran, listScript, false, cmdAction, funcReader);
  93. 93 return result.ExecuteReaderEntity();
  94. 94 }
  95. 95 }
  96. 96 public static int ExecuteNonQuery(OracleConnection conn, OracleTransaction tran, string cmdText, Action<OracleCommand> cmdAction)
  97. 97 {
  98. 98 List<OracleSingleScript> listScript = SplitOracleScript(cmdText);
  99. 99 if (listScript == null || listScript.Count <= 0 || listScript.Count == 1)
  100. 100 {
  101. 101 return SingleExecuteNonQuery(conn, tran, cmdText, cmdAction);
  102. 102 }
  103. 103 else
  104. 104 {
  105. 105 OracleBatchResult<object> result = ExecuteBatchScript<object>(conn, tran, listScript, false, cmdAction, null);
  106. 106 return result.ExecuteNonQuery();
  107. 107 }
  108. 108 }
  109. 109 public static object ExecuteScalar(OracleConnection conn, OracleTransaction tran, string cmdText, Action<OracleCommand> cmdAction)
  110. 110 {
  111. 111 List<OracleSingleScript> listScript = SplitOracleScript(cmdText);
  112. 112 if (listScript == null || listScript.Count <= 0 || listScript.Count == 1)
  113. 113 {
  114. 114 return SingleExecuteScalar(conn, tran, cmdText, cmdAction);
  115. 115 }
  116. 116 else
  117. 117 {
  118. 118 OracleBatchResult<object> result = ExecuteBatchScript<object>(conn, tran, listScript, false, cmdAction, null);
  119. 119 return result.ExecuteScalar();
  120. 120 }
  121. 121 }
  122. 122 public static DataSet ExecuteFillDataSet(OracleConnection conn, OracleTransaction tran, string cmdText, Action<OracleCommand> cmdAction)
  123. 123 {
  124. 124 List<OracleSingleScript> listScript = SplitOracleScript(cmdText);
  125. 125 if (listScript == null || listScript.Count <= 0 || listScript.Count == 1)
  126. 126 {
  127. 127 DataTable dataTable = SingleExecuteFillDataTable(conn, tran, cmdText, cmdAction);
  128. 128 DataSet dataSet = new DataSet();
  129. 129 if (dataTable != null) dataSet.Tables.Add(dataTable);
  130. 130 return dataSet;
  131. 131 }
  132. 132 else
  133. 133 {
  134. 134 OracleBatchResult<object> result = ExecuteBatchScript<object>(conn, tran, listScript, true, cmdAction, null);
  135. 135 return result.ExecuteFillDataSet();
  136. 136 }
  137. 137 }
  138. 138
  139. 139
  140. 140
  141. 141 private static OracleBatchResult<T> ExecuteBatchScript<T>(string connString, IEnumerable<OracleSingleScript> listScript, bool isSelectDataSet, Action<OracleCommand> cmdAction, Func<OracleDataReader, T> funcReader) where T : new()
  142. 142 {
  143. 143 using (OracleConnection conn = new OracleConnection(connString))
  144. 144 {
  145. 145 TryOpenSqlConnection(conn);
  146. 146 using (OracleTransaction tran = conn.BeginTransaction())
  147. 147 {
  148. 148 OracleBatchResult<T> result = ExecuteBatchScript(conn, tran, listScript, isSelectDataSet, cmdAction, funcReader);
  149. 149 return result;
  150. 150 }
  151. 151 }
  152. 152 }
  153. 153 private static OracleBatchResult<T> ExecuteBatchScript<T>(OracleConnection conn, OracleTransaction tran, IEnumerable<OracleSingleScript> listScript, bool isSelectDataSet, Action<OracleCommand> cmdAction, Func<OracleDataReader, T> funcReader) where T : new()
  154. 154 {
  155. 155 OracleBatchResult<T> result = new OracleBatchResult<T>();
  156. 156
  157. 157 bool tranIsNull = tran == null;
  158. 158 if (tranIsNull) tran = conn.BeginTransaction();
  159. 159 try
  160. 160 {
  161. 161 foreach (OracleSingleScript script in listScript)
  162. 162 {
  163. 163 #region 执行查询实体
  164. 164
  165. 165 if (script.IsSelect)
  166. 166 {
  167. 167 if (isSelectDataSet)
  168. 168 {
  169. 169 DataTable dataTable = SingleExecuteFillDataTable(conn, tran, script.SqlScript, cmdAction);
  170. 170 result.AddDataTable(dataTable);
  171. 171 }
  172. 172 else if (typeof(T) == typeof(object) && funcReader == null)
  173. 173 {
  174. 174 object scalar = SingleExecuteScalar(conn, tran, script.SqlScript, cmdAction);
  175. 175 result.AddScalar(scalar);
  176. 176 }
  177. 177 else
  178. 178 {
  179. 179 List<T> list = SingleExecuteReaderList<T>(conn, tran, script.SqlScript, cmdAction, funcReader);
  180. 180 result.AddList(list);
  181. 181 }
  182. 182 }
  183. 183
  184. 184 #endregion
  185. 185 #region 执行增加修改删除
  186. 186
  187. 187 if (script.IsInsert || script.IsUpdate || script.IsDelete)
  188. 188 {
  189. 189 int effect = SingleExecuteNonQuery(conn, tran, script.SqlScript, cmdAction);
  190. 190 result.AddEffect(effect);
  191. 191 }
  192. 192
  193. 193 #endregion
  194. 194 }
  195. 195 if (tranIsNull && tran != null) tran.Commit();
  196. 196 }
  197. 197 finally
  198. 198 {
  199. 199 if (tranIsNull && tran != null) tran.Dispose();
  200. 200 }
  201. 201
  202. 202 return result;
  203. 203 }
  204. 204
  205. 205
  206. 206 #region 执行单条脚本
  207. 207
  208. 208 //private static List<T> SingleExecuteReaderList<T>(string connString, string cmdText, Action<OracleCommand> cmdAction, Func<OracleDataReader, T> funcReader) where T : new()
  209. 209 //{
  210. 210 // using (OracleConnection conn = new OracleConnection(connString))
  211. 211 // {
  212. 212 // TryOpenSqlConnection(conn);
  213. 213 // return SingleExecuteReaderList(conn, null, cmdText, cmdAction, funcReader);
  214. 214 // }
  215. 215 //}
  216. 216 //private static T SingleExecuteReaderEntity<T>(string connString, string cmdText, Action<OracleCommand> cmdAction, Func<OracleDataReader, T> funcReader) where T : new()
  217. 217 //{
  218. 218 // using (OracleConnection conn = new OracleConnection(connString))
  219. 219 // {
  220. 220 // TryOpenSqlConnection(conn);
  221. 221 // return SingleExecuteReaderEntity(conn, null, cmdText, cmdAction, funcReader);
  222. 222 // }
  223. 223 //}
  224. 224 //private static int SingleExecuteNonQuery(string connString, string cmdText, Action<OracleCommand> cmdAction)
  225. 225 //{
  226. 226 // using (OracleConnection conn = new OracleConnection(connString))
  227. 227 // {
  228. 228 // TryOpenSqlConnection(conn);
  229. 229 // return SingleExecuteNonQuery(conn, null, cmdText, cmdAction);
  230. 230 // }
  231. 231 //}
  232. 232 //private static object SingleExecuteScalar(string connString, string cmdText, Action<OracleCommand> cmdAction)
  233. 233 //{
  234. 234 // using (OracleConnection conn = new OracleConnection(connString))
  235. 235 // {
  236. 236 // TryOpenSqlConnection(conn);
  237. 237 // return SingleExecuteScalar(conn, null, cmdText, cmdAction);
  238. 238 // }
  239. 239 //}
  240. 240 //private static DataTable SingleExecuteFillDataTable(string connString, string cmdText, Action<OracleCommand> cmdAction)
  241. 241 //{
  242. 242 // using (OracleConnection conn = new OracleConnection(connString))
  243. 243 // {
  244. 244 // TryOpenSqlConnection(conn);
  245. 245 // return SingleExecuteFillDataTable(conn, null, cmdText, cmdAction);
  246. 246 // }
  247. 247 //}
  248. 248
  249. 249
  250. 250 private static List<T> SingleExecuteReaderList<T>(OracleConnection conn, OracleTransaction tran, string cmdText, Action<OracleCommand> cmdAction, Func<OracleDataReader, T> funcReader) where T : new()
  251. 251 {
  252. 252 List<T> list = new List<T>();
  253. 253 //需要查询的是否是 原生值类型
  254. 254 bool isMetaValue = typeof(T).IsValueType && typeof(T).GetProperties().Length <= 0 && typeof(T).GetFields().Length <= 0;
  255. 255
  256. 256 using (OracleCommand cmd = conn.CreateCommand())
  257. 257 {
  258. 258 cmd.CommandText = cmdText;
  259. 259 cmd.CommandTimeout = int.MaxValue;
  260. 260 //cmd.Transaction = tran;
  261. 261 if (cmdAction != null) cmdAction(cmd);
  262. 262
  263. 263 using (OracleDataReader reader = cmd.ExecuteReader())
  264. 264 {
  265. 265 List<string> listFieldName = new List<string>();
  266. 266 while (reader.Read())
  267. 267 {
  268. 268 if (funcReader != null)
  269. 269 {
  270. 270 //通过指定的 函数 创建对象
  271. 271 T item = funcReader(reader);
  272. 272 if (!object.Equals(item, default(T))) list.Add(item);
  273. 273 }
  274. 274 else
  275. 275 {
  276. 276 if (listFieldName.Count <= 0)
  277. 277 for (int i = 0; i < reader.FieldCount; i++)
  278. 278 {
  279. 279 string fieldName = reader.GetName(i).Trim();
  280. 280 listFieldName.Add(fieldName);
  281. 281 }
  282. 282
  283. 283 //通过反射 创建对象
  284. 284 if (isMetaValue)
  285. 285 {
  286. 286 object value = reader[listFieldName[0]];
  287. 287 T item = (T)Tools.ConvertValue(value, typeof(T));
  288. 288 if (!object.Equals(item, default(T))) list.Add(item);
  289. 289 }
  290. 290 else
  291. 291 {
  292. 292 T item = new T();
  293. 293 foreach (string fieldName in listFieldName)
  294. 294 {
  295. 295 object value = reader[fieldName];
  296. 296 //if (value == null || value == DBNull.Value) value = ConstDefine.InvalidValueDoulbe;
  297. 297 if (value != null && value != DBNull.Value)
  298. 298 Tools.SetValue(item, fieldName, value);
  299. 299 }
  300. 300 if (!object.Equals(item, default(T))) list.Add(item);
  301. 301 }
  302. 302 }
  303. 303 }
  304. 304 }
  305. 305 }
  306. 306
  307. 307 return list;
  308. 308 }
  309. 309 private static T SingleExecuteReaderEntity<T>(OracleConnection conn, OracleTransaction tran, string cmdText, Action<OracleCommand> cmdAction, Func<OracleDataReader, T> funcReader) where T : new()
  310. 310 {
  311. 311 T result = default(T);
  312. 312 //需要查询的是否是 原生值类型
  313. 313 bool isMetaValue = typeof(T).IsValueType && typeof(T).GetProperties().Length <= 0 && typeof(T).GetFields().Length <= 0;
  314. 314
  315. 315 using (OracleCommand cmd = conn.CreateCommand())
  316. 316 {
  317. 317 cmd.CommandText = cmdText;
  318. 318 cmd.CommandTimeout = int.MaxValue;
  319. 319 if (cmdAction != null) cmdAction(cmd);
  320. 320
  321. 321 using (OracleDataReader reader = cmd.ExecuteReader())
  322. 322 {
  323. 323 List<string> listFieldName = new List<string>();
  324. 324 if (reader.Read())
  325. 325 {
  326. 326 if (funcReader != null)
  327. 327 {
  328. 328 //通过指定的 函数 创建对象
  329. 329 T item = funcReader(reader);
  330. 330 result = item;
  331. 331 }
  332. 332 else
  333. 333 {
  334. 334 if (listFieldName.Count <= 0)
  335. 335 for (int i = 0; i < reader.FieldCount; i++)
  336. 336 {
  337. 337 string fieldName = reader.GetName(i).Trim();
  338. 338 listFieldName.Add(fieldName);
  339. 339 }
  340. 340
  341. 341 //通过反射 创建对象
  342. 342 if (isMetaValue)
  343. 343 {
  344. 344 object value = reader[listFieldName[0]];
  345. 345 T item = (T)Tools.ConvertValue(value, typeof(T));
  346. 346 result = item;
  347. 347 }
  348. 348 else
  349. 349 {
  350. 350 T item = new T();
  351. 351 foreach (string fieldName in listFieldName)
  352. 352 Tools.SetValue(item, fieldName, reader[fieldName]);
  353. 353 result = item;
  354. 354 }
  355. 355 }
  356. 356 }
  357. 357 }
  358. 358 }
  359. 359
  360. 360 return result;
  361. 361 }
  362. 362 private static int SingleExecuteNonQuery(OracleConnection conn, OracleTransaction tran, string cmdText, Action<OracleCommand> cmdAction)
  363. 363 {
  364. 364 int result = 0;
  365. 365
  366. 366 using (OracleCommand cmd = conn.CreateCommand())
  367. 367 {
  368. 368 cmd.CommandText = cmdText;
  369. 369 cmd.CommandTimeout = int.MaxValue;
  370. 370 if (cmdAction != null) cmdAction(cmd);
  371. 371
  372. 372 result = cmd.ExecuteNonQuery();
  373. 373 }
  374. 374
  375. 375 return result;
  376. 376 }
  377. 377 private static object SingleExecuteScalar(OracleConnection conn, OracleTransaction tran, string cmdText, Action<OracleCommand> cmdAction)
  378. 378 {
  379. 379 object result = null;
  380. 380
  381. 381 using (OracleCommand cmd = conn.CreateCommand())
  382. 382 {
  383. 383 cmd.CommandText = cmdText;
  384. 384 cmd.CommandTimeout = int.MaxValue;
  385. 385 if (cmdAction != null) cmdAction(cmd);
  386. 386
  387. 387 result = cmd.ExecuteScalar();
  388. 388 }
  389. 389
  390. 390 return result;
  391. 391
  392. 392 }
  393. 393 private static DataTable SingleExecuteFillDataTable(OracleConnection conn, OracleTransaction tran, string cmdText, Action<OracleCommand> cmdAction)
  394. 394 {
  395. 395 DataTable dataTable = new DataTable();
  396. 396
  397. 397 using (OracleCommand cmd = conn.CreateCommand())
  398. 398 {
  399. 399 cmd.CommandText = cmdText;
  400. 400 cmd.CommandTimeout = int.MaxValue;
  401. 401 if (cmdAction != null) cmdAction(cmd);
  402. 402
  403. 403 using (OracleDataAdapter adapter = new OracleDataAdapter(cmd))
  404. 404 {
  405. 405 adapter.Fill(dataTable);
  406. 406 }
  407. 407 }
  408. 408
  409. 409 return dataTable;
  410. 410 }
  411. 411
  412. 412 #endregion
  413. 413
  414. 414
  415. 415
  416. 416 /// <summary>
  417. 417 /// 用指定的 脚本开启一个事务, 并且 打开数据库链接
  418. 418 /// </summary>
  419. 419 public static void DoTransaction(string connString, Action<OracleTransaction, OracleConnection> tranAction)
  420. 420 {
  421. 421 using (OracleConnection conn = new OracleConnection(connString))
  422. 422 {
  423. 423 TryOpenSqlConnection(conn);
  424. 424 using (OracleTransaction tran = conn.BeginTransaction())
  425. 425 {
  426. 426 if (tranAction == null) throw new Exception("OracleHelper.DoTransaction(string, Action) 必须提供 有效的 回调委托!");
  427. 427 if (tranAction != null) tranAction(tran, conn);
  428. 428 }
  429. 429 }
  430. 430 }
  431. 431 /// <summary>
  432. 432 /// 尝试 打开 指定的 数据库链接
  433. 433 /// </summary>
  434. 434 public static void TryOpenSqlConnection(OracleConnection conn)
  435. 435 {
  436. 436 TryOpenSqlConnection(conn, 50);
  437. 437 }
  438. 438 /// <summary>
  439. 439 /// 尝试 打开 指定的 数据库链接
  440. 440 /// </summary>
  441. 441 public static void TryOpenSqlConnection(OracleConnection conn, int reTryCount)
  442. 442 {
  443. 443 if (conn == null) return;
  444. 444 int expCount = 0;
  445. 445 do
  446. 446 {
  447. 447 try
  448. 448 {
  449. 449 conn.Open();
  450. 450 break;
  451. 451 }
  452. 452 catch (Exception exp)
  453. 453 {
  454. 454 if (exp is InvalidOperationException || exp is OracleException)
  455. 455 {
  456. 456 expCount++;
  457. 457 if (expCount >= reTryCount) throw; //重试reTryCount次都失败, 则不再重试, 抛出异常
  458. 458 Thread.Sleep(5); //打开失败时, 休眠 5毫秒, 再重试打开
  459. 459 }
  460. 460 else throw;
  461. 461 }
  462. 462
  463. 463 } while (true);
  464. 464 }
  465. 465
  466. 466
  467. 467
  468. 468 /// <summary>
  469. 469 /// Oracle 不支持 多条脚本 同时执行, 这里按照 ; 拆分脚本, 分次执行
  470. 470 /// </summary>
  471. 471 private static List<OracleSingleScript> SplitOracleScript(string cmdText)
  472. 472 {
  473. 473 List<OracleSingleScript> listScript = new List<OracleSingleScript>();
  474. 474 if (string.IsNullOrWhiteSpace(cmdText)) return listScript;
  475. 475 if (!cmdText.Contains(";"))
  476. 476 {
  477. 477 OracleSingleScript singleScript = OracleSingleScript.Create(cmdText);
  478. 478 if (singleScript != null) listScript.Add(singleScript);
  479. 479 return listScript;
  480. 480 }
  481. 481
  482. 482 string cmdTextTrim = cmdText.Trim().Trim(';').Trim();
  483. 483 if (cmdTextTrim.StartsWith("BEGIN", StringComparison.CurrentCultureIgnoreCase))
  484. 484 cmdTextTrim = cmdTextTrim.Substring("BEGIN".Length);
  485. 485 if (cmdTextTrim.EndsWith("END", StringComparison.CurrentCultureIgnoreCase))
  486. 486 cmdTextTrim = cmdTextTrim.Substring(0, cmdTextTrim.Length - "END".Length);
  487. 487
  488. 488
  489. 489 string[] splitTemp = cmdTextTrim.Split(new[] { ';' }, StringSplitOptions.None);
  490. 490
  491. 491 List<string> listGroup = new List<string>();
  492. 492 foreach (string temp in splitTemp)
  493. 493 {
  494. 494 string tempTrim = temp.Trim();
  495. 495
  496. 496 //可以作为开头的 脚本
  497. 497 if (tempTrim.StartsWith("SELECT", StringComparison.CurrentCultureIgnoreCase)
  498. 498 || tempTrim.StartsWith("INSERT", StringComparison.CurrentCultureIgnoreCase)
  499. 499 || tempTrim.StartsWith("UPDATE", StringComparison.CurrentCultureIgnoreCase)
  500. 500 || tempTrim.StartsWith("DELETE", StringComparison.CurrentCultureIgnoreCase)
  501. 501 )
  502. 502 {
  503. 503 if (listGroup.Count > 0)
  504. 504 {
  505. 505 string script = string.Join(";", listGroup).Trim().Trim(';').Trim();
  506. 506 OracleSingleScript singleScript = OracleSingleScript.Create(script);
  507. 507 if (singleScript != null) listScript.Add(singleScript);
  508. 508 listGroup.Clear();
  509. 509 }
  510. 510 }
  511. 511
  512. 512 listGroup.Add(temp);
  513. 513 }
  514. 514
  515. 515 if (listGroup.Count > 0)
  516. 516 {
  517. 517 string lastScript = string.Join(";", listGroup).Trim().Trim(';').Trim();
  518. 518 OracleSingleScript singleScript = OracleSingleScript.Create(lastScript);
  519. 519 if (singleScript != null) listScript.Add(singleScript);
  520. 520 listGroup.Clear();
  521. 521 }
  522. 522
  523. 523 return listScript;
  524. 524 }
  525. 525
  526. 526
  527. 527
  528. 528
  529. 529
  530. 530 [Serializable]
  531. 531 internal class OracleSingleScript
  532. 532 {
  533. 533 private string sqlScript = string.Empty;
  534. 534
  535. 535 public bool IsSelect { get; private set; }
  536. 536 public bool IsInsert { get; private set; }
  537. 537 public bool IsUpdate { get; private set; }
  538. 538 public bool IsDelete { get; private set; }
  539. 539 public string SqlScript
  540. 540 {
  541. 541 get { return sqlScript; }
  542. 542 set { sqlScript = (value ?? string.Empty).Trim().Trim(';').Trim(); }
  543. 543 }
  544. 544
  545. 545
  546. 546 private OracleSingleScript() { }
  547. 547 public override string ToString()
  548. 548 {
  549. 549 return SqlScript;
  550. 550 }
  551. 551 public static OracleSingleScript Create(string script)
  552. 552 {
  553. 553 script = (script ?? string.Empty).Trim().Trim(';').Trim();
  554. 554 if (string.IsNullOrWhiteSpace(script)) return null;
  555. 555
  556. 556 OracleSingleScript item = new OracleSingleScript();
  557. 557 item.SqlScript = script;
  558. 558
  559. 559 item.IsSelect = script.StartsWith("SELECT", StringComparison.CurrentCultureIgnoreCase);
  560. 560 if (!item.IsSelect)
  561. 561 {
  562. 562 item.IsInsert = script.StartsWith("INSERT", StringComparison.CurrentCultureIgnoreCase);
  563. 563 if (!item.IsInsert)
  564. 564 {
  565. 565 item.IsUpdate = script.StartsWith("UPDATE", StringComparison.CurrentCultureIgnoreCase);
  566. 566 if (!item.IsUpdate)
  567. 567 item.IsDelete = script.StartsWith("DELETE", StringComparison.CurrentCultureIgnoreCase);
  568. 568 }
  569. 569 }
  570. 570
  571. 571 return item;
  572. 572 }
  573. 573 }
  574. 574
  575. 575 [Serializable]
  576. 576 internal class OracleBatchResult<T> where T : new()
  577. 577 {
  578. 578 private readonly List<List<T>> list = new List<List<T>>();
  579. 579 private readonly List<int> effect = new List<int>();
  580. 580 private readonly List<object> scalar = new List<object>();
  581. 581 private readonly List<DataTable> dataTable = new List<DataTable>();
  582. 582 private readonly DataSet dataSet = new DataSet();
  583. 583
  584. 584 public void AddList(List<T> temp) { list.Add(temp); }
  585. 585 public void AddEffect(int temp) { effect.Add(temp); }
  586. 586 public void AddScalar(object temp) { scalar.Add(temp); }
  587. 587 public void AddDataTable(DataTable temp) { dataTable.Add(temp); }
  588. 588
  589. 589 public List<T> ExecuteReaderList()
  590. 590 {
  591. 591 return list.Count >= 1 ? list[list.Count - 1] : null;
  592. 592 }
  593. 593 public T ExecuteReaderEntity()
  594. 594 {
  595. 595 List<T> listT = ExecuteReaderList();
  596. 596 return (listT != null && listT.Count >= 1) ? listT[0] : default(T);
  597. 597 }
  598. 598 public int ExecuteNonQuery()
  599. 599 {
  600. 600 return effect.Count >= 1 ? effect[effect.Count - 1] : 0;
  601. 601 }
  602. 602 public object ExecuteScalar()
  603. 603 {
  604. 604 //如果 scalar 集合 存在数据, 直接返回 最后一个
  605. 605 //如果 scalar 集合无效, 但是 list 集合有效, 尝试获取 第一个实体, 第一个属性的值
  606. 606 //如果 scalar、list 集合有效, 但是 dataTable 集合有效, 尝试获取 第一个DataRow, 第一个DataCell的值
  607. 607
  608. 608 if (scalar.Count >= 1)
  609. 609 {
  610. 610 return scalar[scalar.Count - 1];
  611. 611 }
  612. 612 else if (list.Count >= 1)
  613. 613 {
  614. 614 #region 尝试从 list 实体集合中 返回 单行单列 值
  615. 615
  616. 616 try
  617. 617 {
  618. 618 List<T> listT = list[list.Count-1];
  619. 619 if ((listT != null && listT.Count >= 1))
  620. 620 {
  621. 621 T first = listT[0];
  622. 622 PropertyInfo[] firstProperties = typeof(T).GetProperties();
  623. 623 if (firstProperties.Length >= 1)
  624. 624 return firstProperties[0].GetValue(first, null);
  625. 625 else
  626. 626 {
  627. 627 FieldInfo[] firstFields = typeof(T).GetFields();
  628. 628 if (firstFields.Length >= 1)
  629. 629 return firstFields[0].GetValue(first);
  630. 630 }
  631. 631 }
  632. 632 }
  633. 633 catch(Exception){ }
  634. 634
  635. 635 #endregion
  636. 636 }
  637. 637 else if (dataTable.Count >= 1)
  638. 638 {
  639. 639 #region 尝试从 dataTable 集合中 返回 但行单列 值
  640. 640
  641. 641 try
  642. 642 {
  643. 643 DataTable table = dataTable[dataTable.Count-1];
  644. 644 if ((table != null && table.Rows.Count >= 1))
  645. 645 {
  646. 646 DataRow first = table.Rows[0];
  647. 647 if (table.Columns.Count >= 1)
  648. 648 return first[0];
  649. 649 }
  650. 650 }
  651. 651 catch (Exception) { }
  652. 652
  653. 653 #endregion
  654. 654 }
  655. 655 return null;
  656. 656 }
  657. 657 public DataSet ExecuteFillDataSet()
  658. 658 {
  659. 659 dataSet.Clear();
  660. 660 dataSet.Tables.AddRange(dataTable.ToArray());
  661. 661 return dataSet;
  662. 662 }
  663. 663 }
  664. 664 }

『片段』OracleHelper (支持 多条SQL语句)的更多相关文章

  1. jmert jdbc request支持执行多条sql语句并设置jdbc字符集

    1.jdbc request支持执行多条sql语句 在JDBC Connection Configuration中的sql连接字串中添加如下内容 allowMultiQueries=true 如下图: ...

  2. MyBatis7:MyBatis插件及示例----打印每条SQL语句及其执行时间

    Plugins 摘一段来自MyBatis官方文档的文字. MyBatis允许你在某一点拦截已映射语句执行的调用.默认情况下,MyBatis允许使用插件来拦截方法调用 Executor(update.q ...

  3. MyBatis插件及示例----打印每条SQL语句及其执行时间

    Plugins 摘一段来自MyBatis官方文档的文字. MyBatis允许你在某一点拦截已映射语句执行的调用.默认情况下,MyBatis允许使用插件来拦截方法调用 Executor(update.q ...

  4. Spring 中jdbcTemplate 实现执行多条sql语句

    说一下Spring框架中使用jdbcTemplate实现多条sql语句的执行: 很多情况下我们需要处理一件事情的时候需要对多个表执行多个sql语句,比如淘宝下单时,我们确认付款时要对自己银行账户的表里 ...

  5. java执行多条SQL语句

    一次执行多条SQL的技术要点如下: DatabaseMetaData接口是描述有关数据库的整体综合信息,由于DatabaseMetaData是接口,所以没有构造方法,故不能使用new来创建Databa ...

  6. SQL反模式学习笔记18 减少SQL查询数据,避免使用一条SQL语句解决复杂问题

    目标:减少SQL查询数据,避免使用一条SQL语句解决复杂问题 反模式:视图使用一步操作,单个SQL语句解决复杂问题 使用一个查询来获得所有结果的最常见后果就是产生了一个笛卡尔积.导致查询性能降低. 如 ...

  7. 一条SQL语句在MySQL中如何执行的

    本篇文章会分析一个 sql 语句在 MySQL 中的执行流程,包括 sql 的查询在 MySQL 内部会怎么流转,sql 语句的更新是怎么完成的. 在分析之前我会先带着你看看 MySQL 的基础架构, ...

  8. jmeter 中如何一次运行多条sql语句

    在jmeter测试mysql中如何一次运行多条sql语句 allowMultiQueries=true 注意:太低版本的mysql和jdbc不支持,最好用最新版的

  9. ThinkPHP框架 系统规定的方法查询数据库内容!!同时也支持原生的SQL语句!

    <?php namespace Admin\Controller; use Think\Controller; class MainController extends Controller{ ...

随机推荐

  1. python数据结构-列表-建立/索引/反转

  2. select2使用

    一.简介 select2是Jquery用来代替选择框的一种组件.它让你可以定制下拉框,并且支持搜索.标记,远程数据源,无限滚动和其他更高级的功能.select2的下载地址为:https://selec ...

  3. nginx 负载均衡示例

    一.nginx nginx是一个轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,以开源形式发布.nginx的性能稳定,功能丰富,配置简单,且占用系统资源低.可支持多个 ...

  4. JavaScript生成GUID的算法

    全局唯一标识符(GUID,Globally Unique Identifier)也称作 UUID(Universally Unique IDentifier) . GUID是一种由算法生成的二进制长度 ...

  5. html3秒跳转

    <script>     setTimeout( 'window.location= "home.jsp " ',3000) ;//注意,此处“;”可加可不加</ ...

  6. Sublime Text 2 (for OS X )配置成可以运行基于python3解释器的 .py文件

    Mac自带的python 其version是python 2.7 官网下的Sublime Text 2部署好了以后默认也是 为了使ST2 可以在command+B时可以运行基于python3的.py, ...

  7. hadooop2.6 job pending research

    https://hadoop.apache.org/docs/r2.6.0/hadoop-project-dist/hadoop-common/ClusterSetup.html 我使用的是已经运行在 ...

  8. Oracle 数据库优化-分析现有的sql

    在做数据库sql优化时,首先要对现有的数据库sql进行优化,主要包括以下几种: 1.数据库正在执行的SQL是? 2.已经执行过得SQL是? 3.最耗时的的前几条SQL是? 4.最耗IO的SQL是? 5 ...

  9. uva 120 stacks of flapjacks ——yhx

     Stacks of Flapjacks  Background Stacks and Queues are often considered the bread and butter of data ...

  10. java操作excel文件

    采用POI操作excel API:http://poi.apache.org/apidocs/org/apache/poi/hssf/usermodel/HSSFCell.html poi包:http ...