OracleProvider.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. using Oracle.ManagedDataAccess.Client;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data;
  5. using System.Data.Common;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Text.RegularExpressions;
  9. using System.Threading.Tasks;
  10. namespace SqlSugar
  11. {
  12. public class OracleProvider : AdoProvider
  13. {
  14. public OracleProvider()
  15. {
  16. //this.FormatSql = sql =>
  17. //{
  18. // sql = sql.Replace("+@", "+:");
  19. // if (sql.HasValue()&&sql.Contains("@")) {
  20. // var exceptionalCaseInfo = Regex.Matches(sql, @"\'[^\=]*?\@.*?\'|[\.,\w]+\@[\.,\w]+ | [\.,\w]+\@[\.,\w]+|[\.,\w]+\@[\.,\w]+ |\d+\@\d|\@\@|\w{1,25}\.""\w{1,25}""\@\w{1,25}");
  21. // if (exceptionalCaseInfo != null) {
  22. // foreach (var item in exceptionalCaseInfo.Cast<Match>())
  23. // {
  24. // if (item.Value != null && item.Value.IndexOf(",") == 1&&Regex.IsMatch(item.Value, @"^ \,\@\w+$"))
  25. // {
  26. // continue;
  27. // }
  28. // else if (item.Value != null &&Regex.IsMatch(item.Value.Trim(), @"^\w+\,\@\w+\,$"))
  29. // {
  30. // continue;
  31. // }
  32. // else if (item.Value != null && item.Value.ObjToString().Contains("||") && Regex.IsMatch(item.Value.Replace(" ","").Trim(), @"\|\|@\w+\|\|"))
  33. // {
  34. // continue;
  35. // }
  36. // else if (item.Value != null&& Regex.IsMatch(item.Value.Replace(" ", "").Trim(), @"\(\@\w+\,"))
  37. // {
  38. // continue;
  39. // }
  40. // else if (item.Value != null &&item.Value.Contains("=")&& Regex.IsMatch(item.Value, @"\w+ \@\w+[ ]{0,1}\=[ ]{0,1}\'"))
  41. // {
  42. // continue;
  43. // }
  44. // sql = sql.Replace(item.Value, item.Value.Replace("@", UtilConstants.ReplaceKey));
  45. // }
  46. // }
  47. // sql = sql .Replace("@",":");
  48. // sql = sql.Replace(UtilConstants.ReplaceKey, "@");
  49. // }
  50. // return sql;
  51. //};
  52. }
  53. public override string SqlParameterKeyWord
  54. {
  55. get
  56. {
  57. return ":";
  58. }
  59. }
  60. public override IDbConnection Connection
  61. {
  62. get
  63. {
  64. try
  65. {
  66. if (base._DbConnection == null)
  67. {
  68. base._DbConnection = new OracleConnection(base.Context.CurrentConnectionConfig.ConnectionString);
  69. }
  70. }
  71. catch (Exception ex)
  72. {
  73. Check.Exception(true, ErrorMessage.ConnnectionOpen, ex.Message);
  74. }
  75. return base._DbConnection;
  76. }
  77. set
  78. {
  79. base._DbConnection = value;
  80. }
  81. }
  82. /// <summary>
  83. /// Only SqlServer
  84. /// </summary>
  85. /// <param name="transactionName"></param>
  86. public override void BeginTran(string transactionName)
  87. {
  88. ((OracleConnection)this.Connection).BeginTransaction();
  89. }
  90. /// <summary>
  91. /// Only SqlServer
  92. /// </summary>
  93. /// <param name="iso"></param>
  94. /// <param name="transactionName"></param>
  95. public override void BeginTran(IsolationLevel iso, string transactionName)
  96. {
  97. ((OracleConnection)this.Connection).BeginTransaction(iso);
  98. }
  99. public override IDataAdapter GetAdapter()
  100. {
  101. return new MyOracleDataAdapter();
  102. }
  103. public override DbCommand GetCommand(string sql, SugarParameter[] parameters)
  104. {
  105. sql = ReplaceKeyWordParameterName(sql, parameters);
  106. if (sql?.EndsWith(";")==true&& sql?.TrimStart()?.StartsWith("begin")!=true)
  107. {
  108. sql=sql.TrimEnd(';');
  109. }
  110. OracleCommand sqlCommand = new OracleCommand(sql, (OracleConnection)this.Connection);
  111. sqlCommand.BindByName = true;
  112. sqlCommand.CommandType = this.CommandType;
  113. sqlCommand.CommandTimeout = this.CommandTimeOut;
  114. sqlCommand.InitialLONGFetchSize = -1;
  115. if (this.Transaction != null)
  116. {
  117. sqlCommand.Transaction = (OracleTransaction)this.Transaction;
  118. }
  119. if (parameters.HasValue())
  120. {
  121. IDataParameter[] ipars = ToIDbDataParameter(parameters);
  122. sqlCommand.Parameters.AddRange((OracleParameter[])ipars);
  123. }
  124. CheckConnection();
  125. return sqlCommand;
  126. }
  127. private static string[] KeyWord = new string[] { ":index","@index","@order", ":order", "@user", "@level", ":user", ":level", ":type", "@type",":year","@year","@date",":date" };
  128. private static string ReplaceKeyWordParameterName(string sql, SugarParameter[] parameters)
  129. {
  130. sql = ReplaceKeyWordWithAd(sql, parameters);
  131. if (parameters.HasValue())
  132. {
  133. foreach (var Parameter in parameters.OrderByDescending(x=>x.ParameterName?.Length))
  134. {
  135. if (Parameter.ParameterName != null && Parameter.ParameterName.ToLower().IsContainsStartWithIn(KeyWord))
  136. {
  137. if (parameters.Count(it => it.ParameterName.StartsWith(Parameter.ParameterName)) == 1)
  138. {
  139. var newName = Parameter.ParameterName + "_01";
  140. newName = newName.Insert(1, "KW");
  141. sql = Regex.Replace(sql, Parameter.ParameterName, newName, RegexOptions.IgnoreCase);
  142. Parameter.ParameterName = newName;
  143. }
  144. else if(Parameter.ParameterName.ToLower().IsContainsIn(KeyWord))
  145. {
  146. Check.ExceptionEasy($" {Parameter.ParameterName} is key word", $"{Parameter.ParameterName}是关键词");
  147. }
  148. }
  149. }
  150. }
  151. return sql;
  152. }
  153. private static string ReplaceKeyWordWithAd(string sql, SugarParameter[] parameters)
  154. {
  155. if (parameters != null && sql != null&&sql.Contains("@"))
  156. {
  157. foreach (var item in parameters.OrderByDescending(it => it.ParameterName.Length))
  158. {
  159. if (item.ParameterName.StartsWith("@"))
  160. {
  161. item.ParameterName = ":"+item.ParameterName.TrimStart('@');
  162. }
  163. sql = Regex.Replace(sql,"@" + item.ParameterName.TrimStart(':'),item.ParameterName,RegexOptions.IgnoreCase);
  164. }
  165. }
  166. return sql;
  167. }
  168. public override Action<SqlSugarException> ErrorEvent => it =>
  169. {
  170. if (base.ErrorEvent != null)
  171. {
  172. base.ErrorEvent(it);
  173. }
  174. if (it.Message != null && it.Message.Contains("无效的主机/绑定变量名"))
  175. {
  176. Check.ExceptionEasy(it.Message, $"错误:{it.Message},出现这个错的原因: 1.可能是参数名为关键词(例如 @user )2. SQL错误。");
  177. }
  178. };
  179. public override void SetCommandToAdapter(IDataAdapter dataAdapter, DbCommand command)
  180. {
  181. ((MyOracleDataAdapter)dataAdapter).SelectCommand = (OracleCommand)command;
  182. }
  183. /// <summary>
  184. /// if mysql return MySqlParameter[] pars
  185. /// if sqlerver return SqlParameter[] pars ...
  186. /// </summary>
  187. /// <param name="parameters"></param>
  188. /// <returns></returns>
  189. public override IDataParameter[] ToIDbDataParameter(params SugarParameter[] parameters)
  190. {
  191. if (parameters == null || parameters.Length == 0) return null;
  192. OracleParameter[] result = new OracleParameter[parameters.Length];
  193. int index = 0;
  194. var isVarchar = this.Context.IsVarchar();
  195. foreach (var parameter in parameters)
  196. {
  197. if (parameter.Value == null) parameter.Value = DBNull.Value;
  198. var sqlParameter = new OracleParameter();
  199. sqlParameter.Size = parameter.Size == -1 ? 0 : parameter.Size;
  200. sqlParameter.ParameterName = parameter.ParameterName;
  201. if (sqlParameter.ParameterName[0] == '@')
  202. {
  203. sqlParameter.ParameterName = ':' + sqlParameter.ParameterName.Substring(1, sqlParameter.ParameterName.Length - 1);
  204. }
  205. if (this.CommandType == CommandType.StoredProcedure)
  206. {
  207. sqlParameter.ParameterName = sqlParameter.ParameterName.TrimStart(':');
  208. }
  209. if (parameter.IsRefCursor)
  210. {
  211. sqlParameter.OracleDbType = OracleDbType.RefCursor;
  212. }
  213. if (parameter.IsNvarchar2&& parameter.DbType==System.Data.DbType.String)
  214. {
  215. sqlParameter.OracleDbType = OracleDbType.NVarchar2;
  216. }
  217. if (parameter.IsClob)
  218. {
  219. sqlParameter.OracleDbType = OracleDbType.Clob;
  220. sqlParameter.Value = parameter.Value;
  221. }
  222. if (parameter.IsNClob)
  223. {
  224. sqlParameter.OracleDbType = OracleDbType.NClob;
  225. sqlParameter.Value = parameter.Value;
  226. }
  227. if (parameter.IsArray)
  228. {
  229. sqlParameter.OracleDbType = OracleDbType.Varchar2;
  230. sqlParameter.CollectionType = OracleCollectionType.PLSQLAssociativeArray;
  231. }
  232. if (sqlParameter.DbType == System.Data.DbType.Guid)
  233. {
  234. sqlParameter.DbType = System.Data.DbType.String;
  235. sqlParameter.Value = sqlParameter.Value.ObjToString();
  236. }
  237. else if (parameter.DbType == System.Data.DbType.DateTimeOffset)
  238. {
  239. if (parameter.Value != DBNull.Value)
  240. sqlParameter.Value = UtilMethods.ConvertFromDateTimeOffset((DateTimeOffset)parameter.Value);
  241. sqlParameter.DbType = System.Data.DbType.DateTime;
  242. }
  243. else if (parameter.DbType == System.Data.DbType.Boolean)
  244. {
  245. sqlParameter.DbType = System.Data.DbType.Int16;
  246. if (parameter.Value == DBNull.Value)
  247. {
  248. parameter.Value = 0;
  249. }
  250. else
  251. {
  252. sqlParameter.Value = (bool)parameter.Value ? 1 : 0;
  253. }
  254. }
  255. else if (parameter.DbType == System.Data.DbType.DateTime)
  256. {
  257. sqlParameter.Value = parameter.Value;
  258. sqlParameter.DbType = System.Data.DbType.DateTime;
  259. }
  260. else if (parameter.DbType == System.Data.DbType.Date)
  261. {
  262. sqlParameter.Value = parameter.Value;
  263. sqlParameter.DbType = System.Data.DbType.Date;
  264. }
  265. else if (parameter.DbType == System.Data.DbType.AnsiStringFixedLength)
  266. {
  267. sqlParameter.DbType = System.Data.DbType.AnsiStringFixedLength;
  268. sqlParameter.Value = parameter.Value;
  269. }
  270. else if (parameter.DbType == System.Data.DbType.AnsiString)
  271. {
  272. sqlParameter.DbType = System.Data.DbType.AnsiString;
  273. sqlParameter.Value = parameter.Value;
  274. }
  275. else if (parameter.DbType == System.Data.DbType.UInt32)
  276. {
  277. sqlParameter.DbType = System.Data.DbType.Int32;
  278. sqlParameter.Value = parameter.Value;
  279. }
  280. else if (parameter.DbType == System.Data.DbType.UInt16)
  281. {
  282. sqlParameter.DbType = System.Data.DbType.Int16;
  283. sqlParameter.Value = parameter.Value;
  284. }
  285. else if (parameter.DbType == System.Data.DbType.UInt64)
  286. {
  287. sqlParameter.DbType = System.Data.DbType.Int64;
  288. sqlParameter.Value = parameter.Value;
  289. }
  290. else
  291. {
  292. if (parameter.Value != null && parameter.Value.GetType() == UtilConstants.GuidType)
  293. {
  294. parameter.Value = parameter.Value.ToString();
  295. }
  296. sqlParameter.Value = parameter.Value;
  297. }
  298. if (parameter.Direction != 0)
  299. sqlParameter.Direction = parameter.Direction;
  300. result[index] = sqlParameter;
  301. if (sqlParameter.Direction.IsIn(ParameterDirection.Output, ParameterDirection.InputOutput, ParameterDirection.ReturnValue))
  302. {
  303. if (this.OutputParameters == null) this.OutputParameters = new List<IDataParameter>();
  304. this.OutputParameters.RemoveAll(it => it.ParameterName == sqlParameter.ParameterName);
  305. this.OutputParameters.Add(sqlParameter);
  306. }
  307. if (isVarchar && sqlParameter.DbType == System.Data.DbType.String)
  308. {
  309. sqlParameter.DbType = System.Data.DbType.AnsiString;
  310. }
  311. if (parameter.CustomDbType != null && parameter.CustomDbType is OracleDbType)
  312. {
  313. sqlParameter.OracleDbType = ((OracleDbType)parameter.CustomDbType);
  314. }
  315. ++index;
  316. }
  317. return result;
  318. }
  319. }
  320. }