OciStatementHandle.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  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, IOciHandle, IDisposable
  22. {
  23. #region Fields
  24. OciStatementLanguage language;
  25. OciStatementMode mode;
  26. OciServiceHandle serviceHandle;
  27. OciErrorHandle errorHandle;
  28. ArrayList values;
  29. ArrayList parameters;
  30. bool moreResults;
  31. int columnCount;
  32. #endregion // Fields
  33. #region Constructors
  34. public OciStatementHandle (OciEnvironmentHandle environment, IntPtr handle)
  35. : base (OciHandleType.Statement, environment, handle)
  36. {
  37. parameters = new ArrayList ();
  38. language = OciStatementLanguage.NTV;
  39. mode = OciStatementMode.Default;
  40. moreResults = false;
  41. }
  42. #endregion // Constructors
  43. #region Properties
  44. public int ColumnCount {
  45. get { return columnCount; }
  46. }
  47. public OciErrorHandle ErrorHandle {
  48. get { return errorHandle; }
  49. set { errorHandle = value; }
  50. }
  51. public OciStatementLanguage Language {
  52. get { return language; }
  53. set { language = value; }
  54. }
  55. public OciServiceHandle Service {
  56. get { return serviceHandle; }
  57. set { serviceHandle = value; }
  58. }
  59. public ArrayList Values {
  60. get { return values; }
  61. }
  62. #endregion // Properties
  63. #region Methods
  64. [DllImport ("oci")]
  65. public static extern int OCIDescriptorFree (IntPtr descp,
  66. [MarshalAs (UnmanagedType.U4)] OciDescriptorType type);
  67. [DllImport ("oci")]
  68. public static extern int OCIParamGet (IntPtr hndlp,
  69. [MarshalAs (UnmanagedType.U4)] OciHandleType htype,
  70. IntPtr errhp,
  71. out IntPtr parmdpp,
  72. [MarshalAs (UnmanagedType.U4)] int pos);
  73. [DllImport ("oci")]
  74. public static extern int OCIStmtExecute (IntPtr svchp,
  75. IntPtr stmthp,
  76. IntPtr errhp,
  77. [MarshalAs (UnmanagedType.U4)] bool iters,
  78. uint rowoff,
  79. IntPtr snap_in,
  80. IntPtr snap_out,
  81. [MarshalAs (UnmanagedType.U4)] OciExecuteMode mode);
  82. [DllImport ("oci")]
  83. public static extern int OCIStmtFetch (IntPtr stmtp,
  84. IntPtr errhp,
  85. uint nrows,
  86. ushort orientation,
  87. uint mode);
  88. [DllImport ("oci")]
  89. public static extern int OCIStmtPrepare (IntPtr stmthp,
  90. IntPtr errhp,
  91. string stmt,
  92. [MarshalAs (UnmanagedType.U4)] int stmt_length,
  93. [MarshalAs (UnmanagedType.U4)] OciStatementLanguage language,
  94. [MarshalAs (UnmanagedType.U4)] OciStatementMode mode);
  95. public IntPtr CreateParameterHandle (int position)
  96. {
  97. IntPtr handle = IntPtr.Zero;
  98. int status = 0;
  99. status = OCIParamGet (Handle,
  100. OciHandleType.Statement,
  101. ErrorHandle.Handle,
  102. out handle,
  103. position);
  104. if (status != 0) {
  105. OciErrorInfo info = ErrorHandle.HandleError ();
  106. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  107. }
  108. return handle;
  109. }
  110. public void FreeBindHandle (IntPtr handle)
  111. {
  112. int status = 0;
  113. //status = OCIDescriptorFree (handle, OciDescriptorType.Parameter);
  114. if (status != 0) {
  115. OciErrorInfo info = ErrorHandle.HandleError ();
  116. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  117. }
  118. }
  119. public void FreeParameterHandle (IntPtr handle)
  120. {
  121. int status = 0;
  122. status = OCIDescriptorFree (handle, OciDescriptorType.Parameter);
  123. if (status != 0) {
  124. OciErrorInfo info = ErrorHandle.HandleError ();
  125. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  126. }
  127. }
  128. void Define ()
  129. {
  130. values = new ArrayList ();
  131. for (int i = 0; i < columnCount; i += 1)
  132. values.Add (new OciDefineHandle (this, i + 1));
  133. }
  134. public void Dispose ()
  135. {
  136. Environment.FreeHandle (this);
  137. }
  138. public bool ExecuteQuery ()
  139. {
  140. return Execute (false);
  141. }
  142. public bool ExecuteNonQuery ()
  143. {
  144. return Execute (true);
  145. }
  146. public bool Execute (bool nonQuery)
  147. {
  148. int status = 0;
  149. columnCount = 0;
  150. moreResults = false;
  151. status = OCIStmtExecute (Service.Handle,
  152. Handle,
  153. ErrorHandle.Handle,
  154. nonQuery,
  155. 0,
  156. IntPtr.Zero,
  157. IntPtr.Zero,
  158. OciExecuteMode.Default);
  159. switch (status) {
  160. case OciGlue.OCI_DEFAULT:
  161. if (!nonQuery) {
  162. GetColumnCount ();
  163. Define ();
  164. moreResults = true;
  165. }
  166. break;
  167. case OciGlue.OCI_NO_DATA:
  168. break;
  169. default:
  170. OciErrorInfo info = ErrorHandle.HandleError ();
  171. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  172. }
  173. return true;
  174. }
  175. void GetColumnCount ()
  176. {
  177. int status = 0;
  178. status = OciGlue.OCIAttrGetInt32 ( Handle,
  179. (uint) OciHandleType.Statement,
  180. out columnCount,
  181. IntPtr.Zero,
  182. OciAttributeType.ParameterCount,
  183. ErrorHandle.Handle);
  184. if (status != 0) {
  185. OciErrorInfo info = ErrorHandle.HandleError ();
  186. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  187. }
  188. }
  189. public bool GetAttributeBool (IntPtr handle, OciAttributeType type)
  190. {
  191. bool output;
  192. int status = 0;
  193. status = OciGlue.OCIAttrGetBool (handle,
  194. (uint) OciDescriptorType.Parameter,
  195. out output,
  196. IntPtr.Zero,
  197. type,
  198. ErrorHandle.Handle);
  199. if (status != 0) {
  200. OciErrorInfo info = ErrorHandle.HandleError ();
  201. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  202. }
  203. return output;
  204. }
  205. public sbyte GetAttributeSByte (IntPtr handle, OciAttributeType type) {
  206. sbyte output;
  207. int status = 0;
  208. status = OciGlue.OCIAttrGetSByte (handle,
  209. (uint) OciDescriptorType.Parameter,
  210. out output,
  211. IntPtr.Zero,
  212. type,
  213. ErrorHandle.Handle);
  214. if (status != 0) {
  215. OciErrorInfo info = ErrorHandle.HandleError ();
  216. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  217. }
  218. return output;
  219. }
  220. public byte GetAttributeByte (IntPtr handle, OciAttributeType type)
  221. {
  222. byte output;
  223. int status = 0;
  224. status = OciGlue.OCIAttrGetByte (handle,
  225. (uint) OciDescriptorType.Parameter,
  226. out output,
  227. IntPtr.Zero,
  228. type,
  229. ErrorHandle.Handle);
  230. if (status != 0) {
  231. OciErrorInfo info = ErrorHandle.HandleError ();
  232. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  233. }
  234. return output;
  235. }
  236. public ushort GetAttributeUInt16 (IntPtr handle, OciAttributeType type) {
  237. int status = 0;
  238. ushort output;
  239. status = OciGlue.OCIAttrGetUInt16 (handle,
  240. (uint) OciDescriptorType.Parameter,
  241. out output,
  242. IntPtr.Zero,
  243. type,
  244. ErrorHandle.Handle);
  245. if (status != 0) {
  246. OciErrorInfo info = ErrorHandle.HandleError ();
  247. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  248. }
  249. return output;
  250. }
  251. public int GetAttributeInt32 (IntPtr handle, OciAttributeType type)
  252. {
  253. int status = 0;
  254. int output;
  255. status = OciGlue.OCIAttrGetInt32 (handle,
  256. (uint) OciDescriptorType.Parameter,
  257. out output,
  258. IntPtr.Zero,
  259. type,
  260. ErrorHandle.Handle);
  261. if (status != 0) {
  262. OciErrorInfo info = ErrorHandle.HandleError ();
  263. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  264. }
  265. return output;
  266. }
  267. [MonoTODO]
  268. public string GetAttributeString (IntPtr handle, OciAttributeType type)
  269. {
  270. string output = String.Empty;
  271. IntPtr outputPtr = IntPtr.Zero;
  272. int outSize;
  273. int status = 0;
  274. status = OciGlue.OCIAttrGet (handle,
  275. (uint) OciDescriptorType.Parameter,
  276. out outputPtr,
  277. out outSize,
  278. type,
  279. ErrorHandle.Handle);
  280. if (status != 0) {
  281. OciErrorInfo info = ErrorHandle.HandleError ();
  282. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  283. }
  284. if (outputPtr != IntPtr.Zero && outSize > 0) {
  285. object name = Marshal.PtrToStringAnsi (outputPtr, outSize);
  286. if (name != null) {
  287. output = String.Copy ((string) name);
  288. /* TRWC
  289. * We shouldn't really free this, but how can we make Oracle
  290. * do it?
  291. */
  292. // Marshal.FreeHGlobal (outputPtr); -- this *may* leak memory
  293. }
  294. }
  295. return output;
  296. }
  297. [MonoTODO]
  298. public OciColumnInfo DescribeColumn (int ordinal)
  299. {
  300. int status = 0;
  301. OciColumnInfo columnInfo;
  302. string schemaName;
  303. IntPtr parameterHandle = CreateParameterHandle (ordinal + 1);
  304. columnInfo.ColumnName = GetAttributeString (parameterHandle, OciAttributeType.Name);
  305. columnInfo.ColumnOrdinal = ordinal + 1;
  306. columnInfo.ColumnSize = GetAttributeUInt16 (parameterHandle, OciAttributeType.DataSize);
  307. columnInfo.Precision = GetAttributeByte (parameterHandle, OciAttributeType.Precision);
  308. columnInfo.Scale = GetAttributeSByte (parameterHandle, OciAttributeType.Scale);
  309. columnInfo.DataType = (OciDataType) GetAttributeInt32 (parameterHandle, OciAttributeType.DataType);
  310. columnInfo.AllowDBNull = GetAttributeBool (parameterHandle, OciAttributeType.IsNull);
  311. columnInfo.BaseColumnName = GetAttributeString (parameterHandle, OciAttributeType.Name);
  312. // TRWC not sure what to do with this yet.
  313. schemaName = GetAttributeString (parameterHandle, OciAttributeType.SchemaName);
  314. FreeParameterHandle (parameterHandle);
  315. return columnInfo;
  316. }
  317. public OciStatementType GetStatementType ()
  318. {
  319. int status = 0;
  320. int statementType;
  321. status = OciGlue.OCIAttrGetInt32 (Handle,
  322. (uint) OciHandleType.Statement,
  323. out statementType,
  324. IntPtr.Zero,
  325. OciAttributeType.StatementType,
  326. errorHandle.Handle);
  327. if (status != 0) {
  328. OciErrorInfo info = ErrorHandle.HandleError ();
  329. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  330. }
  331. return (OciStatementType) statementType;
  332. }
  333. public bool Fetch ()
  334. {
  335. int status = 0;
  336. status = OCIStmtFetch (Handle,
  337. ErrorHandle.Handle,
  338. 1,
  339. 2,
  340. 0);
  341. switch (status) {
  342. case OciGlue.OCI_NO_DATA:
  343. moreResults = false;
  344. break;
  345. case OciGlue.OCI_DEFAULT:
  346. moreResults = true;
  347. break;
  348. default:
  349. OciErrorInfo info = ErrorHandle.HandleError ();
  350. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  351. }
  352. return moreResults;
  353. }
  354. public void Prepare (string commandText)
  355. {
  356. int status = 0;
  357. status = OCIStmtPrepare (Handle,
  358. errorHandle.Handle,
  359. commandText,
  360. commandText.Length,
  361. language,
  362. mode);
  363. if (status != 0) {
  364. OciErrorInfo info = ErrorHandle.HandleError ();
  365. throw new OracleException (info.ErrorCode, info.ErrorMessage);
  366. }
  367. }
  368. #endregion // Methods
  369. }
  370. }