OracleInsertable.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace SqlSugar
  7. {
  8. public class OracleInsertable<T> : InsertableProvider<T> where T : class, new()
  9. {
  10. protected override List<string> GetIdentityKeys()
  11. {
  12. return this.EntityInfo.Columns.Where(it => it.OracleSequenceName.HasValue()).Select(it => it.DbColumnName).ToList();
  13. }
  14. protected string GetSeqName()
  15. {
  16. return this.EntityInfo.Columns.Where(it => it.OracleSequenceName.HasValue()).Select(it => it.OracleSequenceName).First();
  17. }
  18. protected List<string> GetSeqNames()
  19. {
  20. return this.EntityInfo.Columns.Where(it => it.OracleSequenceName.HasValue()).Select(it => it.OracleSequenceName).ToList();
  21. }
  22. public override int ExecuteReturnIdentity()
  23. {
  24. bool oldIsAuto = AutoBegin();
  25. InsertBuilder.IsReturnIdentity = true;
  26. PreToSql();
  27. string sql = InsertBuilder.ToSqlString();
  28. if (isIdEntityEnable())
  29. {
  30. if (sql?.StartsWith("INSERT ALL")==true)
  31. {
  32. return this.UseParameter().ExecuteCommand();
  33. }
  34. else
  35. {
  36. sql = sql + " RETURNING ID INTO :newId01 ";
  37. }
  38. InsertBuilder.Parameters.Add(new SugarParameter(":newId01", 0,true));
  39. }
  40. RestoreMapping();
  41. var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation;
  42. this.Context.Ado.IsDisableMasterSlaveSeparation = true;
  43. var count = Ado.ExecuteCommand(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  44. var result = (this.GetIdentityKeys().IsNullOrEmpty() || count == 0) ? 0 : GetSeqValue(GetSeqName()).ObjToInt();
  45. this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation;
  46. After(sql,result);
  47. AutoEnd(oldIsAuto);
  48. if (isIdEntityEnable())
  49. {
  50. return this.InsertBuilder.Parameters.FirstOrDefault(it => it.ParameterName == ":newId01")?.Value?.ObjToInt()??0;
  51. }
  52. return result;
  53. }
  54. private bool isIdEntityEnable()
  55. {
  56. return this.Context.CurrentConnectionConfig?.MoreSettings?.EnableOracleIdentity == true;
  57. }
  58. public override long ExecuteReturnBigIdentity()
  59. {
  60. bool oldIsAuto = AutoBegin();
  61. InsertBuilder.IsReturnIdentity = true;
  62. PreToSql();
  63. string sql = InsertBuilder.ToSqlString();
  64. if (isIdEntityEnable())
  65. {
  66. if (sql?.StartsWith("INSERT ALL") == true)
  67. {
  68. return this.UseParameter().ExecuteCommand();
  69. }
  70. else
  71. {
  72. sql = sql + " RETURNING ID INTO :newId01 ";
  73. }
  74. InsertBuilder.Parameters.Add(new SugarParameter(":newId01", Convert.ToInt64(0), true));
  75. }
  76. RestoreMapping();
  77. var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation;
  78. this.Context.Ado.IsDisableMasterSlaveSeparation = true;
  79. var count = Ado.ExecuteCommand(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  80. var result = (this.GetIdentityKeys().IsNullOrEmpty() || count == 0) ? 0 : Convert.ToInt64(GetSeqValue(GetSeqName()));
  81. this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation;
  82. After(sql, result);
  83. AutoEnd(oldIsAuto);
  84. if (isIdEntityEnable())
  85. {
  86. return this.InsertBuilder.Parameters.FirstOrDefault(it => it.ParameterName == ":newId01")?.Value?.ObjToLong() ?? 0;
  87. }
  88. return result;
  89. }
  90. public async override Task<int> ExecuteReturnIdentityAsync()
  91. {
  92. bool oldIsAuto = AutoBegin();
  93. InsertBuilder.IsReturnIdentity = true;
  94. PreToSql();
  95. string sql = InsertBuilder.ToSqlString();
  96. if (isIdEntityEnable())
  97. {
  98. if (sql?.StartsWith("INSERT ALL") == true)
  99. {
  100. return await this.UseParameter().ExecuteCommandAsync();
  101. }
  102. else
  103. {
  104. sql = sql + " RETURNING ID INTO :newId01 ";
  105. }
  106. InsertBuilder.Parameters.Add(new SugarParameter(":newId01", 0, true));
  107. }
  108. RestoreMapping();
  109. var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation;
  110. this.Context.Ado.IsDisableMasterSlaveSeparation = true;
  111. var count = await Ado.ExecuteCommandAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  112. var result = (this.GetIdentityKeys().IsNullOrEmpty() || count == 0) ? 0 : GetSeqValue(GetSeqName()).ObjToInt();
  113. this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation;
  114. After(sql, result);
  115. AutoEnd(oldIsAuto);
  116. if (isIdEntityEnable())
  117. {
  118. return this.InsertBuilder.Parameters.FirstOrDefault(it => it.ParameterName == ":newId01")?.Value?.ObjToInt() ?? 0;
  119. }
  120. return result;
  121. }
  122. public async override Task<long> ExecuteReturnBigIdentityAsync()
  123. {
  124. bool oldIsAuto = AutoBegin();
  125. InsertBuilder.IsReturnIdentity = true;
  126. PreToSql();
  127. string sql = InsertBuilder.ToSqlString();
  128. if (isIdEntityEnable())
  129. {
  130. if (sql?.StartsWith("INSERT ALL") == true)
  131. {
  132. return await this.UseParameter().ExecuteCommandAsync();
  133. }
  134. else
  135. {
  136. sql = sql + " RETURNING ID INTO :newId01 ";
  137. }
  138. InsertBuilder.Parameters.Add(new SugarParameter(":newId01", Convert.ToInt64(0), true));
  139. }
  140. RestoreMapping();
  141. var isDisableMasterSlaveSeparation = this.Context.Ado.IsDisableMasterSlaveSeparation;
  142. this.Context.Ado.IsDisableMasterSlaveSeparation = true;
  143. var count = await Ado.ExecuteCommandAsync(sql, InsertBuilder.Parameters == null ? null : InsertBuilder.Parameters.ToArray());
  144. var result = (this.GetIdentityKeys().IsNullOrEmpty() || count == 0) ? 0 : Convert.ToInt64(GetSeqValue(GetSeqName()));
  145. this.Context.Ado.IsDisableMasterSlaveSeparation = isDisableMasterSlaveSeparation;
  146. After(sql, result);
  147. AutoEnd(oldIsAuto);
  148. if (isIdEntityEnable())
  149. {
  150. return this.InsertBuilder.Parameters.FirstOrDefault(it => it.ParameterName == ":newId01")?.Value?.ObjToLong() ?? 0;
  151. }
  152. return result;
  153. }
  154. private void AutoEnd(bool oldIsAuto)
  155. {
  156. if (oldIsAuto)
  157. {
  158. this.Context.Context.CurrentConnectionConfig.IsAutoCloseConnection = oldIsAuto;
  159. if (this.Ado.Transaction == null)
  160. this.Context.Ado.Close();
  161. }
  162. }
  163. private bool AutoBegin()
  164. {
  165. var oldIsAuto = this.Context.Context.CurrentConnectionConfig.IsAutoCloseConnection;
  166. if (this.Context.Context.CurrentConnectionConfig.IsAutoCloseConnection)
  167. {
  168. this.Context.Context.CurrentConnectionConfig.IsAutoCloseConnection = false;
  169. }
  170. return oldIsAuto;
  171. }
  172. private object GetSeqValue(string seqName)
  173. {
  174. return Ado.GetScalar(" SELECT " + seqName + ".currval FROM DUAL");
  175. }
  176. protected override void PreToSql()
  177. {
  178. var identities = GetSeqNames();
  179. var insertCount = InsertObjs.Count();
  180. InsertBuilder.OracleSeqInfoList = new Dictionary<string, int>();
  181. if ((identities.HasValue() && insertCount > 1)|| InsertBuilder.IsBlukCopy)
  182. {
  183. Check.Exception(identities.Count != identities.Distinct().Count(), "The field sequence needs to be unique");
  184. foreach (var seqName in identities)
  185. {
  186. int seqBeginValue = 0;
  187. seqBeginValue = this.Ado.GetInt("select " + seqName + ".Nextval from dual");
  188. //Console.WriteLine(seqBeginValue);
  189. var nextLength = insertCount - 1;
  190. if (nextLength > 0)
  191. {
  192. StringBuilder sb = new StringBuilder();
  193. sb.AppendLine(" select " + seqName + ".nextval,t.* from (");
  194. for (int i = 0; i < nextLength; i++)
  195. {
  196. sb.AppendLine(" select 1 from dual");
  197. if (i < (nextLength - 1))
  198. {
  199. sb.AppendLine("union all");
  200. }
  201. }
  202. sb.AppendLine(" )t");
  203. this.Ado.SqlQuery<int>(sb.ToString());
  204. }
  205. InsertBuilder.OracleSeqInfoList.Add(seqName, seqBeginValue);
  206. }
  207. }
  208. base.PreToSql();
  209. }
  210. }
  211. }