// Tim Coleman (tim@timcoleman.com)
// Diego Caravana (diego@toth.it)
// Umadevi S (sumadevi@novell.com)
+// Amit Biswas (amit@amitbiswas.com)
//
// (C) Ximian, Inc. 2002
// Copyright (C) Tim Coleman, 2002
using System.ComponentModel;
using System.Data;
using System.Data.Common;
-#if NET_2_0
-using System.Data.ProviderBase;
-#endif // NET_2_0
using System.Data.SqlTypes;
using System.Runtime.InteropServices;
using System.Text;
namespace System.Data.SqlClient {
[TypeConverterAttribute (typeof (SqlParameterConverter))]
#if NET_2_0
- public sealed class SqlParameter : DbParameterBase, IDbDataParameter, IDataParameter, ICloneable
+ public sealed class SqlParameter : DbParameter, IDbDataParameter, IDataParameter, ICloneable
#else
public sealed class SqlParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
#endif // NET_2_0
DbType dbType;
ParameterDirection direction = ParameterDirection.Input;
bool isNullable;
- bool isSizeSet = false;
bool isTypeSet = false;
int offset;
SqlDbType sqlDbType;
string sourceColumn;
DataRowVersion sourceVersion;
+ SqlCompareOptions compareInfo;
+ int localeId;
+ Object sqlValue;
+ string udtTypeName;
+#if NET_2_0
+ bool sourceColumnNullMapping;
+ string xmlSchemaCollectionDatabase = String.Empty;
+ string xmlSchemaCollectionOwningSchema = String.Empty;
+ string xmlSchemaCollectionName = String.Empty;
+#endif
#endregion // Fields
public SqlParameter ()
: this (String.Empty, SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
{
+ isTypeSet = false;
}
public SqlParameter (string parameterName, object value)
{
- metaParameter = new TdsMetaParameter (parameterName, SqlTypeToFrameworkType (value));
+ metaParameter = new TdsMetaParameter (parameterName, value);
+ InferSqlType (value);
+ metaParameter.Value = SqlTypeToFrameworkType(value);
this.sourceVersion = DataRowVersion.Current;
- InferSqlType (value);
}
public SqlParameter (string parameterName, SqlDbType dbType)
metaParameter = new TdsMetaParameter (parameterName, size,
isNullable, precision,
scale,
- SqlTypeToFrameworkType (value));
- SqlDbType = dbType;
+ value);
+ if (dbType != SqlDbType.Variant)
+ SqlDbType = dbType;
+ metaParameter.Value = SqlTypeToFrameworkType (value);
Direction = direction;
SourceColumn = sourceColumn;
SourceVersion = sourceVersion;
}
+#if NET_2_0
+ public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, bool sourceColumnNullMapping, Object value, string xmlSchemaCollectionDatabase, string xmlSchemaCollectionOwningSchema, string xmlSchemaCollectionName)
+ : this (parameterName, dbType, size, direction, false, precision, scale, sourceColumn, sourceVersion, value)
+ {
+ XmlSchemaCollectionDatabase = xmlSchemaCollectionDatabase;
+ XmlSchemaCollectionOwningSchema = xmlSchemaCollectionOwningSchema;
+ XmlSchemaCollectionName = xmlSchemaCollectionName;
+ SourceColumnNullMapping = sourceColumnNullMapping;
+ }
+#endif
+
// This constructor is used internally to construct a
// SqlParameter. The value array comes from sp_procedure_params_rowset.
// This is in SqlCommand.DeriveParameters.
set { container = value; }
}
+ internal void CheckIfInitialized ()
+ {
+ if (!isTypeSet)
+ throw new Exception ("all parameters to have an explicity set type");
+
+ if (MetaParameter.IsVariableSizeType) {
+ if (SqlDbType == SqlDbType.Decimal && Precision == 0)
+ throw new Exception ("Parameter of type 'Decimal' have an explicitly set Precision and Scale");
+ else if (Size == 0)
+ throw new Exception ("all variable length parameters to have an explicitly set non-zero Size");
+ }
+ }
+
#if ONLY_1_0 || ONLY_1_1
[Browsable (false)]
[DataSysDescription ("The parameter generic type.")]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[RefreshProperties (RefreshProperties.All)]
-#endif
[DataCategory ("Data")]
+#endif
public
#if NET_2_0
override
#endif // NET_2_0
- DbType DbType {
+ DbType DbType {
get { return dbType; }
set {
SetDbType (value);
}
}
- [DataCategory ("Data")]
#if ONLY_1_0 || ONLY_1_1
+ [DataCategory ("Data")]
[DataSysDescription ("Input, output, or bidirectional parameter.")]
[DefaultValue (ParameterDirection.Input)]
#endif
get { return metaParameter; }
}
- string IDataParameter.ParameterName {
- get { return metaParameter.ParameterName; }
- set { metaParameter.ParameterName = value; }
- }
-
#if ONLY_1_0 || ONLY_1_1
[Browsable (false)]
[DataSysDescription ("a design-time property used for strongly typed code-generation.")]
}
[Browsable (false)]
- [DataCategory ("Data")]
#if ONLY_1_0 || ONLY_1_1
+ [DataCategory ("Data")]
[DataSysDescription ("Offset in variable length data types.")]
[DefaultValue (0)]
#endif
#if NET_2_0
[EditorBrowsable (EditorBrowsableState.Advanced)]
#endif
- public
-#if NET_2_0
- override
-#endif // NET_2_0
- int Offset {
+ public int Offset {
get { return offset; }
set { offset = value; }
}
set { metaParameter.ParameterName = value; }
}
- [DataCategory ("Data")]
+ [DefaultValue (0)]
#if ONLY_1_0 || ONLY_1_1
+ [DataCategory ("Data")]
[DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
- [DefaultValue (0)]
-#endif
-#if NET_2_0
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
-#endif
- public
-#if NET_2_0
- override
-#endif // NET_2_0
- byte Precision {
+#endif
+ public byte Precision {
get { return metaParameter.Precision; }
set { metaParameter.Precision = value; }
}
- [DataCategory ("Data")]
+ [DefaultValue (0)]
#if ONLY_1_0 || ONLY_1_1
+ [DataCategory ("Data")]
[DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
- [DefaultValue (0)]
-#endif
-#if NET_2_0
[Browsable (false)]
[EditorBrowsable (EditorBrowsableState.Never)]
#endif
- public
-#if NET_2_0
- override
-#endif // NET_2_0
- byte Scale {
+ public byte Scale {
get { return metaParameter.Scale; }
set { metaParameter.Scale = value; }
}
- [DataCategory ("Data")]
#if ONLY_1_0 || ONLY_1_1
- [DataSysDescription ("Size of variable length data types (strings & arrays).")]
+ [DataCategory ("Data")]
+ [DataSysDescription ("Size of variable length data types (string & arrays).")]
[DefaultValue (0)]
#endif
public
set { metaParameter.Size = value; }
}
- [DataCategory ("Data")]
#if ONLY_1_0 || ONLY_1_1
+ [DataCategory ("Data")]
[DataSysDescription ("When used by a DataAdapter.Update, the source column name that is used to find the DataSetColumn name in the ColumnMappings. This is to copy a value between the parameter and a datarow.")]
[DefaultValue ("")]
#endif
set { sourceColumn = value; }
}
- [DataCategory ("Data")]
#if ONLY_1_0 || ONLY_1_1
+ [DataCategory ("Data")]
[DataSysDescription ("When used by a DataAdapter.Update (UpdateCommand only), the version of the DataRow value that is used to update the data source.")]
[DefaultValue (DataRowVersion.Current)]
#endif
set { sourceVersion = value; }
}
- [DataCategory ("Data")]
#if ONLY_1_0 || ONLY_1_1
+ [DataCategory ("Data")]
[DataSysDescription ("The parameter native type.")]
[DefaultValue (SqlDbType.NVarChar)]
#endif
}
}
- [DataCategory ("Data")]
+ [TypeConverterAttribute (typeof (StringConverter))]
#if ONLY_1_0 || ONLY_1_1
+ [DataCategory ("Data")]
[DataSysDescription ("Value of the parameter.")]
[DefaultValue (null)]
-#endif
- [TypeConverterAttribute (typeof (StringConverter))]
-#if NET_2_0
+#else
[RefreshProperties (RefreshProperties.All)]
#endif
public
}
}
-//#if NET_2_0
-// public SqlCompareOptions CompareInfo{
+#if NET_2_0
+ [Browsable (false)]
+ public SqlCompareOptions CompareInfo{
+ get{ return compareInfo; }
+ set{ compareInfo = value; }
+ }
+
+ [Browsable (false)]
+ public int LocaleId {
+ get { return localeId; }
+ set { localeId = value; }
+ }
+
+ [Browsable (false)]
+ [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
+ public Object SqlValue {
+ get { return sqlValue; }
+ set { sqlValue = value; }
+ }
+
+ public override bool SourceColumnNullMapping {
+ get { return sourceColumnNullMapping; }
+ set { sourceColumnNullMapping = value; }
+ }
-//#endif
+ public string XmlSchemaCollectionDatabase {
+ get { return xmlSchemaCollectionDatabase; }
+ set { xmlSchemaCollectionDatabase = (value == null ? String.Empty : value); }
+ }
+ public string XmlSchemaCollectionName {
+ get { return xmlSchemaCollectionName; }
+ set {
+ xmlSchemaCollectionName = (value == null ? String.Empty : value);
+ }
+ }
+
+ public string XmlSchemaCollectionOwningSchema {
+ get { return xmlSchemaCollectionOwningSchema; }
+ set {
+ xmlSchemaCollectionOwningSchema = (value == null ? String.Empty : value);
+ }
+ }
+#endif
#endregion // Properties
#region Methods
// infer type information.
private void InferSqlType (object value)
{
- Type type = value.GetType ();
+ if (value == null || value == DBNull.Value) {
+ SetSqlDbType (SqlDbType.NVarChar);
+ return;
+ }
+ Type type = value.GetType ();
string exception = String.Format ("The parameter data type of {0} is invalid.", type.Name);
switch (type.FullName) {
SetSqlDbType (SqlDbType.Money);
break;
case "System.Object":
- case "System.DBNull":
- SetSqlDbType (SqlDbType.Variant); // variant can contain numeric,
- //string,binary or data and also nul //values, so we can later resolve // it to correct type.
- break;
+ SetSqlDbType (SqlDbType.Variant);
+ break;
default:
throw new ArgumentException (exception);
}
case DbType.AnsiString:
MetaParameter.TypeName = "varchar";
sqlDbType = SqlDbType.VarChar;
+ MetaParameter.IsVariableSizeType = true;
break;
case DbType.AnsiStringFixedLength:
MetaParameter.TypeName = "char";
sqlDbType = SqlDbType.Char;
+ MetaParameter.IsVariableSizeType = true;
break;
case DbType.Binary:
MetaParameter.TypeName = "varbinary";
sqlDbType = SqlDbType.VarBinary;
+ MetaParameter.IsVariableSizeType = true;
break;
case DbType.Boolean:
MetaParameter.TypeName = "bit";
case DbType.String:
MetaParameter.TypeName = "nvarchar";
sqlDbType = SqlDbType.NVarChar;
+ MetaParameter.IsVariableSizeType = true;
break;
case DbType.StringFixedLength:
MetaParameter.TypeName = "nchar";
sqlDbType = SqlDbType.NChar;
+ MetaParameter.IsVariableSizeType = true;
break;
case DbType.Time:
MetaParameter.TypeName = "datetime";
case "varchar":
SqlDbType = SqlDbType.VarChar;
break;
+ case "sql_variant":
+ SqlDbType = SqlDbType.Variant;
+ break;
default:
SqlDbType = SqlDbType.Variant;
break;
case SqlDbType.Binary:
MetaParameter.TypeName = "binary";
dbType = DbType.Binary;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.Timestamp:
MetaParameter.TypeName = "timestamp";
case SqlDbType.VarBinary:
MetaParameter.TypeName = "varbinary";
dbType = DbType.Binary;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.Bit:
MetaParameter.TypeName = "bit";
case SqlDbType.Char:
MetaParameter.TypeName = "char";
dbType = DbType.AnsiStringFixedLength;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.DateTime:
MetaParameter.TypeName = "datetime";
case SqlDbType.Image:
MetaParameter.TypeName = "image";
dbType = DbType.Binary;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.Int:
MetaParameter.TypeName = "int";
case SqlDbType.NChar:
MetaParameter.TypeName = "nchar";
dbType = DbType.StringFixedLength;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.NText:
MetaParameter.TypeName = "ntext";
dbType = DbType.String;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.NVarChar:
MetaParameter.TypeName = "nvarchar";
dbType = DbType.String;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.Real:
MetaParameter.TypeName = "real";
case SqlDbType.Text:
MetaParameter.TypeName = "text";
dbType = DbType.AnsiString;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.VarChar:
MetaParameter.TypeName = "varchar";
dbType = DbType.AnsiString;
+ MetaParameter.IsVariableSizeType = true;
break;
case SqlDbType.TinyInt:
MetaParameter.TypeName = "tinyint";
private object SqlTypeToFrameworkType (object value)
{
if (! (value is INullable)) // if the value is not SqlType
- return value;
+ return ConvertToFrameworkType (value);
// Map to .net type, as Mono TDS respects only types from .net
switch (value.GetType ().FullName) {
return value;
}
+ private object ConvertToFrameworkType (object value)
+ {
+ if (value == null || value == DBNull.Value)
+ return value;
+ switch (sqlDbType) {
+ case SqlDbType.BigInt :
+ return Convert.ChangeType (value, typeof (Int64));
+ case SqlDbType.Binary:
+ case SqlDbType.VarBinary:
+ if (value is byte[])
+ return value;
+ break;
+ case SqlDbType.Bit:
+ return Convert.ChangeType (value, typeof (bool));
+ case SqlDbType.Int:
+ return Convert.ChangeType (value, typeof (Int32));
+ case SqlDbType.SmallInt :
+ return Convert.ChangeType (value, typeof (Int16));
+ case SqlDbType.TinyInt :
+ return Convert.ChangeType (value, typeof (byte));
+ case SqlDbType.Float:
+ return Convert.ChangeType (value, typeof (Double));
+ case SqlDbType.Real:
+ return Convert.ChangeType (value, typeof (Single));
+ case SqlDbType.Decimal:
+ return Convert.ChangeType (value, typeof (Decimal));
+ case SqlDbType.Money:
+ case SqlDbType.SmallMoney:
+ {
+ Decimal val = (Decimal)Convert.ChangeType (value, typeof (Decimal));
+ return Decimal.Round(val, 4);
+ }
+ case SqlDbType.DateTime:
+ case SqlDbType.SmallDateTime:
+ return Convert.ChangeType (value, typeof (DateTime));
+ case SqlDbType.VarChar:
+ case SqlDbType.NVarChar:
+ case SqlDbType.Char:
+ case SqlDbType.NChar:
+ case SqlDbType.Text:
+ case SqlDbType.NText:
+ return Convert.ChangeType (value, typeof (string));
+ case SqlDbType.UniqueIdentifier:
+ return Convert.ChangeType (value, typeof (Guid));
+ case SqlDbType.Variant:
+ return metaParameter.Value;
+ }
+ throw new NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
+ }
+
#if NET_2_0
- [MonoTODO]
- public override void CopyTo (DbParameter param)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
+
public override void ResetDbType ()
{
- throw new NotImplementedException ();
+ InferSqlType (metaParameter.Value);
}
+
+ public void ResetSqlDbType ()
+ {
+ InferSqlType (metaParameter.Value);
+ }
#endif // NET_2_0
#endregion // Methods