private void WriteParameterInfo(TdsMetaParameter param) { /* * Ms.net send non-nullable datatypes as nullable and allows setting null values * to int/float etc.. So, using Nullable form of type for all data */ param.IsNullable = true; TdsColumnType colType = param.GetMetaType(); param.IsNullable = false; bool partLenType = false; int size = param.Size; if (size < 1) { if (size < 0) { partLenType = true; } size = param.GetActualSize(); } /* * If the value is null, not setting the size to 0 will cause varchar * fields to get inserted as an empty string rather than an null. */ if (param.IsTextType && (param.Value == null || param.Value == DBNull.Value)) { size = 0; } // Change colType according to the following table /* * Original Type Maxlen New Type * * NVarChar 4000 UCS2 NText * BigVarChar 8000 ASCII Text * BigVarBinary 8000 bytes Image * */ TdsColumnType origColType = colType; if (colType == TdsColumnType.BigNVarChar) { // param.GetActualSize() returns len*2 if (size == param.Size) { size <<= 1; } if ((size >> 1) > 4000) { colType = TdsColumnType.NText; } } else if (colType == TdsColumnType.BigVarChar) { if (size > 8000) { colType = TdsColumnType.Text; } } else if (colType == TdsColumnType.BigVarBinary) { if (size > 8000) { colType = TdsColumnType.Image; } } else if (colType == TdsColumnType.DateTime2 || colType == TdsColumnType.DateTimeOffset) { // HACK: Wire-level DateTime{2,Offset} // require TDS 7.3, which this driver // does not implement correctly--so we // serialize to ASCII instead. colType = TdsColumnType.Char; } // Calculation of TypeInfo field /* * orig size value TypeInfo field * * >= 0 <= Maxlen origColType + content len * > Maxlen NewType as per above table + content len * -1 origColType + USHORTMAXLEN (0xFFFF) + content len (TDS 9) * */ // Write updated colType, iff partLenType == false if (TdsVersion > TdsVersion.tds81 && partLenType) { Comm.Append((byte)origColType); Comm.Append((short)-1); } else if (ServerTdsVersion > TdsVersion.tds70 && origColType == TdsColumnType.Decimal) { Comm.Append((byte)TdsColumnType.Numeric); } else { Comm.Append((byte)colType); } if (IsLargeType(colType)) { Comm.Append((short)size); // Parameter size passed in SqlParameter } else if (IsBlobType(colType)) { Comm.Append(size); // Parameter size passed in SqlParameter } else { Comm.Append((byte)size); } // Precision and Scale are non-zero for only decimal/numeric if (param.TypeName == "decimal" || param.TypeName == "numeric") { Comm.Append((param.Precision != 0) ? param.Precision : Precision); Comm.Append(param.Scale); // Convert the decimal value according to Scale if (param.Value != null && param.Value != DBNull.Value && ((decimal)param.Value) != Decimal.MaxValue && ((decimal)param.Value) != Decimal.MinValue && ((decimal)param.Value) != long.MaxValue && ((decimal)param.Value) != long.MinValue && ((decimal)param.Value) != ulong.MaxValue && ((decimal)param.Value) != ulong.MinValue) { long expo = (long)new Decimal(System.Math.Pow(10, (double)param.Scale)); long pVal = (long)(((decimal)param.Value) * expo); param.Value = pVal; } } /* VARADHAN: TDS 8 Debugging */ /* * if (Collation != null) { * Console.WriteLine ("Collation is not null"); * Console.WriteLine ("Column Type: {0}", colType); * Console.WriteLine ("Collation bytes: {0} {1} {2} {3} {4}", Collation[0], Collation[1], Collation[2], * Collation[3], Collation[4]); * } else { * Console.WriteLine ("Collation is null"); * } */ // Tds > 7.0 uses collation if (Collation != null && (colType == TdsColumnType.BigChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarChar || colType == TdsColumnType.NChar || colType == TdsColumnType.NVarChar || colType == TdsColumnType.Text || colType == TdsColumnType.NText)) { Comm.Append(Collation); } // LAMESPEC: size should be 0xFFFF for any bigvarchar, bignvarchar and bigvarbinary // types if param value is NULL if ((colType == TdsColumnType.BigVarChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarBinary || colType == TdsColumnType.Image) && (param.Value == null || param.Value == DBNull.Value)) { size = -1; } else { size = param.GetActualSize(); } if (IsLargeType(colType)) { Comm.Append((short)size); } else if (IsBlobType(colType)) { Comm.Append(size); } else { Comm.Append((byte)size); } if (size > 0) { switch (param.TypeName) { case "money": { // 4 == SqlMoney::MoneyFormat.NumberDecimalDigits Decimal val = Decimal.Round((decimal)param.Value, 4); int[] arr = Decimal.GetBits(val); if (val >= 0) { Comm.Append(arr[1]); Comm.Append(arr[0]); } else { Comm.Append(~arr[1]); Comm.Append(~arr[0] + 1); } break; } case "smallmoney": { // 4 == SqlMoney::MoneyFormat.NumberDecimalDigits Decimal val = Decimal.Round((decimal)param.Value, 4); if (val < SMALLMONEY_MIN || val > SMALLMONEY_MAX) { throw new OverflowException(string.Format( CultureInfo.InvariantCulture, "Value '{0}' is not valid for SmallMoney." + " Must be between {1:N4} and {2:N4}.", val, SMALLMONEY_MIN, SMALLMONEY_MAX)); } int[] arr = Decimal.GetBits(val); int sign = (val > 0 ? 1: -1); Comm.Append(sign * arr[0]); break; } case "datetime": Comm.Append((DateTime)param.Value, 8); break; case "smalldatetime": Comm.Append((DateTime)param.Value, 4); break; case "varchar": case "nvarchar": case "char": case "nchar": case "text": case "ntext": case "datetime2": case "datetimeoffset": byte [] tmp = param.GetBytes(); Comm.Append(tmp); break; case "uniqueidentifier": Comm.Append(((Guid)param.Value).ToByteArray()); break; default: Comm.Append(param.Value); break; } } return; }
private void WriteParameterInfo (TdsMetaParameter param) { /* Ms.net send non-nullable datatypes as nullable and allows setting null values to int/float etc.. So, using Nullable form of type for all data */ param.IsNullable = true; TdsColumnType colType = param.GetMetaType (); param.IsNullable = false; bool partLenType = false; int size = param.Size; if (size < 1) { if (size < 0) partLenType = true; size = param.GetActualSize (); } /* * If the value is null, not setting the size to 0 will cause varchar * fields to get inserted as an empty string rather than an null. */ if (colType != TdsColumnType.IntN && colType != TdsColumnType.DateTimeN) { if (param.Value == null || param.Value == DBNull.Value) size = 0; } // Change colType according to the following table /* * Original Type Maxlen New Type * * NVarChar 4000 UCS2 NText * BigVarChar 8000 ASCII Text * BigVarBinary 8000 bytes Image * */ TdsColumnType origColType = colType; if (colType == TdsColumnType.BigNVarChar) { // param.GetActualSize() returns len*2 if (size == param.Size) size <<= 1; if ((size >> 1) > 4000) colType = TdsColumnType.NText; } else if (colType == TdsColumnType.BigVarChar) { if (size > 8000) colType = TdsColumnType.Text; } else if (colType == TdsColumnType.BigVarBinary) { if (size > 8000) colType = TdsColumnType.Image; } else if (colType == TdsColumnType.DateTime2 || colType == TdsColumnType.DateTimeOffset) { // HACK: Wire-level DateTime{2,Offset} // require TDS 7.3, which this driver // does not implement correctly--so we // serialize to ASCII instead. colType = TdsColumnType.Char; } // Calculation of TypeInfo field /* * orig size value TypeInfo field * * >= 0 <= Maxlen origColType + content len * > Maxlen NewType as per above table + content len * -1 origColType + USHORTMAXLEN (0xFFFF) + content len (TDS 9) * */ // Write updated colType, iff partLenType == false if (TdsVersion > TdsVersion.tds81 && partLenType) { Comm.Append ((byte)origColType); Comm.Append ((short)-1); } else if (ServerTdsVersion > TdsVersion.tds70 && origColType == TdsColumnType.Decimal) { Comm.Append ((byte)TdsColumnType.Numeric); } else { Comm.Append ((byte)colType); } if (IsLargeType (colType)) Comm.Append ((short)size); // Parameter size passed in SqlParameter else if (IsBlobType (colType)) Comm.Append (size); // Parameter size passed in SqlParameter else Comm.Append ((byte)size); // Precision and Scale are non-zero for only decimal/numeric if ( param.TypeName == "decimal" || param.TypeName == "numeric") { Comm.Append ((param.Precision !=0 ) ? param.Precision : Precision); Comm.Append (param.Scale); // Convert the decimal value according to Scale if (param.Value != null && param.Value != DBNull.Value && ((decimal)param.Value) != Decimal.MaxValue && ((decimal)param.Value) != Decimal.MinValue && ((decimal)param.Value) != long.MaxValue && ((decimal)param.Value) != long.MinValue && ((decimal)param.Value) != ulong.MaxValue && ((decimal)param.Value) != ulong.MinValue) { long expo = (long)new Decimal (System.Math.Pow (10, (double)param.Scale)); long pVal = (long)(((decimal)param.Value) * expo); param.Value = pVal; } } /* VARADHAN: TDS 8 Debugging */ /* if (Collation != null) { Console.WriteLine ("Collation is not null"); Console.WriteLine ("Column Type: {0}", colType); Console.WriteLine ("Collation bytes: {0} {1} {2} {3} {4}", Collation[0], Collation[1], Collation[2], Collation[3], Collation[4]); } else { Console.WriteLine ("Collation is null"); } */ // Tds > 7.0 uses collation if (Collation != null && (colType == TdsColumnType.BigChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarChar || colType == TdsColumnType.NChar || colType == TdsColumnType.NVarChar || colType == TdsColumnType.Text || colType == TdsColumnType.NText)) Comm.Append (Collation); // LAMESPEC: size should be 0xFFFF for any bigvarchar, bignvarchar and bigvarbinary // types if param value is NULL if ((colType == TdsColumnType.BigVarChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarBinary || colType == TdsColumnType.Image) && (param.Value == null || param.Value == DBNull.Value)) size = -1; else size = param.GetActualSize (); if (IsLargeType (colType)) Comm.Append ((short)size); else if (IsBlobType (colType)) Comm.Append (size); else Comm.Append ((byte)size); if (size > 0) { switch (param.TypeName) { case "money" : { // 4 == SqlMoney::MoneyFormat.NumberDecimalDigits Decimal val = Decimal.Round ((decimal) param.Value, 4); int[] arr = Decimal.GetBits (val); if (val >= 0) { Comm.Append (arr[1]); Comm.Append (arr[0]); } else { Comm.Append (~arr[1]); Comm.Append (~arr[0] + 1); } break; } case "smallmoney": { // 4 == SqlMoney::MoneyFormat.NumberDecimalDigits Decimal val = Decimal.Round ((decimal) param.Value, 4); if (val < SMALLMONEY_MIN || val > SMALLMONEY_MAX) throw new OverflowException (string.Format ( CultureInfo.InvariantCulture, "Value '{0}' is not valid for SmallMoney." + " Must be between {1:N4} and {2:N4}.", val, SMALLMONEY_MIN, SMALLMONEY_MAX)); int[] arr = Decimal.GetBits (val); int sign = (val>0 ? 1: -1); Comm.Append (sign * arr[0]); break; } case "datetime": Comm.Append ((DateTime)param.Value, 8); break; case "smalldatetime": Comm.Append ((DateTime)param.Value, 4); break; case "varchar" : case "nvarchar" : case "char" : case "nchar" : case "text" : case "ntext" : case "datetime2": case "datetimeoffset": byte [] tmp = param.GetBytes (); Comm.Append (tmp); break; case "uniqueidentifier" : Comm.Append (((Guid)param.Value).ToByteArray()); break; default : Comm.Append (param.Value); break; } } return; }
private void WriteParameterInfo (TdsMetaParameter param) { /* Ms.net send non-nullable datatypes as nullable and allows setting null values to int/float etc.. So, using Nullable form of type for all data */ param.IsNullable = true; TdsColumnType colType = param.GetMetaType (); param.IsNullable = false; bool partLenType = false; int size = param.Size; if (size < 1) { if (size < 0) partLenType = true; size = param.GetActualSize (); } // Change colType according to the following table /* * Original Type Maxlen New Type * * NVarChar 4000 UCS2 NText * BigVarChar 8000 ASCII Text * BigVarBinary 8000 bytes Image * */ TdsColumnType origColType = colType; if (colType == TdsColumnType.BigNVarChar) { // param.GetActualSize() returns len*2 if (size == param.Size) size <<= 1; if ((size >> 1) > 4000) colType = TdsColumnType.NText; } else if (colType == TdsColumnType.BigVarChar) { if (size > 8000) colType = TdsColumnType.Text; } else if (colType == TdsColumnType.BigVarBinary) { if (size > 8000) colType = TdsColumnType.Image; } // Calculation of TypeInfo field /* * orig size value TypeInfo field * * >= 0 <= Maxlen origColType + content len * > Maxlen NewType as per above table + content len * -1 origColType + USHORTMAXLEN (0xFFFF) + content len (TDS 9) * */ // Write updated colType, iff partLenType == false if (TdsVersion > TdsVersion.tds81 && partLenType) { Comm.Append ((byte)origColType); Comm.Append ((short)-1); } else if (ServerTdsVersion > TdsVersion.tds70 && origColType == TdsColumnType.Decimal) { Comm.Append ((byte)TdsColumnType.Numeric); } else { Comm.Append ((byte)colType); } if (IsLargeType (colType)) Comm.Append ((short)size); // Parameter size passed in SqlParameter else if (IsBlobType (colType)) Comm.Append (size); // Parameter size passed in SqlParameter else Comm.Append ((byte)size); // Precision and Scale are non-zero for only decimal/numeric if ( param.TypeName == "decimal" || param.TypeName == "numeric") { Comm.Append ((param.Precision !=0 ) ? param.Precision : (byte) 29); Comm.Append (param.Scale); } /* VARADHAN: TDS 8 Debugging */ /* if (Collation != null) { Console.WriteLine ("Collation is not null"); Console.WriteLine ("Column Type: {0}", colType); Console.WriteLine ("Collation bytes: {0} {1} {2} {3} {4}", Collation[0], Collation[1], Collation[2], Collation[3], Collation[4]); } else { Console.WriteLine ("Collation is null"); } */ // Tds > 7.0 uses collation if (Collation != null && (colType == TdsColumnType.BigChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarChar || colType == TdsColumnType.NChar || colType == TdsColumnType.NVarChar || colType == TdsColumnType.Text || colType == TdsColumnType.NText)) Comm.Append (Collation); // LAMESPEC: size should be 0xFFFF for any bigvarchar, bignvarchar and bigvarbinary // types if param value is NULL if ((colType == TdsColumnType.BigVarChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarBinary) && (param.Value == null || param.Value == DBNull.Value)) size = -1; else size = param.GetActualSize (); if (IsLargeType (colType)) Comm.Append ((short)size); else if (IsBlobType (colType)) Comm.Append (size); else Comm.Append ((byte)size); if (size > 0) { switch (param.TypeName) { case "money" : { Decimal val = (decimal) param.Value; int[] arr = Decimal.GetBits (val); if (val >= 0) { Comm.Append (arr[1]); Comm.Append (arr[0]); } else { Comm.Append (~arr[1]); Comm.Append (~arr[0] + 1); } break; } case "smallmoney": { Decimal val = (decimal) param.Value; if (val < SMALLMONEY_MIN || val > SMALLMONEY_MAX) throw new OverflowException (string.Format ( CultureInfo.InvariantCulture, "Value '{0}' is not valid for SmallMoney." + " Must be between {1:N4} and {2:N4}.", #if NET_2_0 val, #else val.ToString (CultureInfo.CurrentCulture), #endif SMALLMONEY_MIN, SMALLMONEY_MAX)); int[] arr = Decimal.GetBits (val); int sign = (val>0 ? 1: -1); Comm.Append (sign * arr[0]); break; } case "datetime": Comm.Append ((DateTime)param.Value, 8); break; case "smalldatetime": Comm.Append ((DateTime)param.Value, 4); break; case "varchar" : case "nvarchar" : case "char" : case "nchar" : case "text" : case "ntext" : byte [] tmp = param.GetBytes (); Comm.Append (tmp); break; case "uniqueidentifier" : Comm.Append (((Guid)param.Value).ToByteArray()); break; default : Comm.Append (param.Value); break; } } return; }
private void WriteParameterInfo(TdsMetaParameter param) { /* * Ms.net send non-nullable datatypes as nullable and allows setting null values * to int/float etc.. So, using Nullable form of type for all data */ param.IsNullable = true; TdsColumnType colType = param.GetMetaType(); param.IsNullable = false; bool partLenType = false; int size = param.Size; if (size < 1) { if (size < 0) { partLenType = true; } size = param.GetActualSize(); } // Change colType according to the following table /* * Original Type Maxlen New Type * * NVarChar 4000 UCS2 NText * BigVarChar 8000 ASCII Text * BigVarBinary 8000 bytes Image * */ TdsColumnType origColType = colType; if (colType == TdsColumnType.BigNVarChar) { // param.GetActualSize() returns len*2 if (size == param.Size) { size <<= 1; } if ((size >> 1) > 4000) { colType = TdsColumnType.NText; } } else if (colType == TdsColumnType.BigVarChar) { if (size > 8000) { colType = TdsColumnType.Text; } } else if (colType == TdsColumnType.BigVarBinary) { if (size > 8000) { colType = TdsColumnType.Image; } } // Calculation of TypeInfo field /* * orig size value TypeInfo field * * >= 0 <= Maxlen origColType + content len * > Maxlen NewType as per above table + content len * -1 origColType + USHORTMAXLEN (0xFFFF) + content len (TDS 9) * */ // Write updated colType, iff partLenType == false if (TdsVersion > TdsVersion.tds81 && partLenType) { Comm.Append((byte)origColType); Comm.Append((short)-1); } else if (ServerTdsVersion > TdsVersion.tds70 && origColType == TdsColumnType.Decimal) { Comm.Append((byte)TdsColumnType.Numeric); } else { Comm.Append((byte)colType); } if (IsLargeType(colType)) { Comm.Append((short)size); // Parameter size passed in SqlParameter } else if (IsBlobType(colType)) { Comm.Append(size); // Parameter size passed in SqlParameter } else { Comm.Append((byte)size); } // Precision and Scale are non-zero for only decimal/numeric if (param.TypeName == "decimal" || param.TypeName == "numeric") { Comm.Append((param.Precision != 0) ? param.Precision : (byte)29); Comm.Append(param.Scale); } /* VARADHAN: TDS 8 Debugging */ /* * if (Collation != null) { * Console.WriteLine ("Collation is not null"); * Console.WriteLine ("Column Type: {0}", colType); * Console.WriteLine ("Collation bytes: {0} {1} {2} {3} {4}", Collation[0], Collation[1], Collation[2], * Collation[3], Collation[4]); * } else { * Console.WriteLine ("Collation is null"); * } */ // Tds > 7.0 uses collation if (Collation != null && (colType == TdsColumnType.BigChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarChar || colType == TdsColumnType.NChar || colType == TdsColumnType.NVarChar || colType == TdsColumnType.Text || colType == TdsColumnType.NText)) { Comm.Append(Collation); } // LAMESPEC: size should be 0xFFFF for any bigvarchar, bignvarchar and bigvarbinary // types if param value is NULL if ((colType == TdsColumnType.BigVarChar || colType == TdsColumnType.BigNVarChar || colType == TdsColumnType.BigVarBinary) && (param.Value == null || param.Value == DBNull.Value)) { size = -1; } else { size = param.GetActualSize(); } if (IsLargeType(colType)) { Comm.Append((short)size); } else if (IsBlobType(colType)) { Comm.Append(size); } else { Comm.Append((byte)size); } if (size > 0) { switch (param.TypeName) { case "money": { Decimal val = (decimal)param.Value; int[] arr = Decimal.GetBits(val); if (val >= 0) { Comm.Append(arr[1]); Comm.Append(arr[0]); } else { Comm.Append(~arr[1]); Comm.Append(~arr[0] + 1); } break; } case "smallmoney": { Decimal val = (decimal)param.Value; if (val < SMALLMONEY_MIN || val > SMALLMONEY_MAX) { throw new OverflowException(string.Format( CultureInfo.InvariantCulture, "Value '{0}' is not valid for SmallMoney." + " Must be between {1:N4} and {2:N4}.", #if NET_2_0 val, #else val.ToString(CultureInfo.CurrentCulture), #endif SMALLMONEY_MIN, SMALLMONEY_MAX)); } int[] arr = Decimal.GetBits(val); int sign = (val > 0 ? 1: -1); Comm.Append(sign * arr[0]); break; } case "datetime": Comm.Append((DateTime)param.Value, 8); break; case "smalldatetime": Comm.Append((DateTime)param.Value, 4); break; case "varchar": case "nvarchar": case "char": case "nchar": case "text": case "ntext": byte [] tmp = param.GetBytes(); Comm.Append(tmp); break; case "uniqueidentifier": Comm.Append(((Guid)param.Value).ToByteArray()); break; default: Comm.Append(param.Value); break; } } return; }