4 // Part of the Mono class libraries at
5 // mcs/class/System.Data.OracleClient/System.Data.OracleClient
7 // Assembly: System.Data.OracleClient.dll
8 // Namespace: System.Data.OracleClient
11 // Tim Coleman <tim@timcoleman.com>
12 // Daniel Moragn <monodanmorg@yahoo.com>
13 // Hubert FONGARNAND <informatique.internet@fiducial.fr>
15 // Copyright (C) Tim Coleman , 2003
16 // Copyright (C) Daniel Morgan, 2005, 2008
17 // Copyright (C) Hubert FONGARNAND, 2005
19 // Licensed under the MIT/X11 License.
23 using System.Collections;
24 using System.ComponentModel;
27 using System.Data.Common;
29 using System.Data.SqlTypes;
30 using System.Data.OracleClient.Oci;
31 using System.Globalization;
32 using System.Runtime.InteropServices;
35 namespace System.Data.OracleClient
37 [TypeConverter (typeof(OracleParameter.OracleParameterConverter))]
38 public sealed class OracleParameter :
40 DbParameter, IDbDataParameter, ICloneable
42 MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
48 OracleType oracleType = OracleType.VarChar;
51 ParameterDirection direction = ParameterDirection.Input;
57 bool sourceColumnNullMapping;
59 DataRowVersion srcVersion;
60 DbType dbType = DbType.AnsiString;
63 object value = DBNull.Value;
64 OciLobLocator lobLocator; // only if Blob or Clob
65 IntPtr bindOutValue = IntPtr.Zero;
66 OciDateTimeDescriptor dateTimeDesc;
67 IntPtr cursor = IntPtr.Zero;
69 OracleParameterCollection container;
70 OciBindHandle bindHandle;
71 //OciErrorHandle errorHandle;
72 OracleConnection connection;
74 IntPtr bindValue = IntPtr.Zero;
78 short indicator; // TODO: handle indicator to indicate NULL value for OUT parameters
86 // constructor for cloning the object
87 internal OracleParameter (OracleParameter value)
89 this.name = value.name;
90 this.oracleType = value.oracleType;
91 this.ociType = value.ociType;
92 this.size = value.size;
93 this.direction = value.direction;
94 this.isNullable = value.isNullable;
95 this.precision = value.precision;
96 this.scale = value.scale;
97 this.srcColumn = value.srcColumn;
98 this.srcVersion = value.srcVersion;
99 this.dbType = value.dbType;
100 this.offset = value.offset;
101 this.sizeSet = value.sizeSet;
102 this.value = value.value;
103 this.lobLocator = value.lobLocator;
106 public OracleParameter ()
107 : this (String.Empty, OracleType.VarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
111 public OracleParameter (string name, object value)
115 srcColumn = string.Empty;
116 SourceVersion = DataRowVersion.Current;
117 InferOracleType (value);
120 public OracleParameter (string name, OracleType oracleType)
121 : this (name, oracleType, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
125 public OracleParameter (string name, OracleType oracleType, int size)
126 : this (name, oracleType, size, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
130 public OracleParameter (string name, OracleType oracleType, int size, string srcColumn)
131 : this (name, oracleType, size, ParameterDirection.Input, false, 0, 0, srcColumn, DataRowVersion.Current, null)
136 public OracleParameter (string name, OracleType oracleType, int size, ParameterDirection direction, string sourceColumn, DataRowVersion sourceVersion, bool sourceColumnNullMapping, object value)
140 throw new ArgumentException("Size must be not be negative.");
143 SourceColumnNullMapping = sourceColumnNullMapping;
144 OracleType = oracleType;
145 Direction = direction;
146 SourceColumn = sourceColumn;
147 SourceVersion = sourceVersion;
151 public OracleParameter (string name, OracleType oracleType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string srcColumn, DataRowVersion srcVersion, object value)
155 throw new ArgumentException("Size must be not be negative.");
158 this.isNullable = isNullable;
159 this.precision = precision;
162 OracleType = oracleType;
163 Direction = direction;
164 SourceColumn = srcColumn;
165 SourceVersion = srcVersion;
168 #endregion // Constructors
172 internal OracleParameterCollection Container {
173 get { return container; }
174 set { container = value; }
179 [RefreshProperties (RefreshProperties.All)]
180 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
187 get { return dbType; }
188 set { SetDbType (value); }
192 [DefaultValue (ParameterDirection.Input)]
194 [RefreshProperties (RefreshProperties.All)]
199 ParameterDirection Direction {
200 get { return direction; }
201 set { direction = value; }
207 [DefaultValue (false)]
208 [EditorBrowsable (EditorBrowsableState.Never)]
215 get { return isNullable; }
216 set { isNullable = value; }
220 [EditorBrowsable (EditorBrowsableState.Advanced)]
226 get { return offset; }
227 set { offset = value; }
230 [DefaultValue (OracleType.VarChar)]
231 [RefreshProperties (RefreshProperties.All)]
233 [DbProviderSpecificTypeProperty (true)]
235 public OracleType OracleType {
236 get { return oracleType; }
237 set { SetOracleType (value); }
247 string ParameterName {
253 set { name = value; }
258 [EditorBrowsable (EditorBrowsableState.Never)]
259 [Obsolete("Set the precision of a decimal use the Math classes.")]
263 public byte Precision {
264 get { return precision; }
265 set { /* NO EFFECT*/ }
270 [EditorBrowsable (EditorBrowsableState.Never)]
271 [Obsolete("Set the precision of a decimal use the Math classes.")]
276 get { return scale; }
277 set { /* NO EFFECT*/ }
302 string SourceColumn {
303 get { return srcColumn; }
304 set { srcColumn = value; }
309 public override bool SourceColumnNullMapping {
310 get { return sourceColumnNullMapping; }
311 set { sourceColumnNullMapping = value; }
316 [DefaultValue ("Current")]
322 DataRowVersion SourceVersion {
323 get { return srcVersion; }
324 set { srcVersion = value; }
328 [DefaultValue (null)]
330 [RefreshProperties (RefreshProperties.All)]
331 [TypeConverter (typeof(StringConverter))]
332 [MonoTODO("InferOracleType is not always needed")]
338 get { return this.value; }
341 InferOracleType (value);
345 #endregion // Properties
349 private void AssertSizeIsSet ()
352 case OciDataType.VarChar2:
353 case OciDataType.String:
354 case OciDataType.VarChar:
355 case OciDataType.Char:
356 case OciDataType.CharZ:
357 case OciDataType.OciString:
359 throw new Exception ("Size must be set.");
366 internal void Bind (OciStatementHandle statement, OracleConnection con, uint pos)
370 if (bindHandle == null)
371 bindHandle = new OciBindHandle ((OciHandle) statement);
373 IntPtr tmpHandle = bindHandle.Handle;
375 if (Direction != ParameterDirection.Input)
386 string svalue = null;
388 DateTime dt = DateTime.MinValue;
391 if (direction == ParameterDirection.Input || direction == ParameterDirection.InputOutput) {
394 else if (v is DBNull)
397 INullable mynullable = v as INullable;
398 if (mynullable != null)
399 isnull = mynullable.IsNull;
403 if (isnull == true && direction == ParameterDirection.Input) {
405 bindType = OciDataType.VarChar2;
409 case OciDataType.VarChar2:
410 case OciDataType.String:
411 case OciDataType.VarChar:
412 case OciDataType.Char:
413 case OciDataType.CharZ:
414 case OciDataType.OciString:
415 bindType = OciDataType.String;
418 // convert value from managed type to type to marshal
419 if (direction == ParameterDirection.Input ||
420 direction == ParameterDirection.InputOutput) {
422 svalue = v.ToString () + '\0';
425 // set bind length to size of data
426 bindSize = (size + 1) * 4;
428 // allocate memory based on bind length
429 bytes = new byte[bindSize];
431 if (direction == ParameterDirection.Input ||
432 direction == ParameterDirection.InputOutput) {
434 // convert managed type to memory allocated earlier
435 // in this case using OCIUnicodeToCharSet
437 // Get size of buffer
438 status = OciCalls.OCIUnicodeToCharSet (statement.Parent, null, svalue, out rsize);
440 status = OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);
443 case OciDataType.Date:
444 bindType = OciDataType.Date;
446 // convert value from managed type to type to marshal
447 if (direction == ParameterDirection.Input ||
448 direction == ParameterDirection.InputOutput) {
451 bytes = new byte [7];
454 dt = DateTime.MinValue;
457 dt = DateTime.Parse (sDate);
459 else if (v is DateTime)
461 else if (v is OracleString) {
462 sDate = v.ToString ();
463 dt = DateTime.Parse (sDate);
465 else if (v is OracleDateTime) {
466 OracleDateTime odt = (OracleDateTime) v;
467 dt = (DateTime) odt.Value;
470 throw new NotImplementedException ("For OracleType.DateTime, data type not implemented: " + v.GetType().ToString() + ".");
472 // for Input and InputOuput, create byte array and pack DateTime into it
473 bytes = PackDate (dt);
476 // allocate 7-byte array for Output and ReturnValue to put date
477 bytes = new byte [7];
480 case OciDataType.Number:
481 bindType = OciDataType.String;
484 // define size for binding
485 bindSize = 30; // a NUMBER is 22 bytes but as a string we need more
487 bytes = new byte [bindSize];
488 // convert value from managed type to type to marshal
489 if (direction == ParameterDirection.Input ||
490 direction == ParameterDirection.InputOutput) {
493 if(v is IFormattable)
494 svalue = ((IFormattable)v).ToString (null, con.SessionFormatProvider);
495 else if (v is OracleNumber)
496 svalue = ((OracleNumber)v).ToString(con.SessionFormatProvider);
498 svalue = v.ToString();
500 svalue = svalue + "\0";
503 // Get size of buffer
504 OciCalls.OCIUnicodeToCharSet (statement.Parent, null, svalue, out rsize);
507 bytes = new byte [bindSize];
508 OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);
511 case OciDataType.Long:
512 case OciDataType.LongVarChar:
513 bindType = OciDataType.LongVarChar;
515 // FIXME: use piecewise fetching for Long, Clob, Blob, and Long Raw
516 // See http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci05bnd.htm#sthref724
518 bindSize = Size + 5; // 4 bytes prepended for length, bytes, 1 byte NUL character
522 // convert value from managed type to type to marshal
523 if (direction == ParameterDirection.Input ||
524 direction == ParameterDirection.InputOutput) {
526 svalue = v.ToString () + '\0';
529 bytes = new byte [bindSize];
531 ASCIIEncoding enc = new ASCIIEncoding ();
533 if (direction == ParameterDirection.Input ||
534 direction == ParameterDirection.InputOutput) {
536 if (svalue.Length > 0) {
537 byteCount = enc.GetBytes (svalue, 4, svalue.Length, bytes, 0);
538 // LONG VARCHAR prepends a 4-byte length
540 byte[] byteArrayLen = BitConverter.GetBytes ((uint) byteCount);
541 bytes[0] = byteArrayLen[0];
542 bytes[1] = byteArrayLen[1];
543 bytes[2] = byteArrayLen[2];
544 bytes[3] = byteArrayLen[3];
550 // FIXME: move this up - see how Char, Number, and Date are done...
551 if (direction == ParameterDirection.Output ||
552 direction == ParameterDirection.InputOutput ||
553 direction == ParameterDirection.ReturnValue) {
556 case OciDataType.RowIdDescriptor:
558 bindType = OciDataType.Char;
560 bindOutValue = OciCalls.AllocateClear (bindSize);
561 bindValue = bindOutValue;
563 case OciDataType.TimeStamp:
564 dateTimeDesc = (OciDateTimeDescriptor) connection.Environment.Allocate (OciHandleType.TimeStamp);
565 if (dateTimeDesc == null) {
566 OciErrorInfo info = connection.ErrorHandle.HandleError ();
567 throw new OracleException (info.ErrorCode, info.ErrorMessage);
569 dateTimeDesc.ErrorHandle = connection.ErrorHandle;
571 bindType = OciDataType.TimeStamp;
572 bindOutValue = dateTimeDesc.Handle;
573 bindValue = dateTimeDesc.Handle;
576 case OciDataType.Blob:
577 case OciDataType.Clob:
579 lobLocator = (OciLobLocator) connection.Environment.Allocate (OciHandleType.LobLocator);
580 if (lobLocator == null) {
581 OciErrorInfo info = connection.ErrorHandle.HandleError ();
582 throw new OracleException (info.ErrorCode, info.ErrorMessage);
584 bindOutValue = lobLocator.Handle;
585 bindValue = lobLocator.Handle;
586 lobLocator.ErrorHandle = connection.ErrorHandle;
587 lobLocator.Service = statement.Service;
590 case OciDataType.RSet: // REF CURSOR
591 cursor = IntPtr.Zero;
592 OciCalls.OCIHandleAlloc (connection.Environment,
594 OciHandleType.Statement,
599 bindType = OciDataType.RSet;
602 // define other types
603 throw new NotImplementedException ("Data Type not implemented: " + ociType.ToString() + ".");
604 } // switch of ociDataType for output
605 bindValue = bindOutValue;
607 else if ((v == DBNull.Value || v == null || isnull == true) && direction == ParameterDirection.Input) {
609 bindType = OciDataType.VarChar2;
614 dt = DateTime.MinValue;
615 if (oracleType == OracleType.Timestamp){
616 bindType = OciDataType.TimeStamp;
618 dt = DateTime.MinValue;
622 dt = DateTime.Parse (sDate);
624 else if (v is DateTime)
626 else if (v is OracleString){
628 dt = DateTime.Parse (sDate);
630 else if (v is OracleDateTime) {
631 OracleDateTime odt = (OracleDateTime) v;
632 dt = (DateTime) odt.Value;
635 throw new NotImplementedException ("For OracleType.Timestamp, data type not implemented: " + v.GetType().ToString()); // ?
637 short year = (short) dt.Year;
638 byte month = (byte) dt.Month;
639 byte day = (byte) dt.Day;
640 byte hour = (byte) dt.Hour;
641 byte min = (byte) dt.Minute;
642 byte sec = (byte) dt.Second;
643 uint fsec = (uint) dt.Millisecond;
644 string timezone = "";
645 dateTimeDesc = (OciDateTimeDescriptor) connection.Environment.Allocate (OciHandleType.TimeStamp);
646 if (dateTimeDesc == null) {
647 OciErrorInfo info = connection.ErrorHandle.HandleError ();
648 throw new OracleException (info.ErrorCode, info.ErrorMessage);
650 dateTimeDesc.ErrorHandle = connection.ErrorHandle;
651 dateTimeDesc.SetDateTime (connection.Session,
652 connection.ErrorHandle,
653 year, month, day, hour, min, sec, fsec,
657 else if (oracleType == OracleType.Blob) {
659 bindType = OciDataType.LongRaw;
660 bindSize = bytes.Length;
662 else if (oracleType == OracleType.Clob) {
663 string sv = v.ToString();
666 // Get size of buffer
667 OciCalls.OCIUnicodeToCharSet (statement.Parent, null, sv, out rsize);
670 bytes = new byte[rsize];
671 OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, sv, out rsize);
673 bindType = OciDataType.Long;
674 bindSize = bytes.Length;
676 else if (oracleType == OracleType.Raw) {
677 byte[] val = v as byte[];
678 bindValue = OciCalls.AllocateClear (val.Length);
679 Marshal.Copy (val, 0, bindValue, val.Length);
680 bindSize = val.Length;
682 svalue = v.ToString () + '\0';
685 // Get size of buffer
686 OciCalls.OCIUnicodeToCharSet (statement.Parent, null, svalue, out rsize);
689 bytes = new byte[rsize];
690 OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);
692 bindType = OciDataType.String;
693 bindSize = svalue.Length;
695 } // else - Input, Ouput...
700 // Now, call the appropriate OCI Bind function;
702 if (useRef == true) {
703 if (bindType == OciDataType.TimeStamp) {
704 bindValue = dateTimeDesc.Handle;
705 status = OciCalls.OCIBindByNameRef (statement,
707 connection.ErrorHandle,
709 ParameterName.Length,
721 status = OciCalls.OCIBindByNameRef (statement,
723 connection.ErrorHandle,
725 ParameterName.Length,
737 else if (bindType == OciDataType.RSet) {
738 status = OciCalls.OCIBindByNameRef (statement,
740 connection.ErrorHandle,
742 ParameterName.Length,
753 else if (bytes != null) {
754 status = OciCalls.OCIBindByNameBytes (statement,
756 connection.ErrorHandle,
758 ParameterName.Length,
770 status = OciCalls.OCIBindByName (statement,
772 connection.ErrorHandle,
774 ParameterName.Length, // FIXME: this should be in bytes!
785 OciErrorHandle.ThrowExceptionIfError (connection.ErrorHandle, status);
787 bindHandle.SetHandle (tmpHandle);
790 object ICloneable.Clone ()
792 return new OracleParameter(this);
795 private void InferOracleType (object value)
797 Type type = value.GetType ();
798 string exception = String.Format ("The parameter data type of {0} is invalid.", type.FullName);
799 switch (type.FullName) {
801 SetOracleType (OracleType.Number);
803 case "System.Boolean":
805 SetOracleType (OracleType.Byte);
807 case "System.String":
808 case "System.Data.OracleClient.OracleString":
809 SetOracleType (OracleType.VarChar);
811 case "System.Data.OracleClient.OracleDateTime":
812 case "System.DateTime":
813 SetOracleType (OracleType.DateTime);
815 case "System.Decimal":
816 case "System.Data.OracleClient.OracleNumber":
817 SetOracleType (OracleType.Number);
818 //scale = ((decimal) value).Scale;
820 case "System.Double":
821 SetOracleType (OracleType.Double);
823 case "System.Byte[]":
825 SetOracleType (OracleType.Raw);
828 SetOracleType (OracleType.Int32);
830 case "System.Single":
831 SetOracleType (OracleType.Float);
834 SetOracleType (OracleType.Int16);
836 case "System.DBNull":
837 break; //unable to guess type
839 throw new ArgumentException (exception);
843 private int InferSize ()
848 case OciDataType.VarChar2:
849 case OciDataType.String:
850 case OciDataType.VarChar:
851 case OciDataType.Char:
852 case OciDataType.CharZ:
853 case OciDataType.OciString:
854 case OciDataType.Long:
855 case OciDataType.LongVarChar:
856 if (value == null || value == DBNull.Value)
859 newSize = value.ToString ().Length;
861 case OciDataType.RowIdDescriptor:
864 case OciDataType.Integer:
865 case OciDataType.Number:
866 case OciDataType.Float:
869 case OciDataType.Date:
872 case OciDataType.TimeStamp:
875 case OciDataType.Blob:
876 case OciDataType.Clob:
877 case OciDataType.RSet: // REF CURSOR
881 if (value == null || value == DBNull.Value)
884 newSize = value.ToString ().Length;
893 private void SetDbType (DbType type)
895 string exception = String.Format ("No mapping exists from DbType {0} to a known OracleType.", type);
897 case DbType.AnsiString:
898 oracleType = OracleType.VarChar;
899 ociType = OciDataType.VarChar;
901 case DbType.AnsiStringFixedLength:
902 oracleType = OracleType.Char;
903 ociType = OciDataType.Char;
907 oracleType = OracleType.Raw;
908 ociType = OciDataType.Raw;
912 oracleType = OracleType.Byte;
913 ociType = OciDataType.Integer;
915 case DbType.Currency:
918 oracleType = OracleType.Number;
919 ociType = OciDataType.Number;
922 case DbType.DateTime:
924 oracleType = OracleType.DateTime;
925 ociType = OciDataType.Char;
928 oracleType = OracleType.Double;
929 ociType = OciDataType.Float;
932 oracleType = OracleType.Int16;
933 ociType = OciDataType.Integer;
936 oracleType = OracleType.Int32;
937 ociType = OciDataType.Integer;
940 oracleType = OracleType.Blob;
941 ociType = OciDataType.Blob;
944 oracleType = OracleType.Float;
945 ociType = OciDataType.Float;
948 oracleType = OracleType.NVarChar;
949 ociType = OciDataType.VarChar;
951 case DbType.StringFixedLength:
952 oracleType = OracleType.NChar;
953 ociType = OciDataType.Char;
956 throw new ArgumentException (exception);
961 private void SetOracleType (OracleType type)
964 string exception = String.Format ("No mapping exists from OracleType {0} to a known DbType.", type);
966 case OracleType.BFile:
967 case OracleType.Blob:
968 dbType = DbType.Binary;
969 ociType = OciDataType.Blob;
971 case OracleType.LongRaw:
973 dbType = DbType.Binary;
974 ociType = OciDataType.Raw;
976 case OracleType.Byte:
977 dbType = DbType.Byte;
978 ociType = OciDataType.Number;
980 case OracleType.Char:
981 dbType = DbType.AnsiString;
982 ociType = OciDataType.Char;
984 case OracleType.Clob:
985 dbType = DbType.AnsiString;
986 ociType = OciDataType.Clob;
988 case OracleType.LongVarChar:
989 case OracleType.RowId:
990 case OracleType.VarChar:
991 dbType = DbType.AnsiString;
992 ociType = OciDataType.VarChar;
994 case OracleType.Cursor: // REF CURSOR
995 ociType = OciDataType.RSet;
996 dbType = DbType.Object;
998 case OracleType.IntervalDayToSecond:
999 dbType = DbType.AnsiStringFixedLength;
1000 ociType = OciDataType.Char;
1002 case OracleType.Timestamp:
1003 case OracleType.TimestampLocal:
1004 case OracleType.TimestampWithTZ:
1005 dbType = DbType.DateTime;
1006 ociType = OciDataType.TimeStamp;
1008 case OracleType.DateTime:
1009 dbType = DbType.DateTime;
1010 ociType = OciDataType.Date;
1012 case OracleType.Double:
1013 dbType = DbType.Double;
1014 ociType = OciDataType.Number;
1016 case OracleType.Float:
1017 dbType = DbType.Single;
1018 ociType = OciDataType.Number;
1020 case OracleType.Int16:
1021 dbType = DbType.Int16;
1022 ociType = OciDataType.Number;
1024 case OracleType.Int32:
1025 case OracleType.IntervalYearToMonth:
1026 dbType = DbType.Int32;
1027 ociType = OciDataType.Number;
1029 case OracleType.NChar:
1030 dbType = DbType.StringFixedLength;
1031 ociType = OciDataType.Char;
1033 case OracleType.NClob:
1034 case OracleType.NVarChar:
1035 dbType = DbType.String;
1036 ociType = OciDataType.Char;
1038 case OracleType.Number:
1039 dbType = DbType.VarNumeric;
1040 ociType = OciDataType.Number;
1042 case OracleType.SByte:
1043 dbType = DbType.SByte;
1044 ociType = OciDataType.Number;
1046 case OracleType.UInt16:
1047 dbType = DbType.UInt16;
1048 ociType = OciDataType.Number;
1050 case OracleType.UInt32:
1051 dbType = DbType.UInt32;
1052 ociType = OciDataType.Number;
1055 throw new ArgumentException (exception);
1062 public override void ResetDbType ()
1067 public void ResetOracleType ()
1069 InferOracleType (value);
1073 public override string ToString ()
1075 return ParameterName;
1078 private void GetOutValue (OracleCommand cmd)
1080 // used to update the parameter value
1081 // for Output, the output of InputOutput, and Return parameters
1082 value = DBNull.Value;
1083 if (indicator == -1)
1087 IntPtr env = IntPtr.Zero;
1088 StringBuilder ret = null;
1090 // FIXME: redo all types - see how Char, Number, and Date are done
1091 // here and in Bind()
1094 case OciDataType.VarChar2:
1095 case OciDataType.String:
1096 case OciDataType.VarChar:
1097 case OciDataType.Char:
1098 case OciDataType.CharZ:
1099 case OciDataType.OciString:
1100 case OciDataType.RowIdDescriptor:
1101 // Get length of returned string
1103 env = cmd.Connection.Environment;
1104 OciCalls.OCICharSetToUnicode (env, null, bytes, out rsize);
1107 ret = new StringBuilder(rsize);
1108 OciCalls.OCICharSetToUnicode (env, ret, bytes, out rsize);
1110 value = ret.ToString ();
1112 case OciDataType.Long:
1113 case OciDataType.LongVarChar:
1115 if (BitConverter.IsLittleEndian)
1116 longSize = BitConverter.ToInt32 (new byte [] {bytes [0], bytes [1], bytes [2], bytes [3]}, 0);
1118 longSize = BitConverter.ToInt32 (new byte [] {bytes [3], bytes [2], bytes [1], bytes [0]}, 0);
1120 ASCIIEncoding encoding = new ASCIIEncoding ();
1121 value = encoding.GetString (bytes, 4, longSize);
1124 case OciDataType.Integer:
1125 case OciDataType.Number:
1126 case OciDataType.Float:
1128 env = cmd.Connection.Environment;
1129 OciCalls.OCICharSetToUnicode (env, null, bytes, out rsize);
1132 ret = new StringBuilder(rsize);
1133 OciCalls.OCICharSetToUnicode (env, ret, bytes, out rsize);
1135 // if not empty, parse string as a decimal using session format
1137 value = Decimal.Parse (ret.ToString (), cmd.Connection.SessionFormatProvider);
1139 case OciDataType.TimeStamp:
1140 value = dateTimeDesc.GetDateTime (connection.Environment, dateTimeDesc.ErrorHandle);
1142 case OciDataType.Date:
1143 value = UnpackDate (bytes);
1145 case OciDataType.Blob:
1146 case OciDataType.Clob:
1147 OracleLob lob = new OracleLob (lobLocator, ociType);
1148 lob.connection = connection;
1151 case OciDataType.RSet: // REF CURSOR
1152 OciStatementHandle cursorStatement = GetOutRefCursor (cmd);
1153 value = new OracleDataReader (cursorStatement.Command, cursorStatement, true, CommandBehavior.Default);
1156 throw new NotImplementedException ("Data Type not implemented: " + ociType.ToString() + ".");
1160 internal OciStatementHandle GetOutRefCursor (OracleCommand cmd)
1162 OciStatementHandle cursorStatement = new OciStatementHandle (cmd.Connection.ServiceContext, cursor);
1164 cursorStatement.ErrorHandle = cmd.ErrorHandle;
1165 cursorStatement.Command = cmd;
1166 cursorStatement.SetupRefCursorResult (cmd.Connection);
1167 cursorStatement.Service = cmd.Connection.ServiceContext;
1168 cursor = IntPtr.Zero;
1169 return cursorStatement;
1172 internal void Update (OracleCommand cmd)
1174 if (Direction != ParameterDirection.Input)
1180 internal void FreeHandle ()
1183 case OciDataType.Clob:
1184 case OciDataType.Blob:
1187 case OciDataType.Raw:
1188 Marshal.FreeHGlobal (bindValue);
1190 case OciDataType.TimeStamp:
1193 Marshal.FreeHGlobal (bindOutValue);
1197 bindOutValue = IntPtr.Zero;
1198 bindValue = IntPtr.Zero;
1204 // copied from OciDefineHandle
1205 [MonoTODO ("Be able to handle negative dates... i.e. BCE.")]
1206 private DateTime UnpackDate (byte[] bytes)
1208 byte century = bytes [0];
1209 byte year = bytes [1];
1210 byte month = bytes [2];
1211 byte day = bytes [3];
1212 byte hour = bytes [4];
1213 byte minute = bytes [5];
1214 byte second = bytes [6];
1217 return new DateTime ((century - 100) * 100 + (year - 100),
1226 private byte[] PackDate (DateTime dateValue)
1228 byte[] buffer = new byte[7];
1230 buffer[0] = (byte)((dateValue.Year / 100) + 100); //century
1231 buffer[1] = (byte)((dateValue.Year % 100) + 100); // Year
1232 buffer[2] = (byte)dateValue.Month;
1233 buffer[3] = (byte)dateValue.Day;
1234 buffer[4] = (byte)(dateValue.Hour+1);
1235 buffer[5] = (byte)(dateValue.Minute+1);
1236 buffer[6] = (byte)(dateValue.Second+1);
1241 #endregion // Methods
1243 internal sealed class OracleParameterConverter : ExpandableObjectConverter
1245 public OracleParameterConverter ()
1250 public override bool CanConvertTo (ITypeDescriptorContext context, Type destinationType)
1252 throw new NotImplementedException ();
1256 public override object ConvertTo (ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
1258 throw new NotImplementedException ();