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