OciStatementHandle.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. //
  2. // OciStatementHandle.cs
  3. //
  4. // Part of managed C#/.NET library System.Data.OracleClient.dll
  5. //
  6. // Part of the Mono class libraries at
  7. // mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci
  8. //
  9. // Assembly: System.Data.OracleClient.dll
  10. // Namespace: System.Data.OracleClient.Oci
  11. //
  12. // Author:
  13. // Tim Coleman <[email protected]>
  14. //
  15. // Copyright (C) Tim Coleman, 2003
  16. //
  17. using System;
  18. using System.Collections;
  19. using System.Runtime.InteropServices;
  20. namespace System.Data.OracleClient.Oci {
  21. internal sealed class OciStatementHandle : OciHandle, IDisposable
  22. {
  23. #region Fields
  24. int columnCount;
  25. bool disposed = false;
  26. OciErrorHandle errorHandle;
  27. bool moreResults;
  28. OciServiceHandle serviceHandle;
  29. ArrayList values;
  30. OracleCommand command;
  31. #endregion // Fields
  32. #region Constructors
  33. public OciStatementHandle (OciHandle parent, IntPtr handle)
  34. : base (OciHandleType.Statement, parent, handle)
  35. {
  36. moreResults = false;
  37. }
  38. #endregion // Constructors
  39. #region Properties
  40. public int ColumnCount {
  41. get { return columnCount; }
  42. }
  43. public OciErrorHandle ErrorHandle {
  44. get { return errorHandle; }
  45. set { errorHandle = value; }
  46. }
  47. public OciServiceHandle Service {
  48. get { return serviceHandle; }
  49. set { serviceHandle = value; }
  50. }
  51. public ArrayList Values {
  52. get { return values; }
  53. }
  54. public OracleCommand Command {
  55. get { return command; }
  56. set { command = value; }
  57. }
  58. #endregion // Properties
  59. #region Methods
  60. protected override void Dispose (bool disposing)
  61. {
  62. if (!disposed) {
  63. disposed = true;
  64. if (disposing) {
  65. if (values != null) {
  66. foreach (OciDefineHandle h in values)
  67. h.Dispose ();
  68. values = null;
  69. }
  70. }
  71. base.Dispose (disposing);
  72. }
  73. }
  74. public OciParameterDescriptor GetParameter (int position)
  75. {
  76. IntPtr handle = IntPtr.Zero;
  77. int status = 0;
  78. status = OciCalls.OCIParamGet (this,
  79. OciHandleType.Statement,
  80. ErrorHandle,
  81. out handle,
  82. position + 1);
  83. if (status != 0) {
  84. OciErrorInfo info = ErrorHandle.HandleError ();
  85. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  86. }
  87. OciParameterDescriptor output = new OciParameterDescriptor (this, handle);
  88. output.ErrorHandle = ErrorHandle;
  89. return output;
  90. }
  91. public OciDefineHandle GetDefineHandle (int position)
  92. {
  93. OciDefineHandle defineHandle = new OciDefineHandle (this, IntPtr.Zero);
  94. defineHandle.ErrorHandle = ErrorHandle;
  95. defineHandle.DefineByPosition (position);
  96. return defineHandle;
  97. }
  98. void Define ()
  99. {
  100. values = new ArrayList ();
  101. for (int i = 0; i < columnCount; i += 1)
  102. values.Add (GetDefineHandle (i));
  103. }
  104. public bool ExecuteQuery ()
  105. {
  106. return Execute (false,false);
  107. }
  108. public bool ExecuteNonQuery (bool useAutoCommit)
  109. {
  110. return Execute (true, useAutoCommit);
  111. }
  112. public bool Execute (bool nonQuery, bool useAutoCommit)
  113. {
  114. int status = 0;
  115. columnCount = 0;
  116. moreResults = false;
  117. int executeMode;
  118. if( useAutoCommit)
  119. executeMode = (int)OciExecuteMode.CommitOnSuccess;
  120. else
  121. executeMode = (int)OciExecuteMode.Default;
  122. if (this.disposed)
  123. {
  124. throw new InvalidOperationException ("StatementHandle is already disposed.");
  125. }
  126. status = OciCalls.OCIStmtExecute (Service,
  127. Handle,
  128. ErrorHandle,
  129. nonQuery,
  130. 0,
  131. IntPtr.Zero,
  132. IntPtr.Zero,
  133. (OciExecuteMode)executeMode);
  134. switch (status) {
  135. case OciGlue.OCI_DEFAULT:
  136. if (!nonQuery) {
  137. GetColumnCount ();
  138. Define ();
  139. moreResults = true;
  140. }
  141. break;
  142. case OciGlue.OCI_NO_DATA:
  143. break;
  144. case OciGlue.OCI_INVALID_HANDLE:
  145. throw new OracleException (0, "Invalid handle.");
  146. default:
  147. OciErrorInfo info = ErrorHandle.HandleError ();
  148. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  149. }
  150. return true;
  151. }
  152. void GetColumnCount ()
  153. {
  154. columnCount = GetAttributeInt32 (OciAttributeType.ParameterCount, ErrorHandle);
  155. }
  156. public OciStatementType GetStatementType ()
  157. {
  158. return (OciStatementType) GetAttributeInt32 (OciAttributeType.StatementType, ErrorHandle);
  159. }
  160. public bool Fetch ()
  161. {
  162. int status = 0;
  163. if (this.disposed)
  164. {
  165. throw new InvalidOperationException ("StatementHandle is already disposed.");
  166. }
  167. status = OciCalls.OCIStmtFetch (Handle,
  168. ErrorHandle.Handle,
  169. 1,
  170. 2,
  171. 0);
  172. switch (status) {
  173. case OciGlue.OCI_NO_DATA:
  174. moreResults = false;
  175. break;
  176. case OciGlue.OCI_DEFAULT:
  177. moreResults = true;
  178. break;
  179. case OciGlue.OCI_SUCCESS_WITH_INFO:
  180. //OciErrorInfo ei = ErrorHandle.HandleError ();
  181. //command.Connection.CreateInfoMessage (ei);
  182. moreResults = true;
  183. break;
  184. default:
  185. OciErrorInfo info = ErrorHandle.HandleError ();
  186. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  187. }
  188. return moreResults;
  189. }
  190. public void Prepare (string commandText)
  191. {
  192. int status = 0;
  193. if (this.disposed) {
  194. throw new InvalidOperationException ("StatementHandle is already disposed.");
  195. }
  196. int rsize = 0;
  197. byte [] buffer;
  198. // Get size of buffer
  199. OciCalls.OCIUnicodeToCharSet (Parent, null, commandText, out rsize);
  200. // Fill buffer
  201. buffer = new byte[rsize];
  202. OciCalls.OCIUnicodeToCharSet (Parent, buffer, commandText, out rsize);
  203. // Execute statement
  204. status = OciCalls.OCIStmtPrepare (this,
  205. ErrorHandle,
  206. buffer,
  207. buffer.Length,
  208. OciStatementLanguage.NTV,
  209. OciStatementMode.Default);
  210. if (status != 0) {
  211. OciErrorInfo info = ErrorHandle.HandleError ();
  212. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  213. }
  214. }
  215. #endregion // Methods
  216. }
  217. }