Esempio n. 1
2
		private int ExecuteNonQueryInternal (OciStatementHandle statement, bool useAutoCommit)
		{
			moreResults = -1;

			if (preparedStatement == null)
				PrepareStatement (statement);

			bool isNonQuery = IsNonQuery (statement);

			BindParameters (statement);
			if (isNonQuery == true)
				statement.ExecuteNonQuery (useAutoCommit);
			else
				statement.ExecuteQuery (false);

			UpdateParameterValues ();

			int rowsAffected = statement.GetAttributeInt32 (OciAttributeType.RowCount, ErrorHandle);

			return rowsAffected;
		}
Esempio n. 2
0
		internal OracleDataReader (OracleCommand command, OciStatementHandle statement, bool extHasRows, CommandBehavior behavior)
		{
			this.command = command;
			this.hasRows = extHasRows;
			this.schemaTable = ConstructSchemaTable ();
			this.statement = statement;
			this.statementType = statement.GetStatementType ();
			this.behavior = behavior;
		}
		internal OracleDataReader (OracleCommand command, OciStatementHandle statement, bool extHasRows ) 
		{
			this.command = command;
			this.hasRows = extHasRows;
			this.isClosed = false;
			this.schemaTable = ConstructSchemaTable ();
			this.statement = statement;
			this.statementType = statement.GetStatementType ();
	        }
Esempio n. 4
0
		public OracleCommand (string commandText, OracleConnection connection, OracleTransaction tx)
		{
			moreResults = -1;
			preparedStatement = null;
			CommandText = commandText;
			Connection = connection;
			Transaction = tx;
			CommandType = CommandType.Text;
			UpdatedRowSource = UpdateRowSource.Both;
			DesignTimeVisible = true;
			parameters = new OracleParameterCollection ();
		}
Esempio n. 5
0
        public OciStatementHandle CreateStatement()
        {
            OciStatementHandle statement = (OciStatementHandle)environment.Allocate(OciHandleType.Statement);

            if (statement == null)
            {
                OciErrorInfo info = environment.HandleError();
                throw new OracleException(info.ErrorCode, info.ErrorMessage);
            }
            statement.ErrorHandle = error;
            statement.Service     = service;

            return(statement);
        }
Esempio n. 6
0
		void Prepare ()
		{
			AssertConnectionIsOpen ();
			OciStatementHandle statement = GetStatementHandle ();
			PrepareStatement (statement);
			preparedStatement = statement;
		}
Esempio n. 7
0
		void PrepareStatement (OciStatementHandle statement)
		{
			if (commandType == CommandType.StoredProcedure) {
				StringBuilder sb = new StringBuilder ();
				if (Parameters.Count > 0)
					foreach (OracleParameter parm in Parameters) {
						if (sb.Length > 0)
							sb.Append (",");
						sb.Append (parm.ParameterName + "=>:" + parm.ParameterName);
					}

				string sql = "begin " + commandText + "(" + sb.ToString() + "); end;";
				statement.Prepare (sql);
			} else	// Text
				statement.Prepare (commandText);
		}
Esempio n. 8
0
		private void SafeDisposeHandle (OciStatementHandle h)
		{
			if (h != null && h != preparedStatement) 
				h.Dispose();
		}
Esempio n. 9
0
		OracleDataReader ExecuteReader (CommandBehavior behavior)
		{
			AssertConnectionIsOpen ();
			AssertTransactionMatch ();
			AssertCommandTextIsSet ();

			moreResults = -1;

			bool hasRows = false;

			this.behavior = behavior;

			if (Transaction != null)
				Transaction.AttachToServiceContext ();

			OciStatementHandle statement = GetStatementHandle ();
			OracleDataReader rd = null;

			try {
				if (preparedStatement == null)
					PrepareStatement (statement);
				else
					preparedStatement = null;	// OracleDataReader releases the statement handle

				bool isNonQuery = IsNonQuery (statement);

				BindParameters (statement);

				if (isNonQuery) 
					ExecuteNonQueryInternal (statement, false);
				else {	
					if ((behavior & CommandBehavior.SchemaOnly) != 0)
						statement.ExecuteQuery (true);
					else
						hasRows = statement.ExecuteQuery (false);

					UpdateParameterValues ();
				}

				if (Parameters.Count > 0) {
					for (int p = 0; p < Parameters.Count; p++) {
						OracleParameter parm = Parameters [p];
						if (parm.OracleType.Equals (OracleType.Cursor)) {
							if (parm.Direction != ParameterDirection.Input) {
								rd = (OracleDataReader) parm.Value;
								break;
							}
						}
					}					
				}

				if (rd == null)
					rd = new OracleDataReader (this, statement, hasRows, behavior);

			} finally {
				if (statement != null && rd == null)
					statement.Dispose();
			}

			return rd;
		}
Esempio n. 10
0
		private bool IsNonQuery (OciStatementHandle statementHandle)
		{
			// assumes Prepare() has been called prior to calling this function

			OciStatementType statementType = statementHandle.GetStatementType ();
			if (statementType.Equals (OciStatementType.Select))
				return false;

			return true;
		}
		private void BindParameters (OciStatementHandle statement)
		{
			foreach (OracleParameter p in Parameters) 
				p.Bind (statement, Connection);
		}
Esempio n. 12
0
		internal void Bind (OciStatementHandle statement, OracleConnection con, uint pos)
		{
			connection = con;

			if (bindHandle == null)
				bindHandle = new OciBindHandle ((OciHandle) statement);

			IntPtr tmpHandle = bindHandle.Handle;

			if (Direction != ParameterDirection.Input)
				AssertSizeIsSet ();
			if (!sizeSet)
				size = InferSize ();

			bindSize = size;
			object v = value;
			int status = 0;
			bindType = ociType;
			int rsize = 0;

			string svalue;
			string sDate;
			DateTime dt;
			bool isnull = false;
			int byteCount;
			byte[] byteArrayLen;

			if (direction == ParameterDirection.Input || direction == ParameterDirection.InputOutput) {
				if (v == null)
					isnull = true;
				else if (v is DBNull)
					isnull = true;
				else {
					INullable mynullable = v as INullable;
					if (mynullable != null)
						isnull = mynullable.IsNull;
				}					
			} 

			if (isnull == true && direction == ParameterDirection.Input) {
				bindType = OciDataType.VarChar2;
				bindSize = 0;
			} else {
				switch(ociType) {
				case OciDataType.VarChar2:
				case OciDataType.String:
				case OciDataType.VarChar:
				case OciDataType.Char:
				case OciDataType.CharZ:
				case OciDataType.OciString:
					bindType = OciDataType.String;
					svalue = "\0";
					// convert value from managed type to type to marshal
					if (direction == ParameterDirection.Input || 
						direction == ParameterDirection.InputOutput) {

						svalue = v.ToString ();

						if (direction == ParameterDirection.Input && size > 0 && svalue.Length > size)
							svalue = svalue.Substring(0, size);

						svalue = svalue.ToString () + '\0';
						
						// convert managed type to memory allocated earlier
						// in this case using OCIUnicodeToCharSet
						rsize = 0;
						// Get size of buffer
						status = OciCalls.OCIUnicodeToCharSet (statement.Parent, null, svalue, out rsize);

						if (direction == ParameterDirection.Input)
							bindSize = rsize;
						else {
							// this cannot be rsize because you need room for the output after the execute
							bindSize = Encoding.UTF8.GetMaxByteCount (Size + 1);
						}

						// allocate memory based on bind size
						bytes = new byte [bindSize];

						// Fill buffer
						status = OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);
					} else {
						// for Output and ReturnValue parameters, get size in bytes 					
						bindSize = Encoding.UTF8.GetMaxByteCount (size + 1);
						// allocate memory for oracle to place the results for the Return or Output param						
						bytes = new byte [bindSize];
					}
					break;
				case OciDataType.Date:
					bindType = OciDataType.Date;
					bindSize = 7;
					// convert value from managed type to type to marshal
					if (direction == ParameterDirection.Input || 
						direction == ParameterDirection.InputOutput) {

						if (isnull)
							bytes = new byte [7];
						else {
							sDate = "";
							dt = DateTime.MinValue;
							if (v is String) {
								sDate = (string) v;
								dt = DateTime.Parse (sDate);
							}
							else if (v is DateTime)
								dt = (DateTime) v;
							else if (v is OracleString) {
								sDate = v.ToString ();
								dt = DateTime.Parse (sDate);
							}
							else if (v is OracleDateTime) {
								OracleDateTime odt = (OracleDateTime) v;
								dt = (DateTime) odt.Value;
							}
							else
								throw new NotImplementedException ("For OracleType.DateTime, data type not implemented: " + v.GetType().ToString() + ".");

							// for Input and InputOuput, create byte array and pack DateTime into it
							bytes = PackDate (dt);
						}
					} else	{
						// allocate 7-byte array for Output and ReturnValue to put date
						bytes = new byte [7];
					}
					break;
				case OciDataType.TimeStamp:
					dateTimeDesc = (OciDateTimeDescriptor) connection.Environment.Allocate (OciHandleType.TimeStamp);
					if (dateTimeDesc == null) {
						OciErrorInfo info = connection.ErrorHandle.HandleError ();
						throw new OracleException (info.ErrorCode, info.ErrorMessage);
					}
					dateTimeDesc.ErrorHandle = connection.ErrorHandle;
					bindSize = 11;
					bindType = OciDataType.TimeStamp;
					bindOutValue = dateTimeDesc.Handle;
					bindValue = dateTimeDesc.Handle;
					useRef = true;
					if (direction == ParameterDirection.Input || 
						direction == ParameterDirection.InputOutput) {

						dt = DateTime.MinValue;
						sDate = "";
						if (isnull)
							Indicator = -1;
						else if (v is String) {
							sDate = (string) v;
							dt = DateTime.Parse (sDate);
						}
						else if (v is DateTime)
							dt = (DateTime) v;
						else if (v is OracleString) {
							sDate = (string) v;
							dt = DateTime.Parse (sDate);
						}
						else if (v is OracleDateTime) {
							OracleDateTime odt = (OracleDateTime) v;
							dt = (DateTime) odt.Value;
						}
						else
							throw new NotImplementedException ("For OracleType.Timestamp, data type not implemented: " + v.GetType().ToString()); // ?

						short year = (short) dt.Year;
						byte month = (byte) dt.Month;
						byte day = (byte) dt.Day;
						byte hour = (byte) dt.Hour;
						byte min = (byte) dt.Minute;
						byte sec = (byte) dt.Second;
						uint fsec = (uint) dt.Millisecond;
						string timezone = "";
						dateTimeDesc.SetDateTime (connection.Session,
							connection.ErrorHandle,
							year, month, day, hour, min, sec, fsec,
							timezone);
					}
					break;
				case OciDataType.Integer:
				case OciDataType.Float:
				case OciDataType.Number:
					bindType = OciDataType.String;
					Indicator = 0;
					svalue = "\0";
					// convert value from managed type to type to marshal
					if (direction == ParameterDirection.Input || 
						direction == ParameterDirection.InputOutput) {

						svalue = null;
						if(v is IFormattable)
							svalue = ((IFormattable)v).ToString (null, con.SessionFormatProvider);
						else if (v is OracleNumber)
							svalue = ((OracleNumber)v).ToString(con.SessionFormatProvider);
						else
							svalue = v.ToString();

						svalue = svalue + "\0";

						rsize = 0;
						// Get size of buffer
						OciCalls.OCIUnicodeToCharSet (statement.Parent, null, svalue, out rsize);

						// Fill buffer 
						
						if (direction == ParameterDirection.Input)
							bindSize = rsize;
						else
							bindSize = 30; // need room for output possibly being bigger than the input
						
						bytes = new byte [bindSize];
						OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);
					} else {
						// Output and ReturnValue parameters allocate memory
						bindSize = 30;
						bytes = new byte [bindSize];
					} 
					break;
				case OciDataType.Long:
				case OciDataType.LongVarChar:
					bindType = OciDataType.LongVarChar;

					// FIXME: use piecewise fetching for Long, Clob, Blob, and Long Raw
					// See http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14250/oci05bnd.htm#sthref724
					
					bindSize = Size + 5; // 4 bytes prepended for length, bytes, 1 byte NUL character

					Indicator = 0;
					svalue = "\0";
					// convert value from managed type to type to marshal
					if (direction == ParameterDirection.Input || 
						direction == ParameterDirection.InputOutput) {

						svalue = v.ToString () + '\0';
					}

					bytes = new byte [bindSize];
					// LONG is only ANSI 
					ASCIIEncoding enc = new ASCIIEncoding ();
					
					if (direction == ParameterDirection.Input || 
						direction == ParameterDirection.InputOutput) {
						if (svalue.Length > 0) {	
							byteCount = enc.GetBytes (svalue, 4, svalue.Length, bytes, 0);
							// LONG VARCHAR prepends a 4-byte length
							if (byteCount > 0) {
								byteArrayLen = BitConverter.GetBytes ((uint) byteCount);
								bytes[0] = byteArrayLen[0];
								bytes[1] = byteArrayLen[1];
								bytes[2] = byteArrayLen[2];
								bytes[3] = byteArrayLen[3];
							}
						}
					}
					break;
				case OciDataType.Clob:
					if (direction == ParameterDirection.Input) {
						svalue = v.ToString();
						rsize = 0;

						// Get size of buffer
						OciCalls.OCIUnicodeToCharSet (statement.Parent, null, svalue, out rsize);

						// Fill buffer
						bytes = new byte[rsize];
						OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);

						bindType = OciDataType.Long;
						bindSize = bytes.Length;
					} 
					else if (direction == ParameterDirection.InputOutput) {
						// not the exact error that .net 2.0 throws, but this is better
						throw new NotImplementedException ("Parameters of OracleType.Clob with direction of InputOutput are not supported.");
					}
					else {
						// Output and Return parameters
						bindSize = -1;
						lobLocator = (OciLobLocator) connection.Environment.Allocate (OciHandleType.LobLocator);
						if (lobLocator == null) {
							OciErrorInfo info = connection.ErrorHandle.HandleError ();
							throw new OracleException (info.ErrorCode, info.ErrorMessage);
						}
						bindOutValue = lobLocator.Handle;
						bindValue = lobLocator.Handle;
						lobLocator.ErrorHandle = connection.ErrorHandle;
						lobLocator.Service = statement.Service;
						lobLocator.Environment = connection.Environment;
						useRef = true;
					}
					break;
				case OciDataType.Blob:
					if (direction == ParameterDirection.Input) {
						if (v is byte[]) {
							bytes = (byte[]) v;
							bindType = OciDataType.LongRaw;
							bindSize = bytes.Length;
						}
						else if (v is OracleLob) {
							OracleLob lob = (OracleLob) v;
							if (lob.LobType == OracleType.Blob) {
								lobLocator = lob.Locator;
								bindOutValue = lobLocator.Handle;
								bindValue = lobLocator.Handle;
								lobLocator.ErrorHandle = connection.ErrorHandle;
								lobLocator.Service = connection.ServiceContext;
								useRef = true;
							}
							else
								throw new NotImplementedException("For OracleType.Blob, data type OracleLob of LobType Clob/NClob is not implemented.");
						}
						else
							throw new NotImplementedException ("For OracleType.Blob, data type not implemented: " + v.GetType().ToString()); // ?
					}
					else if (direction == ParameterDirection.InputOutput) {
						// not the exact error that .net 2.0 throws, but this is better
						throw new NotImplementedException ("Parameters of OracleType.Blob with direction of InputOutput are not supported.");
					}
					else {
						bindSize = -1;
						if (value != null && value is OracleLob) {
							OracleLob blob = (OracleLob) value;
							if (blob.LobType == OracleType.Blob)
								if (value != OracleLob.Null) {
									lobLocator = blob.Locator;
									byte[] bs = (byte[]) blob.Value;
									bindSize = bs.Length;
								}
						}
						if (lobLocator == null) {
							lobLocator = (OciLobLocator) connection.Environment.Allocate (OciHandleType.LobLocator);
							if (lobLocator == null) {
								OciErrorInfo info = connection.ErrorHandle.HandleError ();
								throw new OracleException (info.ErrorCode, info.ErrorMessage);
							}
						}
						bindOutValue = lobLocator.Handle;
						bindValue = lobLocator.Handle;
						lobLocator.ErrorHandle = connection.ErrorHandle;
						lobLocator.Service = connection.ServiceContext;
						lobLocator.Environment = connection.Environment;
						useRef = true;
					}
					break;
				case OciDataType.Raw:
				case OciDataType.VarRaw:
					bindType = OciDataType.VarRaw;
					bindSize = Size + 2; // include 2 bytes prepended to hold the length
					Indicator = 0;
					bytes = new byte [bindSize];
					if (direction == ParameterDirection.Input || 
						direction == ParameterDirection.InputOutput) {
						byteCount = 0;
						byte[] val;
						if (dbType == DbType.Guid)
							val = ((Guid)v).ToByteArray();
						else
							val = v as byte[];
						if (val.Length > 0) {	
							byteCount = val.Length;
							// LONG VARRAW prepends a 4-byte length
							if (byteCount > 0) {
								byteArrayLen = BitConverter.GetBytes ((ushort) byteCount);
								bytes[0] = byteArrayLen[0];
								bytes[1] = byteArrayLen[1];
								Array.ConstrainedCopy (val, 0, bytes, 2, byteCount);
							}
						}
					}
					break;
				case OciDataType.LongRaw:
				case OciDataType.LongVarRaw:
					bindType = OciDataType.LongVarRaw;
					bindSize = Size + 4; // include 4 bytes prepended to hold the length
					Indicator = 0;
					bytes = new byte [bindSize];
					if (direction == ParameterDirection.Input || 
						direction == ParameterDirection.InputOutput) {
						byteCount = 0;
						byte[] val = v as byte[];
						if (val.Length > 0) {	
							byteCount = val.Length;
							// LONG VARRAW prepends a 4-byte length
							if (byteCount > 0) {
								byteArrayLen = BitConverter.GetBytes ((uint) byteCount);
								bytes[0] = byteArrayLen[0];
								bytes[1] = byteArrayLen[1];
								bytes[2] = byteArrayLen[2];
								bytes[3] = byteArrayLen[3];
								Array.ConstrainedCopy (val, 0, bytes, 4, byteCount);
							}
						}
					}
					break;
				case OciDataType.RowIdDescriptor:
					if (direction == ParameterDirection.Output || 
						direction == ParameterDirection.InputOutput || 
						direction == ParameterDirection.ReturnValue) {

					size = 10;
					bindType = OciDataType.Char;
					bindSize = size * 2;
					bindOutValue = OciCalls.AllocateClear (bindSize);
					bindValue = bindOutValue;
					} else
						throw new NotImplementedException("data type RowIdDescriptor as Intput parameters");
					break;
				case OciDataType.RSet: // REF CURSOR
					if (direction == ParameterDirection.Output || 
						direction == ParameterDirection.InputOutput || 
						direction == ParameterDirection.ReturnValue) {
						if (cursor != IntPtr.Zero) {
							OciCalls.OCIHandleFree (cursor,
								OciHandleType.Statement);
							cursor = IntPtr.Zero;
						}
						OciCalls.OCIHandleAlloc (connection.Environment,
							out cursor,
							OciHandleType.Statement,
							0,
							IntPtr.Zero);
							bindSize = 0;
						bindType = OciDataType.RSet;
					} else
						throw new NotImplementedException ("data type Ref Cursor not implemented for Input parameters");
					break;
				default:
					throw new NotImplementedException ("Data Type not implemented: " + ociType.ToString() + ".");
				}			
			}
			
			// Now, call the appropriate OCI Bind function;

			if (useRef == true) {
				if (bindType == OciDataType.TimeStamp) {
					bindValue = dateTimeDesc.Handle;
					status = OciCalls.OCIBindByNameRef (statement,
						out tmpHandle,
						connection.ErrorHandle,
						ParameterName,
						ParameterName.Length,
						ref bindValue,
						bindSize,
						bindType,
						indicator,
						IntPtr.Zero,
						IntPtr.Zero,
						0,
						IntPtr.Zero,
						0);
				}
				else {
					status = OciCalls.OCIBindByNameRef (statement,
						out tmpHandle,
						connection.ErrorHandle,
						ParameterName,
						ParameterName.Length,
						ref bindValue,
						bindSize,
						bindType,
						indicator,
						IntPtr.Zero,
						IntPtr.Zero,
						0,
						IntPtr.Zero,
						0);
				}
			}
			else if (bindType == OciDataType.RSet) {
				status = OciCalls.OCIBindByNameRef (statement,
					out tmpHandle,
					connection.ErrorHandle,
					ParameterName,
					ParameterName.Length,
					ref cursor,
					bindSize,
					bindType,
					indicator,
					IntPtr.Zero,
					IntPtr.Zero,
					0,
					IntPtr.Zero,
					0);
			}
			else if (bytes != null) {
				status = OciCalls.OCIBindByNameBytes (statement,
					out tmpHandle,
					connection.ErrorHandle,
					ParameterName,
					ParameterName.Length,
					bytes,
					bindSize,
					bindType,
					indicator,
					IntPtr.Zero,
					IntPtr.Zero,
					0,
					IntPtr.Zero,
					0);
			}
			else {
				status = OciCalls.OCIBindByName (statement,
					out tmpHandle,
					connection.ErrorHandle,
					ParameterName,
					ParameterName.Length, // FIXME: this should be in bytes!
					bindValue,
					bindSize,
					bindType,
					indicator,
					IntPtr.Zero,
					IntPtr.Zero,
					0,
					IntPtr.Zero,
					0);
			}
			OciErrorHandle.ThrowExceptionIfError (connection.ErrorHandle, status);

			bindHandle.SetHandle (tmpHandle);
		}
Esempio n. 13
0
		internal OciStatementHandle GetOutRefCursor (OracleCommand cmd) 
		{
				OciStatementHandle cursorStatement = new OciStatementHandle (cmd.Connection.ServiceContext, cursor);

				cursorStatement.ErrorHandle = cmd.ErrorHandle;
				cursorStatement.Command = cmd;
				cursorStatement.SetupRefCursorResult (cmd.Connection);
				cursorStatement.Service = cmd.Connection.ServiceContext;
				cursor = IntPtr.Zero;
				return cursorStatement;			
		}
Esempio n. 14
0
		bool NextResult ()
		{
			ValidateState ();

			if (statement == null)
				return false;

			statement.Dispose ();
			statement = null;
			
			statement = command.GetNextResult ();
			
			if (statement == null)
				return false;

			return true; 
		}
Esempio n. 15
0
		void Close ()
		{
			if (!isClosed) {
				GetRecordsAffected ();
				if (command != null)
					command.CloseDataReader ();
			}
			if (statement != null) {
				statement.Dispose();
				statement = null;
			}
			if (schemaTable != null) {
				schemaTable.Dispose ();
				schemaTable = null;
			}
			isClosed = true;
		}
		public OracleDataReader ExecuteReader (CommandBehavior behavior)
		{
			AssertConnectionIsOpen ();
			AssertTransactionMatch ();
			AssertCommandTextIsSet ();
			AssertNoDataReader ();
			bool hasRows = false;

                        this.behavior = behavior;
				
			if (Transaction != null) 
				Transaction.AttachToServiceContext ();
			
			OciStatementHandle statement = GetStatementHandle ();
			OracleDataReader rd = null;

			try	{
				if (preparedStatement == null)
					PrepareStatement (statement);
				else
					preparedStatement = null;	// OracleDataReader releases the statement handle

				bool isNonQuery = IsNonQuery (statement);

				BindParameters (statement);

				if (isNonQuery)
					ExecuteNonQueryInternal (statement, false);
				else
					hasRows = statement.ExecuteQuery ();

				rd = new OracleDataReader (this, statement, hasRows);
			}
			finally	{
				if (statement != null && rd == null)
					statement.Dispose();
			}

			return rd;
		}
Esempio n. 17
0
		private void BindParameters (OciStatementHandle statement)
		{
			for (int p = 0; p < Parameters.Count; p++)
				Parameters[p].Bind (statement, Connection, (uint) p);
		}
		internal void Bind (OciStatementHandle statement, OracleConnection connection) 
		{
			if (bindHandle == null)
				bindHandle = new OciBindHandle ((OciHandle) statement);

			IntPtr tmpHandle = bindHandle.Handle;

			if (Direction != ParameterDirection.Input)
				AssertSizeIsSet ();
			if (!sizeSet)
				size = InferSize ();

			byte[] bytes = null;
			int status = 0;
			int indicator = 0;
			OciDataType bindType = ociType;
			IntPtr bindValue = IntPtr.Zero;
			int bindSize = size;
			int rsize = 0;

			if (value == DBNull.Value) {
				indicator = 0;
				bindType = OciDataType.VarChar2;
				bindSize = 0;
			}
			else {
				// TODO: do other data types and oracle data types
				// should I be using IConvertible to convert?
				if (oracleType == OracleType.DateTime) {
					string oraDateFormat = connection.GetSessionDateFormat ();
					string sysDateFormat = OracleDateTime.ConvertOracleDateFormatToSystemDateTime (oraDateFormat);

					string sDate = "";
					DateTime dt = DateTime.MinValue;
					if (value is String) {
						sDate = (string) value;
						dt = DateTime.Parse (sDate);
					}
					else if (value is DateTime)
						dt = (DateTime) value;
					else if (value is OracleString) {
						sDate = (string) value;
						dt = DateTime.Parse (sDate);
					}
					else if (value is OracleDateTime) {
						OracleDateTime odt = (OracleDateTime) value;
						dt = (DateTime) odt.Value;
					}
					else
						throw new NotImplementedException (); // ?

					sDate = dt.ToString (sysDateFormat);
					rsize = 0;
			
					// Get size of buffer
					OciCalls.OCIUnicodeToCharSet (statement.Parent, null, sDate, out rsize);
			
					// Fill buffer
					bytes = new byte[rsize];
					OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, sDate, out rsize);
					
					bindType = OciDataType.VarChar2; 
					//bindValue = Marshal.StringToHGlobalAnsi (sDate);
					bindSize = sDate.Length;
				}
				else if (oracleType == OracleType.Blob) {
					bytes = (byte[]) value;
					bindType = OciDataType.LongRaw;
					bindSize = bytes.Length;
				}
				else if (oracleType == OracleType.Clob) {
					string v = (string) value;
					rsize = 0;
			
					// Get size of buffer
					OciCalls.OCIUnicodeToCharSet (statement.Parent, null, v, out rsize);
			
					// Fill buffer
					bytes = new byte[rsize];
					OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, v, out rsize);

					bindType = OciDataType.Long;
					bindSize = bytes.Length;
				}
				else if (oracleType == OracleType.Raw) {
					byte[] val = value as byte[];
					bindValue = Marshal.AllocHGlobal (val.Length);
					Marshal.Copy (val, 0, bindValue, val.Length);
					bindSize = val.Length;
				}
				else {
					string svalue = value.ToString ();
					rsize = 0;
			
					// Get size of buffer
					OciCalls.OCIUnicodeToCharSet (statement.Parent, null, svalue, out rsize);
			
					// Fill buffer
					bytes = new byte[rsize];
					OciCalls.OCIUnicodeToCharSet (statement.Parent, bytes, svalue, out rsize);

					//bindValue = Marshal.StringToHGlobalAnsi (value.ToString ());
					bindType = OciDataType.VarChar2;
					bindSize = value.ToString ().Length;
				}
			}

			if (bytes != null) {
				status = OciCalls.OCIBindByNameBytes (statement,
					out tmpHandle,
					connection.ErrorHandle,
					ParameterName,
					ParameterName.Length,
					bytes,
					bindSize,
					bindType,
					indicator,
					IntPtr.Zero,
					IntPtr.Zero,
					0,
					IntPtr.Zero,
					0);
			}
			else {
				status = OciCalls.OCIBindByName (statement,
					out tmpHandle,
					connection.ErrorHandle,
					ParameterName,
					ParameterName.Length,
					bindValue,
					bindSize,
					bindType,
					indicator,
					IntPtr.Zero,
					IntPtr.Zero,
					0,
					IntPtr.Zero,
					0);
			}


			if (status != 0) {
				OciErrorInfo info = connection.ErrorHandle.HandleError ();
				throw new OracleException (info.ErrorCode, info.ErrorMessage);
			}

			bindHandle.SetHandle (tmpHandle);
		}