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); } }