private void ValidateParameter() { if (this.userSpecifiedType && (OleDbType.Empty == OleDbType)) { throw ODB.UninitializedParameters(this.parent.IndexOf(this), ParameterName, OleDbType); } else if ((0 == GetParameterSize()) && (0 != (ParameterDirection.Output & Direction))) { throw ADP.UninitializedParameterSize(this.parent.IndexOf(this), ParameterName, NativeDBType.dataType, Size); } Debug.Assert(0 <= Size, "unexpected parameter size"); }
// goal: call virtual property getters only once per parameter internal bool BindParameter(int index, Bindings bindings) { int changeID = _changeID; object value = Value; NativeDBType dbtype = GetBindType(value); if (OleDbType.Empty == dbtype.enumOleDbType) { throw ODB.UninitializedParameters(index, dbtype.enumOleDbType); } _coerceMetaType = dbtype; value = CoerceValue(value, dbtype); CoercedValue = value; ParameterDirection direction = Direction; byte precision; if (ShouldSerializePrecision()) { precision = PrecisionInternal; } else { precision = ValuePrecision(value); } if (0 == precision) { precision = dbtype.maxpre; } byte scale; if (ShouldSerializeScale()) { scale = ScaleInternal; } else { scale = ValueScale(value); } int wtype = dbtype.wType; int bytecount, size; if (dbtype.islong) // long data (image, text, ntext) { bytecount = ADP.PtrSize; if (ShouldSerializeSize()) { size = Size; } else { if (NativeDBType.STR == dbtype.dbType) { size = Int32.MaxValue; // WebData 98940 } else if (NativeDBType.WSTR == dbtype.dbType) { size = Int32.MaxValue / 2; } else { size = Int32.MaxValue; } } wtype |= NativeDBType.BYREF; } else if (dbtype.IsVariableLength) // variable length data (varbinary, varchar, nvarchar) { if (!ShouldSerializeSize() && ADP.IsDirection(this, ParameterDirection.Output)) { throw ADP.UninitializedParameterSize(index, _coerceMetaType.dataType); } bool computedSize; if (ShouldSerializeSize()) { size = Size; computedSize = false; } else { size = ValueSize(value); computedSize = true; } if (0 < size) { if (NativeDBType.WSTR == dbtype.wType) { // maximum 0x3FFFFFFE characters, computed this way to avoid overflow exception bytecount = Math.Min(size, 0x3FFFFFFE) * 2 + 2; } else { Debug.Assert(NativeDBType.STR != dbtype.wType, "should have ANSI binding, describing is okay"); bytecount = size; } if (computedSize) { if (NativeDBType.STR == dbtype.dbType) // WebData 98140 // maximum 0x7ffffffe characters, computed this way to avoid overflow exception { size = Math.Min(size, 0x3FFFFFFE) * 2; } } if (ODB.LargeDataSize < bytecount) { bytecount = ADP.PtrSize; wtype |= NativeDBType.BYREF; } } else if (0 == size) { if (NativeDBType.WSTR == wtype) // allow space for null termination character { bytecount = 2; // 0 == size, okay for (STR == dbType) } else { Debug.Assert(NativeDBType.STR != dbtype.wType, "should have ANSI binding, describing is okay"); bytecount = 0; } } else if (-1 == size) { bytecount = ADP.PtrSize; wtype |= NativeDBType.BYREF; } else { throw ADP.InvalidSizeValue(size); } } else // fixed length data { bytecount = dbtype.fixlen; size = bytecount; } bindings.CurrentIndex = index; // tagDBPARAMBINDINFO info for SetParameterInfo bindings.DataSourceType = dbtype.dbString.DangerousGetHandle(); // NOTE: This is a constant and isn't exposed publicly, so there really isn't a potential for Handle Recycling. bindings.Name = ADP.PtrZero; bindings.ParamSize = new IntPtr(size); bindings.Flags = GetBindFlags(direction); //bindings.Precision = precision; //bindings.Scale = scale; // tagDBBINDING info for CreateAccessor bindings.Ordinal = (IntPtr)(index + 1); bindings.Part = dbtype.dbPart; bindings.ParamIO = GetBindDirection(direction); bindings.Precision = precision; bindings.Scale = scale; bindings.DbType = wtype; bindings.MaxLen = bytecount; // also increments databuffer size (uses DbType) //bindings.ValueOffset = bindings.DataBufferSize; // set via MaxLen //bindings.LengthOffset = i * sizeof_int64; //bindings.StatusOffset = i * sizeof_int64 + sizeof_int32; //bindings.TypeInfoPtr = 0; //bindings.ObjectPtr = 0; //bindings.BindExtPtr = 0; //bindings.MemOwner = /*DBMEMOWNER_CLIENTOWNED*/0; //bindings.Flags = 0; //bindings.ParameterChangeID = changeID; // bind until something changes Debug.Assert(_changeID == changeID, "parameter has unexpectedly changed"); if (Bid.AdvancedOn) { Bid.Trace("<oledb.struct.tagDBPARAMBINDINFO|INFO|ADV> index=%d, parameterName='%ls'\n", index, ParameterName); //, bindings.BindInfo[index]); Bid.Trace("<oledb.struct.tagDBBINDING|INFO|ADV>\n"); //, bindings.DBBinding[index]); } return(IsParameterComputed()); }
internal bool BindParameter(int index, Bindings bindings) { int size; int ptrSize; byte precisionInternal; byte scaleInternal; object obj2 = this.Value; NativeDBType bindType = this.GetBindType(obj2); if (bindType.enumOleDbType == System.Data.OleDb.OleDbType.Empty) { throw ODB.UninitializedParameters(index, bindType.enumOleDbType); } this._coerceMetaType = bindType; obj2 = CoerceValue(obj2, bindType); this.CoercedValue = obj2; ParameterDirection direction = this.Direction; if (this.ShouldSerializePrecision()) { precisionInternal = this.PrecisionInternal; } else { precisionInternal = this.ValuePrecision(obj2); } if (precisionInternal == 0) { precisionInternal = bindType.maxpre; } if (this.ShouldSerializeScale()) { scaleInternal = this.ScaleInternal; } else { scaleInternal = this.ValueScale(obj2); } int wType = bindType.wType; if (bindType.islong) { ptrSize = ADP.PtrSize; if (this.ShouldSerializeSize()) { size = this.Size; } else if (0x81 == bindType.dbType) { size = 0x7fffffff; } else if (130 == bindType.dbType) { size = 0x3fffffff; } else { size = 0x7fffffff; } wType |= 0x4000; } else if (bindType.IsVariableLength) { bool flag; if (!this.ShouldSerializeSize() && ADP.IsDirection(this, ParameterDirection.Output)) { throw ADP.UninitializedParameterSize(index, this._coerceMetaType.dataType); } if (this.ShouldSerializeSize()) { size = this.Size; flag = false; } else { size = this.ValueSize(obj2); flag = true; } if (0 >= size) { if (size != 0) { if (-1 != size) { throw ADP.InvalidSizeValue(size); } ptrSize = ADP.PtrSize; wType |= 0x4000; } else if (130 == wType) { ptrSize = 2; } else { ptrSize = 0; } } else { if (130 == bindType.wType) { ptrSize = (Math.Min(size, 0x3ffffffe) * 2) + 2; } else { ptrSize = size; } if (flag && (0x81 == bindType.dbType)) { size = Math.Min(size, 0x3ffffffe) * 2; } if (0x2000 < ptrSize) { ptrSize = ADP.PtrSize; wType |= 0x4000; } } } else { ptrSize = bindType.fixlen; size = ptrSize; } bindings.CurrentIndex = index; bindings.DataSourceType = bindType.dbString.DangerousGetHandle(); bindings.Name = ADP.PtrZero; bindings.ParamSize = new IntPtr(size); bindings.Flags = GetBindFlags(direction); bindings.Ordinal = (IntPtr)(index + 1); bindings.Part = bindType.dbPart; bindings.ParamIO = GetBindDirection(direction); bindings.Precision = precisionInternal; bindings.Scale = scaleInternal; bindings.DbType = wType; bindings.MaxLen = ptrSize; if (Bid.AdvancedOn) { Bid.Trace("<oledb.struct.tagDBPARAMBINDINFO|INFO|ADV> index=%d, parameterName='%ls'\n", index, this.ParameterName); Bid.Trace("<oledb.struct.tagDBBINDING|INFO|ADV>\n"); } return(this.IsParameterComputed()); }