internal void PrepareForBind( OracleConnection connection, ref int offset ) { OracleParameter parameter = Parameter; // Don't bother with parameters where the user asks for the default value. if (!IsDirection(parameter, ParameterDirection.Output) && null == parameter.Value) { _bufferLengthInBytes = 0; return; } _bindingMetaType = parameter.GetMetaType(); // We currently don't support binding a REF CURSOR as an input parameter; that // is for a future release. if (OCI.DATATYPE.RSET == _bindingMetaType.OciType && ParameterDirection.Output != parameter.Direction) { throw ADP.InputRefCursorNotSupported(parameter.ParameterName); } // Make sure we have a coerced value, if we haven't already done // so, then save it. parameter.SetCoercedValue(_bindingMetaType.BaseType, _bindingMetaType.NoConvertType); _coercedValue = parameter.CoercedValue; // When they're binding a LOB type, but not providing a LOB object, // we have to change the binding under the covers so we aren't forced // to create a temporary LOB. switch (_bindingMetaType.OciType) { case OCI.DATATYPE.BFILE: case OCI.DATATYPE.BLOB: case OCI.DATATYPE.CLOB: if (!ADP.IsNull(_coercedValue) && !(_coercedValue is OracleLob || _coercedValue is OracleBFile)) { _bindingMetaType = MetaType.GetMetaTypeForType(_bindingMetaType.DbType); } break; } // For fixed-width types, we take the bind size from the meta type // information; if it's zero, then the type must be variable width // (or it's an output parameter) and we require that they specify a // size. _bufferLength = _bindingMetaType.BindSize; if ((IsDirection(parameter, ParameterDirection.Output) && _bindingMetaType.IsVariableLength) || // they must specify a size for variable-length output parameters... (0 == _bufferLength && !ADP.IsNull(_coercedValue)) || // ...or if it's a non-null, variable-length input paramter... (_bufferLength > short.MaxValue)) // ...or if the parameter type's maximum size is huge. { int size = parameter.BindSize; if (0 != size) { _bufferLength = size; } if (0 == _bufferLength || MetaType.LongMax == _bufferLength) { throw ADP.ParameterSizeIsMissing(parameter.ParameterName, _bindingMetaType.BaseType); } } _bufferLengthInBytes = _bufferLength; if (_bindingMetaType.IsCharacterType && connection.ServerVersionAtLeastOracle8) { _bindAsUCS2 = true; _bufferLengthInBytes *= ADP.CharSize; } // Anything with a length that exceeds what fits into a two-byte integer // requires special binding because the base types don't allow more than // 65535 bytes. We change the binding under the covers to reflect the // different type. if (!ADP.IsNull(_coercedValue) && _bufferLength > _bindingMetaType.MaxBindSize) { // DEVNOTE: it is perfectly fine to bind values less than 65535 bytes // as long, so there's no problem with using the maximum number // of bytes for each Unicode character above. switch (_bindingMetaType.OciType) { case OCI.DATATYPE.CHAR: case OCI.DATATYPE.LONG: case OCI.DATATYPE.VARCHAR2: _bindingMetaType = (_bindingMetaType.UsesNationalCharacterSet) ? MetaType.oracleTypeMetaType_LONGNVARCHAR : MetaType.oracleTypeMetaType_LONGVARCHAR; break; case OCI.DATATYPE.RAW: case OCI.DATATYPE.LONGRAW: _bindingMetaType = MetaType.oracleTypeMetaType_LONGVARRAW; break; default: Debug.Assert(false, "invalid type for long binding!"); // this should never happen! break; } // Long data requires a LONGVARCHAR or LONGVARRAW binding instead, which // mean we have to add another 4 bytes for the length. _bufferLengthInBytes += 4; } if (0 > _bufferLengthInBytes) { throw ADP.ParameterSizeIsTooLarge(parameter.ParameterName); } // Fill in the buffer offsets. We lay out the buffer as follows: // // indicator 0-3 // length 4-7 // data 8-... // _indicatorOffset = offset; offset += 4; _lengthOffset = offset; offset += 4; _valueOffset = offset; offset += _bufferLengthInBytes; offset = (offset + 3) & ~0x3; // DWORD align, please. }
internal void PrepareForBind(OracleConnection connection, ref int offset) { OracleParameter parameter = this.Parameter; bool flag = false; object obj2 = parameter.Value; if (!IsDirection(parameter, ParameterDirection.Output) && (obj2 == null)) { this._bufferLength = 0; } else { this._bindingMetaType = parameter.GetMetaType(obj2); if ((OCI.DATATYPE.RSET == this._bindingMetaType.OciType) && System.Data.Common.ADP.IsDirection(parameter.Direction, ParameterDirection.Input)) { throw System.Data.Common.ADP.InputRefCursorNotSupported(parameter.ParameterName); } parameter.SetCoercedValueInternal(obj2, this._bindingMetaType); this._coercedValue = parameter.GetCoercedValueInternal(); switch (this._bindingMetaType.OciType) { case OCI.DATATYPE.CLOB: case OCI.DATATYPE.BLOB: case OCI.DATATYPE.BFILE: if ((!System.Data.Common.ADP.IsNull(this._coercedValue) && !(this._coercedValue is OracleLob)) && !(this._coercedValue is OracleBFile)) { if (!connection.HasTransaction) { this._bindingMetaType = MetaType.GetMetaTypeForType(this._bindingMetaType.DbType); flag = true; break; } this._freeTemporaryLob = true; this._coercedValue = this.CreateTemporaryLobForValue(connection, this._bindingMetaType.OracleType, this._coercedValue); } break; } this._bindSize = this._bindingMetaType.BindSize; if (((IsDirection(parameter, ParameterDirection.Output) && this._bindingMetaType.IsVariableLength) || ((this._bindSize == 0) && !System.Data.Common.ADP.IsNull(this._coercedValue))) || (this._bindSize > 0x7fff)) { int bindSize = parameter.BindSize; if (bindSize != 0) { this._bindSize = bindSize; } if (((this._bindSize == 0) || (0x7fffffff == this._bindSize)) && !this.IsEmpty(this._coercedValue)) { throw System.Data.Common.ADP.ParameterSizeIsMissing(parameter.ParameterName, this._bindingMetaType.BaseType); } } this._bufferLength = this._bindSize; if (this._bindingMetaType.IsCharacterType && connection.ServerVersionAtLeastOracle8) { this._bindAsUCS2 = true; this._bufferLength *= System.Data.Common.ADP.CharSize; } if (!System.Data.Common.ADP.IsNull(this._coercedValue) && ((this._bindSize > this._bindingMetaType.MaxBindSize) || flag)) { switch (this._bindingMetaType.OciType) { case OCI.DATATYPE.RAW: case OCI.DATATYPE.LONGRAW: this._bindingMetaType = MetaType.oracleTypeMetaType_LONGVARRAW; break; case OCI.DATATYPE.CHAR: case OCI.DATATYPE.VARCHAR2: case OCI.DATATYPE.LONG: this._bindingMetaType = this._bindingMetaType.UsesNationalCharacterSet ? MetaType.oracleTypeMetaType_LONGNVARCHAR : MetaType.oracleTypeMetaType_LONGVARCHAR; break; } this._bufferLength += 4; } if (0 > this._bufferLength) { throw System.Data.Common.ADP.ParameterSizeIsTooLarge(parameter.ParameterName); } this._indicatorOffset = offset; offset += IntPtr.Size; this._lengthOffset = offset; offset += IntPtr.Size; this._valueOffset = offset; offset += this._bufferLength; offset = (offset + (IntPtr.Size - 1)) & ~(IntPtr.Size - 1); } }
internal static OracleString GetPersistedRowid(OracleConnection connection, OciRowidDescriptor rowidHandle) { OracleString @null = OracleString.Null; if (rowidHandle != null) { OciErrorHandle errorHandle = connection.ErrorHandle; NativeBuffer scratchBuffer = connection.GetScratchBuffer(0xf82); bool success = false; bool flag = false; RuntimeHelpers.PrepareConstrainedRegions(); try { int num; scratchBuffer.DangerousAddRef(ref success); if (OCI.ClientVersionAtLeastOracle9i) { int length = scratchBuffer.Length; num = TracedNativeMethods.OCIRowidToChar(rowidHandle, scratchBuffer, ref length, errorHandle); if (num != 0) { connection.CheckError(errorHandle, num); } return(new OracleString(scratchBuffer.PtrToStringAnsi(0, length))); } rowidHandle.DangerousAddRef(ref flag); OciServiceContextHandle serviceContextHandle = connection.ServiceContextHandle; OciStatementHandle stmtp = new OciStatementHandle(serviceContextHandle); string stmt = "begin :rowid := :rdesc; end;"; int offset = 0; int num6 = 4; int num5 = 8; int num3 = 12; int num2 = 0x10; int num4 = 20; try { IntPtr ptr; IntPtr ptr2; num = TracedNativeMethods.OCIStmtPrepare(stmtp, errorHandle, stmt, OCI.SYNTAX.OCI_NTV_SYNTAX, OCI.MODE.OCI_DEFAULT, connection); if (num != 0) { connection.CheckError(errorHandle, num); } scratchBuffer.WriteIntPtr(num5, rowidHandle.DangerousGetHandle()); scratchBuffer.WriteInt32(offset, 0); scratchBuffer.WriteInt32(num6, 4); scratchBuffer.WriteInt32(num3, 0); scratchBuffer.WriteInt32(num2, 0xf6e); num = TracedNativeMethods.OCIBindByName(stmtp, out ptr2, errorHandle, "rowid", 5, scratchBuffer.DangerousGetDataPtr(num4), 0xf6e, OCI.DATATYPE.VARCHAR2, scratchBuffer.DangerousGetDataPtr(num3), scratchBuffer.DangerousGetDataPtr(num2), OCI.MODE.OCI_DEFAULT); if (num != 0) { connection.CheckError(errorHandle, num); } num = TracedNativeMethods.OCIBindByName(stmtp, out ptr, errorHandle, "rdesc", 5, scratchBuffer.DangerousGetDataPtr(num5), 4, OCI.DATATYPE.ROWID_DESC, scratchBuffer.DangerousGetDataPtr(offset), scratchBuffer.DangerousGetDataPtr(num6), OCI.MODE.OCI_DEFAULT); if (num != 0) { connection.CheckError(errorHandle, num); } num = TracedNativeMethods.OCIStmtExecute(serviceContextHandle, stmtp, errorHandle, 1, OCI.MODE.OCI_DEFAULT); if (num != 0) { connection.CheckError(errorHandle, num); } if (scratchBuffer.ReadInt16(num3) == -1) { return(@null); } @null = new OracleString(scratchBuffer, num4, num2, MetaType.GetMetaTypeForType(OracleType.RowId), connection, false, true); GC.KeepAlive(rowidHandle); } finally { OciHandle.SafeDispose(ref stmtp); } } finally { if (flag) { rowidHandle.DangerousRelease(); } if (success) { scratchBuffer.DangerousRelease(); } } } return(@null); }
internal bool Describe(ref int offset, OracleConnection connection, OciErrorHandle errorHandle) { byte num; short num3; bool flag = false; bool flag2 = false; this._describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_SQLCODE, out this._columnName, errorHandle, this._connection); this._describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_OBJECT, out num3, errorHandle); this._describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_SESSION, out num, errorHandle); this._isNullable = 0 != num; OCI.DATATYPE ociType = (OCI.DATATYPE)num3; switch (ociType) { case OCI.DATATYPE.VARCHAR2: case OCI.DATATYPE.CHAR: { int num2; this._describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_FNCODE, out this._byteSize, errorHandle); this._describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_FORM, out num, errorHandle); OCI.CHARSETFORM charsetform = (OCI.CHARSETFORM)num; this._bindAsUTF16 = connection.ServerVersionAtLeastOracle8; if (connection.ServerVersionAtLeastOracle9i && OCI.ClientVersionAtLeastOracle9i) { this._describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_CHAR_SIZE, out num3, errorHandle); num2 = num3; } else { num2 = this._byteSize; } if (charsetform == OCI.CHARSETFORM.SQLCS_NCHAR) { this._metaType = MetaType.GetMetaTypeForType((OCI.DATATYPE.CHAR == ociType) ? System.Data.OracleClient.OracleType.NChar : System.Data.OracleClient.OracleType.NVarChar); } else { this._metaType = MetaType.GetMetaTypeForType((OCI.DATATYPE.CHAR == ociType) ? System.Data.OracleClient.OracleType.Char : System.Data.OracleClient.OracleType.VarChar); if (this._bindAsUTF16) { this._byteSize *= System.Data.Common.ADP.CharSize; } } this._byteSize = Math.Max(this._byteSize, num2 * System.Data.Common.ADP.CharSize); flag = true; break; } case OCI.DATATYPE.NUMBER: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.Number); this._byteSize = this._metaType.BindSize; this._describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_ENV, out this._precision, errorHandle); this._describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_SERVER, out this._scale, errorHandle); break; case OCI.DATATYPE.LONG: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.LongVarChar); this._byteSize = this._metaType.BindSize; flag = true; flag2 = true; this._bindAsUTF16 = connection.ServerVersionAtLeastOracle8; break; case OCI.DATATYPE.ROWID: case OCI.DATATYPE.ROWID_DESC: case OCI.DATATYPE.UROWID: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.RowId); this._byteSize = this._metaType.BindSize; if (connection.UnicodeEnabled) { this._bindAsUTF16 = true; this._byteSize *= System.Data.Common.ADP.CharSize; } flag = true; break; case OCI.DATATYPE.DATE: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.DateTime); this._byteSize = this._metaType.BindSize; flag = true; break; case OCI.DATATYPE.RAW: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.Raw); this._describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_FNCODE, out this._byteSize, errorHandle); flag = true; break; case OCI.DATATYPE.LONGRAW: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.LongRaw); this._byteSize = this._metaType.BindSize; flag = true; flag2 = true; break; case OCI.DATATYPE.CLOB: this._describeHandle.GetAttribute(OCI.ATTR.OCI_ATTR_CHARSET_FORM, out num, errorHandle); this._metaType = MetaType.GetMetaTypeForType((2 == num) ? System.Data.OracleClient.OracleType.NClob : System.Data.OracleClient.OracleType.Clob); this._byteSize = this._metaType.BindSize; flag2 = true; break; case OCI.DATATYPE.BLOB: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.Blob); this._byteSize = this._metaType.BindSize; flag2 = true; break; case OCI.DATATYPE.BFILE: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.BFile); this._byteSize = this._metaType.BindSize; flag2 = true; break; case OCI.DATATYPE.TIMESTAMP: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.Timestamp); this._byteSize = this._metaType.BindSize; flag = true; break; case OCI.DATATYPE.TIMESTAMP_TZ: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.TimestampWithTZ); this._byteSize = this._metaType.BindSize; flag = true; break; case OCI.DATATYPE.INTERVAL_YM: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.IntervalYearToMonth); this._byteSize = this._metaType.BindSize; break; case OCI.DATATYPE.INTERVAL_DS: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.IntervalDayToSecond); this._byteSize = this._metaType.BindSize; break; case OCI.DATATYPE.TIMESTAMP_LTZ: this._metaType = MetaType.GetMetaTypeForType(System.Data.OracleClient.OracleType.TimestampLocal); this._byteSize = this._metaType.BindSize; flag = true; break; default: throw System.Data.Common.ADP.TypeNotSupported(ociType); } if (this._isNullable) { this._indicatorOffset = offset; offset += IntPtr.Size; } else { this._indicatorOffset = -1; } if (flag) { this._lengthOffset = offset; offset += IntPtr.Size; } else { this._lengthOffset = -1; } this._valueOffset = offset; if ((OCI.DATATYPE.LONG == ociType) || (OCI.DATATYPE.LONGRAW == ociType)) { offset += IntPtr.Size; } else { offset += this._byteSize; } offset = (offset + (IntPtr.Size - 1)) & ~(IntPtr.Size - 1); OciHandle.SafeDispose(ref this._describeHandle); return(flag2); }