bool isSizeSet = false;
bool isNullable;
object value;
+ bool isVariableSizeType;
#endregion // Fields
public object Value {
get { return value; }
- set { this.value = value; }
+ set {
+ if (value == DBNull.Value || value == null) {
+ this.value = value;
+ return;
+ }
+
+ // if size is set, truncate the value to specified size
+ if (value.GetType () == typeof (string)) {
+ int len = ((string)value).Length;
+
+ if ((TypeName == "nvarchar" ||
+ TypeName == "nchar")
+ && isSizeSet && size > 0 && len > size) {
+ this.value = ((string)value).Substring (0, size);
+ } else {
+ this.value = value;
+ }
+ } else if (value.GetType () == typeof (byte[])) {
+ int len = ((byte[])value).Length;
+
+ if (isSizeSet && size > 0 && len > size ) {
+ byte [] tmpVal = new byte [size];
+ Array.Copy (((byte[]) value), ((byte[]) this.value), size);
+ this.value = tmpVal;
+ } else {
+ this.value = value;
+ }
+ } else {
+ this.value = value;
+ }
+ }
}
public byte Precision {
}
public byte Scale {
- get { return scale; }
+ get {
+ if (TypeName == "decimal" || TypeName == "numeric") {
+ if (scale == 0 && !Convert.IsDBNull(Value)) {
+ int[] arr = Decimal.GetBits (
+ Convert.ToDecimal(Value));
+ scale = (byte)((arr[3]>>16) & (int)0xFF);
+ }
+ }
+ return scale;
+ }
set { scale = value; }
}
}
}
+ public bool IsVariableSizeType
+ {
+ get { return isVariableSizeType; }
+ set { isVariableSizeType = value; }
+ }
+
#endregion // Properties
#region Methods
internal string Prepare ()
{
- StringBuilder result = new StringBuilder (String.Format ("{0} {1}", ParameterName, TypeName));
- switch (TypeName) {
+ string typeName = TypeName;
+
+ if (typeName == "varbinary") {
+ int size = Size;
+ if (size <= 0) {
+ size = GetActualSize ();
+ }
+
+ if (size > 8000) {
+ typeName = "image";
+ }
+ }
+
+ string includeAt = "@";
+ if (ParameterName [0] == '@')
+ includeAt = "";
+ StringBuilder result = new StringBuilder (String.Format ("{0}{1} {2}", includeAt, ParameterName, typeName));
+ switch (typeName) {
case "decimal":
case "numeric":
- result.Append (String.Format ("({0},{1})", Precision, Scale));
+ // msdotnet sends a default precision of 28
+ result.Append (String.Format ("({0},{1})",
+ (Precision == (byte)0 ? (byte)28 : Precision), Scale));
break;
case "varchar":
case "varbinary":
if (size <= 0)
size = 1;
}
- result.Append (String.Format ("({0})", size));
+ result.Append (size > 8000 ? "(max)" : String.Format ("({0})", size));
break;
case "nvarchar":
- result.Append (String.Format ("({0})", Size > 0 ? Size : 4000));
+ result.Append (Size > 0 ? (Size > 8000 ? "(max)" : String.Format ("({0})", Size)) : "(4000)");
break;
case "char":
case "nchar":
switch (Value.GetType ().ToString ()) {
case "System.String":
- return ((string) value).Length;
+ int len = ((string)value).Length;
+ if (TypeName == "nvarchar" || TypeName == "nchar" || TypeName == "ntext")
+ len *= 2;
+ return len ;
case "System.Byte[]":
return ((byte[]) value).Length;
}
private int GetSize ()
{
- if (IsNullable) {
- switch (TypeName) {
- case "bigint":
- return 8;
- case "datetime":
- return 8;
- case "float":
- return 8;
- case "int":
- return 4;
- case "real":
- return 4;
- case "smalldatetime":
- return 4;
- case "smallint":
- return 2;
- case "tinyint":
- return 1;
- }
+ switch (TypeName) {
+ case "decimal":
+ return 17;
+ case "uniqueidentifier":
+ return 16;
+ case "bigint":
+ case "datetime":
+ case "float":
+ case "money":
+ return 8;
+ case "int":
+ case "real":
+ case "smalldatetime":
+ case "smallmoney":
+ return 4;
+ case "smallint":
+ return 2;
+ case "tinyint":
+ case "bit":
+ return 1;
+ /*
+ case "nvarchar" :
+ */
+ case "nchar" :
+ case "ntext" :
+ return size*2 ;
}
return size;
}
+ internal byte[] GetBytes ()
+ {
+ byte[] result = {};
+ if (Value == DBNull.Value || Value == null)
+ return result;
+
+ switch (TypeName)
+ {
+ case "nvarchar" :
+ case "nchar" :
+ case "ntext" :
+ return Encoding.Unicode.GetBytes ((string)Value);
+ case "varchar" :
+ case "char" :
+ case "text" :
+ return Encoding.Default.GetBytes ((string)Value);
+ default :
+ return ((byte[]) Value);
+ }
+ }
+
internal TdsColumnType GetMetaType ()
{
switch (TypeName) {
case "binary":
- return TdsColumnType.Binary;
+ return TdsColumnType.BigBinary;
case "bit":
+ if (IsNullable)
+ return TdsColumnType.BitN;
return TdsColumnType.Bit;
+ case "bigint":
+ return TdsColumnType.IntN;
case "char":
return TdsColumnType.Char;
+ case "money":
+ if (IsNullable)
+ return TdsColumnType.MoneyN;
+ return TdsColumnType.Money;
+ case "smallmoney":
+ if (IsNullable)
+ return TdsColumnType.MoneyN ;
+ return TdsColumnType.Money4;
case "decimal":
return TdsColumnType.Decimal;
case "datetime":
if (IsNullable)
return TdsColumnType.DateTimeN;
return TdsColumnType.DateTime;
+ case "smalldatetime":
+ if (IsNullable)
+ return TdsColumnType.DateTimeN;
+ return TdsColumnType.DateTime4;
case "float":
+ if (IsNullable)
+ return TdsColumnType.FloatN ;
return TdsColumnType.Float8;
case "image":
return TdsColumnType.Image;
case "ntext":
return TdsColumnType.NText;
case "nvarchar":
- return TdsColumnType.NVarChar;
+ return TdsColumnType.BigNVarChar;
case "real":
+ if (IsNullable)
+ return TdsColumnType.FloatN ;
return TdsColumnType.Real;
case "smallint":
if (IsNullable)
case "uniqueidentifier":
return TdsColumnType.UniqueIdentifier;
case "varbinary":
- return TdsColumnType.VarBinary;
+ return TdsColumnType.BigVarBinary;
case "varchar":
- return TdsColumnType.VarChar;
+ return TdsColumnType.BigVarChar;
default:
- throw new NotSupportedException ();
+ throw new NotSupportedException ("Unknown Type : " + TypeName);
+ }
+ }
+
+ public void Validate (int index)
+ {
+ if ((this.direction == TdsParameterDirection.InputOutput || this.direction == TdsParameterDirection.Output) &&
+ this.isVariableSizeType && (Value == DBNull.Value || Value == null) && Size == 0
+ )
+ {
+ throw new InvalidOperationException (String.Format ("{0}[{1}]: the Size property should " +
+ "not be of size 0",
+ this.typeName,
+ index));
}
}