2 // System.Data.SqlClient.SqlParameter.cs
5 // Rodrigo Moya (rodrigo@ximian.com)
6 // Daniel Morgan (danmorg@sc.rr.com)
7 // Tim Coleman (tim@timcoleman.com)
8 // Diego Caravana (diego@toth.it)
9 // Umadevi S (sumadevi@novell.com)
10 // Amit Biswas (amit@amitbiswas.com)
11 // Veerapuram Varadhan (vvaradhan@novell.com)
13 // (C) Ximian, Inc. 2002
14 // Copyright (C) Tim Coleman, 2002
18 // Copyright (C) 2004, 2008, 2009 Novell, Inc (http://www.novell.com)
20 // Permission is hereby granted, free of charge, to any person obtaining
21 // a copy of this software and associated documentation files (the
22 // "Software"), to deal in the Software without restriction, including
23 // without limitation the rights to use, copy, modify, merge, publish,
24 // distribute, sublicense, and/or sell copies of the Software, and to
25 // permit persons to whom the Software is furnished to do so, subject to
26 // the following conditions:
28 // The above copyright notice and this permission notice shall be
29 // included in all copies or substantial portions of the Software.
31 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
41 using Mono.Data.Tds.Protocol;
43 using System.Collections;
44 using System.ComponentModel;
46 using System.Data.Common;
47 using System.Data.SqlTypes;
48 using System.Globalization;
49 using System.Runtime.InteropServices;
53 namespace System.Data.SqlClient {
54 [TypeConverterAttribute ("System.Data.SqlClient.SqlParameter+SqlParameterConverter, " + Consts.AssemblySystem_Data)]
55 public sealed class SqlParameter : DbParameter, IDbDataParameter, IDataParameter, ICloneable
57 #region Import from old DbParameter
58 static Hashtable dbTypeMapping = new Hashtable ();
59 internal static Hashtable DbTypeMapping {
60 get { return dbTypeMapping;}
61 set { dbTypeMapping = value;}
64 // LAMESPEC: Implementors should populate the dbTypeMapping accordingly
65 internal Type SystemType {
67 return (Type) dbTypeMapping [SqlDbType];
74 TdsMetaParameter metaParameter;
76 SqlParameterCollection container;
78 ParameterDirection direction = ParameterDirection.Input;
83 DataRowVersion sourceVersion;
84 SqlCompareOptions compareInfo;
88 bool sourceColumnNullMapping;
89 string xmlSchemaCollectionDatabase = String.Empty;
90 string xmlSchemaCollectionOwningSchema = String.Empty;
91 string xmlSchemaCollectionName = String.Empty;
93 static Hashtable type_mapping;
100 static SqlParameter ()
102 if (DbTypeMapping == null)
103 DbTypeMapping = new Hashtable ();
105 DbTypeMapping.Add (SqlDbType.BigInt, typeof (long));
106 DbTypeMapping.Add (SqlDbType.Bit, typeof (bool));
107 DbTypeMapping.Add (SqlDbType.Char, typeof (string));
108 DbTypeMapping.Add (SqlDbType.NChar, typeof (string));
109 DbTypeMapping.Add (SqlDbType.Text, typeof (string));
110 DbTypeMapping.Add (SqlDbType.NText, typeof (string));
111 DbTypeMapping.Add (SqlDbType.VarChar, typeof (string));
112 DbTypeMapping.Add (SqlDbType.NVarChar, typeof (string));
113 DbTypeMapping.Add (SqlDbType.SmallDateTime, typeof (DateTime));
114 DbTypeMapping.Add (SqlDbType.DateTime, typeof (DateTime));
115 DbTypeMapping.Add (SqlDbType.DateTime2, typeof (DateTime));
116 DbTypeMapping.Add (SqlDbType.DateTimeOffset, typeof (DateTimeOffset));
117 DbTypeMapping.Add (SqlDbType.Decimal, typeof (decimal));
118 DbTypeMapping.Add (SqlDbType.Float, typeof (double));
119 DbTypeMapping.Add (SqlDbType.Binary, typeof (byte []));
120 DbTypeMapping.Add (SqlDbType.Image, typeof (byte []));
121 DbTypeMapping.Add (SqlDbType.Money, typeof (decimal));
122 DbTypeMapping.Add (SqlDbType.SmallMoney, typeof (decimal));
123 DbTypeMapping.Add (SqlDbType.VarBinary, typeof (byte []));
124 DbTypeMapping.Add (SqlDbType.TinyInt, typeof (byte));
125 DbTypeMapping.Add (SqlDbType.Int, typeof (int));
126 DbTypeMapping.Add (SqlDbType.Real, typeof (float));
127 DbTypeMapping.Add (SqlDbType.SmallInt, typeof (short));
128 DbTypeMapping.Add (SqlDbType.UniqueIdentifier, typeof (Guid));
129 DbTypeMapping.Add (SqlDbType.Variant, typeof (object));
130 DbTypeMapping.Add (SqlDbType.Xml, typeof (string));
132 type_mapping = new Hashtable ();
134 type_mapping.Add (typeof (long), SqlDbType.BigInt);
135 type_mapping.Add (typeof (SqlTypes.SqlInt64), SqlDbType.BigInt);
137 type_mapping.Add (typeof (bool), SqlDbType.Bit);
138 type_mapping.Add (typeof (SqlTypes.SqlBoolean), SqlDbType.Bit);
140 type_mapping.Add (typeof (char), SqlDbType.NVarChar);
141 type_mapping.Add (typeof (char []), SqlDbType.NVarChar);
142 type_mapping.Add (typeof (SqlTypes.SqlChars), SqlDbType.NVarChar);
144 type_mapping.Add (typeof (string), SqlDbType.NVarChar);
145 type_mapping.Add (typeof (SqlTypes.SqlString), SqlDbType.NVarChar);
147 type_mapping.Add (typeof (DateTime), SqlDbType.DateTime);
148 type_mapping.Add (typeof (SqlTypes.SqlDateTime), SqlDbType.DateTime);
150 type_mapping.Add (typeof (decimal), SqlDbType.Decimal);
151 type_mapping.Add (typeof (SqlTypes.SqlDecimal), SqlDbType.Decimal);
153 type_mapping.Add (typeof (double), SqlDbType.Float);
154 type_mapping.Add (typeof (SqlTypes.SqlDouble), SqlDbType.Float);
156 type_mapping.Add (typeof (byte []), SqlDbType.VarBinary);
157 type_mapping.Add (typeof (SqlTypes.SqlBinary), SqlDbType.VarBinary);
159 type_mapping.Add (typeof (SqlTypes.SqlBytes), SqlDbType.VarBinary);
161 type_mapping.Add (typeof (byte), SqlDbType.TinyInt);
162 type_mapping.Add (typeof (SqlTypes.SqlByte), SqlDbType.TinyInt);
164 type_mapping.Add (typeof (int), SqlDbType.Int);
165 type_mapping.Add (typeof (SqlTypes.SqlInt32), SqlDbType.Int);
167 type_mapping.Add (typeof (float), SqlDbType.Real);
168 type_mapping.Add (typeof (SqlTypes.SqlSingle), SqlDbType.Real);
170 type_mapping.Add (typeof (short), SqlDbType.SmallInt);
171 type_mapping.Add (typeof (SqlTypes.SqlInt16), SqlDbType.SmallInt);
173 type_mapping.Add (typeof (Guid), SqlDbType.UniqueIdentifier);
174 type_mapping.Add (typeof (SqlTypes.SqlGuid), SqlDbType.UniqueIdentifier);
176 type_mapping.Add (typeof (SqlTypes.SqlMoney), SqlDbType.Money);
178 type_mapping.Add (typeof (XmlReader), SqlDbType.Xml);
179 type_mapping.Add (typeof (SqlTypes.SqlXml), SqlDbType.Xml);
181 type_mapping.Add (typeof (object), SqlDbType.Variant);
182 type_mapping.Add (typeof (DateTimeOffset), SqlDbType.DateTimeOffset);
185 public SqlParameter ()
186 : this (String.Empty, SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
191 public SqlParameter (string parameterName, object value)
193 if (parameterName == null)
194 parameterName = string.Empty;
195 metaParameter = new TdsMetaParameter (parameterName, GetFrameworkValue);
196 metaParameter.RawValue = value;
197 InferSqlType (value);
198 sourceVersion = DataRowVersion.Current;
201 public SqlParameter (string parameterName, SqlDbType dbType)
202 : this (parameterName, dbType, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, null)
206 public SqlParameter (string parameterName, SqlDbType dbType, int size)
207 : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, null)
211 public SqlParameter (string parameterName, SqlDbType dbType, int size, string sourceColumn)
212 : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, sourceColumn, DataRowVersion.Current, null)
216 [EditorBrowsable (EditorBrowsableState.Advanced)]
217 public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
219 if (parameterName == null)
220 parameterName = string.Empty;
222 metaParameter = new TdsMetaParameter (parameterName, size,
223 isNullable, precision,
226 metaParameter.RawValue = value;
228 Direction = direction;
229 SourceColumn = sourceColumn;
230 SourceVersion = sourceVersion;
233 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)
234 : this (parameterName, dbType, size, direction, false, precision, scale, sourceColumn, sourceVersion, value)
236 XmlSchemaCollectionDatabase = xmlSchemaCollectionDatabase;
237 XmlSchemaCollectionOwningSchema = xmlSchemaCollectionOwningSchema;
238 XmlSchemaCollectionName = xmlSchemaCollectionName;
239 SourceColumnNullMapping = sourceColumnNullMapping;
242 // This constructor is used internally to construct a
243 // SqlParameter. The value array comes from sp_procedure_params_rowset.
244 // This is in SqlCommand.DeriveParameters.
246 // http://social.msdn.microsoft.com/forums/en-US/transactsql/thread/900756fd-3980-48e3-ae59-a15d7fc15b4c/
247 internal SqlParameter (object[] dbValues)
248 : this (dbValues [3].ToString (), (object) null)
250 ParameterName = (string) dbValues [3];
252 switch ((short) dbValues [5]) {
254 Direction = ParameterDirection.Input;
257 Direction = ParameterDirection.InputOutput;
260 Direction = ParameterDirection.Output;
263 Direction = ParameterDirection.ReturnValue;
266 Direction = ParameterDirection.Input;
270 SqlDbType = (SqlDbType) FrameworkDbTypeFromName ((string) dbValues [16]);
272 if (MetaParameter.IsVariableSizeType) {
273 if (dbValues [10] != DBNull.Value)
274 Size = (int) dbValues [10];
277 if (SqlDbType == SqlDbType.Decimal) {
278 if (dbValues [12] != null && dbValues [12] != DBNull.Value)
279 Precision = (byte) ((short) dbValues [12]);
280 if (dbValues [13] != null && dbValues [13] != DBNull.Value)
281 Scale = (byte) ((short) dbValues [13]);
285 #endregion // Constructors
289 // Used to ensure that only one collection can contain this
291 internal SqlParameterCollection Container {
292 get { return container; }
293 set { container = value; }
296 internal void CheckIfInitialized ()
299 throw new Exception ("all parameters to have an explicity set type");
301 if (MetaParameter.IsVariableSizeType) {
302 if (SqlDbType == SqlDbType.Decimal && Precision == 0)
303 throw new Exception ("Parameter of type 'Decimal' have an explicitly set Precision and Scale");
305 throw new Exception ("all variable length parameters to have an explicitly set non-zero Size");
309 public override DbType DbType {
310 get { return dbType; }
318 [RefreshProperties (RefreshProperties.All)]
320 ParameterDirection Direction {
321 get { return direction; }
324 switch( direction ) {
325 case ParameterDirection.Output:
326 MetaParameter.Direction = TdsParameterDirection.Output;
328 case ParameterDirection.InputOutput:
329 MetaParameter.Direction = TdsParameterDirection.InputOutput;
331 case ParameterDirection.ReturnValue:
332 MetaParameter.Direction = TdsParameterDirection.ReturnValue;
338 internal TdsMetaParameter MetaParameter {
339 get { return metaParameter; }
342 public override bool IsNullable {
343 get { return metaParameter.IsNullable; }
344 set { metaParameter.IsNullable = value; }
348 [EditorBrowsable (EditorBrowsableState.Advanced)]
350 get { return offset; }
351 set { offset = value; }
354 public override string ParameterName {
355 get { return metaParameter.ParameterName; }
358 value = string.Empty;
359 metaParameter.ParameterName = value;
364 public byte Precision {
365 get { return metaParameter.Precision; }
366 set { metaParameter.Precision = value; }
371 get { return metaParameter.Scale; }
372 set { metaParameter.Scale = value; }
375 public override int Size {
376 get { return metaParameter.Size; }
377 set { metaParameter.Size = value; }
380 public override string SourceColumn {
382 if (sourceColumn == null)
386 set { sourceColumn = value; }
389 public override DataRowVersion SourceVersion {
390 get { return sourceVersion; }
391 set { sourceVersion = value; }
394 [RefreshProperties (RefreshProperties.All)]
395 [DbProviderSpecificTypeProperty(true)]
396 public SqlDbType SqlDbType {
397 get { return sqlDbType; }
399 SetSqlDbType (value);
405 [TypeConverterAttribute (typeof (StringConverter))]
406 [RefreshProperties (RefreshProperties.All)]
407 public override object Value {
410 return GetSqlValue (metaParameter.RawValue);
411 return metaParameter.RawValue;
415 InferSqlType (value);
418 if (value is INullable) {
419 sqlType = value.GetType ();
420 value = SqlTypeToFrameworkType (value);
422 metaParameter.RawValue = value;
427 public SqlCompareOptions CompareInfo{
428 get{ return compareInfo; }
429 set{ compareInfo = value; }
433 public int LocaleId {
434 get { return localeId; }
435 set { localeId = value; }
439 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
440 public Object SqlValue {
442 return GetSqlValue (metaParameter.RawValue);
449 public override bool SourceColumnNullMapping {
450 get { return sourceColumnNullMapping; }
451 set { sourceColumnNullMapping = value; }
454 public string XmlSchemaCollectionDatabase {
455 get { return xmlSchemaCollectionDatabase; }
456 set { xmlSchemaCollectionDatabase = (value == null ? String.Empty : value); }
459 public string XmlSchemaCollectionName {
460 get { return xmlSchemaCollectionName; }
462 xmlSchemaCollectionName = (value == null ? String.Empty : value);
466 public string XmlSchemaCollectionOwningSchema {
467 get { return xmlSchemaCollectionOwningSchema; }
469 xmlSchemaCollectionOwningSchema = (value == null ? String.Empty : value);
473 [BrowsableAttribute(false)]
474 public string UdtTypeName { get; set; }
476 #endregion // Properties
480 object ICloneable.Clone ()
482 return new SqlParameter (ParameterName, SqlDbType, Size, Direction, IsNullable, Precision, Scale, SourceColumn, SourceVersion, Value);
485 // If the value is set without the DbType/SqlDbType being set, then we
486 // infer type information.
487 void InferSqlType (object value)
489 if (value == null || value == DBNull.Value) {
490 SetSqlDbType (SqlDbType.NVarChar);
494 Type type = value.GetType ();
496 type = Enum.GetUnderlyingType (type);
497 object t = type_mapping [type];
499 throw new ArgumentException (String.Format ("The parameter data type of {0} is invalid.", type.FullName));
500 SetSqlDbType ((SqlDbType) t);
504 // Returns System.Type corresponding to the underlying SqlDbType
505 internal override Type SystemType {
507 return (Type) DbTypeMapping [sqlDbType];
511 internal override object FrameworkDbType {
519 t = (DbType) DbTypeFromName ((string)value);
520 SetDbType ((DbType)t);
521 } catch (ArgumentException) {
522 t = (SqlDbType)FrameworkDbTypeFromName ((string)value);
523 SetSqlDbType ((SqlDbType) t);
529 DbType DbTypeFromName (string name)
531 switch (name.ToLower ()) {
533 return DbType.AnsiString;
534 case "ansistringfixedlength":
535 return DbType.AnsiStringFixedLength;
537 return DbType.Binary;
539 return DbType.Boolean;
543 return DbType.Currency;
547 return DbType.DateTime;
549 return DbType.Decimal;
551 return DbType.Double;
561 return DbType.Object;
563 return DbType.Single;
565 return DbType.String;
566 case "stringfixedlength":
567 return DbType.StringFixedLength;
573 string exception = String.Format ("No mapping exists from {0} to a known DbType.", name);
574 throw new ArgumentException (exception);
578 // When the DbType is set, we also set the SqlDbType, as well as the SQL Server
579 // string representation of the type name. If the DbType is not convertible
580 // to an SqlDbType, throw an exception.
581 private void SetDbType (DbType type)
584 case DbType.AnsiString:
585 MetaParameter.TypeName = "varchar";
586 sqlDbType = SqlDbType.VarChar;
587 MetaParameter.IsVariableSizeType = true;
589 case DbType.AnsiStringFixedLength:
590 MetaParameter.TypeName = "char";
591 sqlDbType = SqlDbType.Char;
592 MetaParameter.IsVariableSizeType = true;
595 MetaParameter.TypeName = "varbinary";
596 sqlDbType = SqlDbType.VarBinary;
597 MetaParameter.IsVariableSizeType = true;
600 MetaParameter.TypeName = "bit";
601 sqlDbType = SqlDbType.Bit;
604 MetaParameter.TypeName = "tinyint";
605 sqlDbType = SqlDbType.TinyInt;
607 case DbType.Currency:
608 sqlDbType = SqlDbType.Money;
609 MetaParameter.TypeName = "money";
612 case DbType.DateTime:
613 MetaParameter.TypeName = "datetime";
614 sqlDbType = SqlDbType.DateTime;
616 case DbType.DateTime2:
617 MetaParameter.TypeName = "datetime2";
618 sqlDbType = SqlDbType.DateTime2;
621 MetaParameter.TypeName = "decimal";
622 sqlDbType = SqlDbType.Decimal;
625 MetaParameter.TypeName = "float";
626 sqlDbType = SqlDbType.Float;
629 MetaParameter.TypeName = "uniqueidentifier";
630 sqlDbType = SqlDbType.UniqueIdentifier;
633 MetaParameter.TypeName = "smallint";
634 sqlDbType = SqlDbType.SmallInt;
637 MetaParameter.TypeName = "int";
638 sqlDbType = SqlDbType.Int;
641 MetaParameter.TypeName = "bigint";
642 sqlDbType = SqlDbType.BigInt;
645 MetaParameter.TypeName = "sql_variant";
646 sqlDbType = SqlDbType.Variant;
649 MetaParameter.TypeName = "real";
650 sqlDbType = SqlDbType.Real;
653 MetaParameter.TypeName = "nvarchar";
654 sqlDbType = SqlDbType.NVarChar;
655 MetaParameter.IsVariableSizeType = true;
657 case DbType.StringFixedLength:
658 MetaParameter.TypeName = "nchar";
659 sqlDbType = SqlDbType.NChar;
660 MetaParameter.IsVariableSizeType = true;
663 MetaParameter.TypeName = "datetime";
664 sqlDbType = SqlDbType.DateTime;
666 // Handle Xml type as string
668 MetaParameter.TypeName = "xml";
669 sqlDbType = SqlDbType.Xml;
670 MetaParameter.IsVariableSizeType = true;
673 string exception = String.Format ("No mapping exists from DbType {0} to a known SqlDbType.", type);
674 throw new ArgumentException (exception);
679 // Used by internal constructor which has a SQL Server typename
680 private SqlDbType FrameworkDbTypeFromName (string dbTypeName)
682 switch (dbTypeName.ToLower ()) {
684 return SqlDbType.BigInt;
686 return SqlDbType.Binary;
688 return SqlDbType.Bit;
690 return SqlDbType.Char;
692 return SqlDbType.DateTime;
694 return SqlDbType.Decimal;
696 return SqlDbType.Float;
698 return SqlDbType.Image;
700 return SqlDbType.Int;
702 return SqlDbType.Money;
704 return SqlDbType.NChar;
706 return SqlDbType.NText;
708 return SqlDbType.NVarChar;
710 return SqlDbType.Real;
711 case "smalldatetime":
712 return SqlDbType.SmallDateTime;
714 return SqlDbType.SmallInt;
716 return SqlDbType.SmallMoney;
718 return SqlDbType.Text;
720 return SqlDbType.Timestamp;
722 return SqlDbType.TinyInt;
723 case "uniqueidentifier":
724 return SqlDbType.UniqueIdentifier;
726 return SqlDbType.VarBinary;
728 return SqlDbType.VarChar;
730 return SqlDbType.Variant;
732 return SqlDbType.Xml;
734 return SqlDbType.Variant;
738 // When the SqlDbType is set, we also set the DbType, as well as the SQL Server
739 // string representation of the type name. If the SqlDbType is not convertible
740 // to a DbType, throw an exception.
741 internal void SetSqlDbType (SqlDbType type)
744 case SqlDbType.BigInt:
745 MetaParameter.TypeName = "bigint";
746 dbType = DbType.Int64;
748 case SqlDbType.Binary:
749 MetaParameter.TypeName = "binary";
750 dbType = DbType.Binary;
751 MetaParameter.IsVariableSizeType = true;
753 case SqlDbType.Timestamp:
754 MetaParameter.TypeName = "timestamp";
755 dbType = DbType.Binary;
757 case SqlDbType.VarBinary:
758 MetaParameter.TypeName = "varbinary";
759 dbType = DbType.Binary;
760 MetaParameter.IsVariableSizeType = true;
763 MetaParameter.TypeName = "bit";
764 dbType = DbType.Boolean;
767 MetaParameter.TypeName = "char";
768 dbType = DbType.AnsiStringFixedLength;
769 MetaParameter.IsVariableSizeType = true;
771 case SqlDbType.DateTime:
772 MetaParameter.TypeName = "datetime";
773 dbType = DbType.DateTime;
775 case SqlDbType.SmallDateTime:
776 MetaParameter.TypeName = "smalldatetime";
777 dbType = DbType.DateTime;
779 case SqlDbType.DateTime2:
780 MetaParameter.TypeName = "datetime2";
781 dbType = DbType.DateTime2;
783 case SqlDbType.DateTimeOffset:
784 MetaParameter.TypeName = "datetimeoffset";
785 dbType = DbType.DateTimeOffset;
787 case SqlDbType.Decimal:
788 MetaParameter.TypeName = "decimal";
789 dbType = DbType.Decimal;
791 case SqlDbType.Float:
792 MetaParameter.TypeName = "float";
793 dbType = DbType.Double;
795 case SqlDbType.Image:
796 MetaParameter.TypeName = "image";
797 dbType = DbType.Binary;
798 MetaParameter.IsVariableSizeType = true;
801 MetaParameter.TypeName = "int";
802 dbType = DbType.Int32;
804 case SqlDbType.Money:
805 MetaParameter.TypeName = "money";
806 dbType = DbType.Currency;
808 case SqlDbType.SmallMoney:
809 MetaParameter.TypeName = "smallmoney";
810 dbType = DbType.Currency;
812 case SqlDbType.NChar:
813 MetaParameter.TypeName = "nchar";
814 dbType = DbType.StringFixedLength;
815 MetaParameter.IsVariableSizeType = true;
817 case SqlDbType.NText:
818 MetaParameter.TypeName = "ntext";
819 dbType = DbType.String;
820 MetaParameter.IsVariableSizeType = true;
822 case SqlDbType.NVarChar:
823 MetaParameter.TypeName = "nvarchar";
824 dbType = DbType.String;
825 MetaParameter.IsVariableSizeType = true;
828 MetaParameter.TypeName = "real";
829 dbType = DbType.Single;
831 case SqlDbType.SmallInt:
832 MetaParameter.TypeName = "smallint";
833 dbType = DbType.Int16;
836 MetaParameter.TypeName = "text";
837 dbType = DbType.AnsiString;
838 MetaParameter.IsVariableSizeType = true;
840 case SqlDbType.VarChar:
841 MetaParameter.TypeName = "varchar";
842 dbType = DbType.AnsiString;
843 MetaParameter.IsVariableSizeType = true;
845 case SqlDbType.TinyInt:
846 MetaParameter.TypeName = "tinyint";
847 dbType = DbType.Byte;
849 case SqlDbType.UniqueIdentifier:
850 MetaParameter.TypeName = "uniqueidentifier";
851 dbType = DbType.Guid;
853 case SqlDbType.Variant:
854 MetaParameter.TypeName = "sql_variant";
855 dbType = DbType.Object;
858 MetaParameter.TypeName = "xml";
860 MetaParameter.IsVariableSizeType = true;
863 string exception = String.Format ("No mapping exists from SqlDbType {0} to a known DbType.", type);
864 throw new ArgumentOutOfRangeException ("SqlDbType", exception);
869 public override string ToString()
871 return ParameterName;
874 object GetFrameworkValue (object rawValue, ref bool updated)
878 updated = typeChanged || updated;
880 tdsValue = SqlTypeToFrameworkType (rawValue);
887 // TODO: Code copied from SqlDataReader, need a better approach
888 object GetSqlValue (object value)
893 case SqlDbType.BigInt:
894 if (value == DBNull.Value)
895 return SqlInt64.Null;
896 return (SqlInt64) ((long) value);
897 case SqlDbType.Binary:
898 case SqlDbType.Image:
899 case SqlDbType.VarBinary:
900 case SqlDbType.Timestamp:
901 if (value == DBNull.Value)
902 return SqlBinary.Null;
903 return (SqlBinary) (byte[]) value;
905 if (value == DBNull.Value)
906 return SqlBoolean.Null;
907 return (SqlBoolean) ((bool) value);
909 case SqlDbType.NChar:
910 case SqlDbType.NText:
911 case SqlDbType.NVarChar:
913 case SqlDbType.VarChar:
914 if (value == DBNull.Value)
915 return SqlString.Null;
918 Type type = value.GetType ();
919 if (type == typeof (char))
920 str = value.ToString ();
921 else if (type == typeof (char[]))
922 str = new String ((char[])value);
924 str = ((string)value);
925 return (SqlString) str;
926 case SqlDbType.DateTime:
927 case SqlDbType.SmallDateTime:
928 if (value == DBNull.Value)
929 return SqlDateTime.Null;
930 return (SqlDateTime) ((DateTime) value);
931 case SqlDbType.Decimal:
932 if (value == DBNull.Value)
933 return SqlDecimal.Null;
934 if (value is TdsBigDecimal)
935 return SqlDecimalExtensions.FromTdsBigDecimal ((TdsBigDecimal) value);
936 return (SqlDecimal) ((decimal) value);
937 case SqlDbType.Float:
938 if (value == DBNull.Value)
939 return SqlDouble.Null;
940 return (SqlDouble) ((double) value);
942 if (value == DBNull.Value)
943 return SqlInt32.Null;
944 return (SqlInt32) ((int) value);
945 case SqlDbType.Money:
946 case SqlDbType.SmallMoney:
947 if (value == DBNull.Value)
948 return SqlMoney.Null;
949 return (SqlMoney) ((decimal) value);
951 if (value == DBNull.Value)
952 return SqlSingle.Null;
953 return (SqlSingle) ((float) value);
954 case SqlDbType.UniqueIdentifier:
955 if (value == DBNull.Value)
957 return (SqlGuid) ((Guid) value);
958 case SqlDbType.SmallInt:
959 if (value == DBNull.Value)
960 return SqlInt16.Null;
961 return (SqlInt16) ((short) value);
962 case SqlDbType.TinyInt:
963 if (value == DBNull.Value)
965 return (SqlByte) ((byte) value);
967 if (value == DBNull.Value)
969 return (SqlXml) value;
971 throw new NotImplementedException ("Type '" + sqlDbType + "' not implemented.");
975 object SqlTypeToFrameworkType (object value)
977 INullable nullable = value as INullable;
978 if (nullable == null)
979 return ConvertToFrameworkType (value);
984 Type type = value.GetType ();
985 // Map to .net type, as Mono TDS respects only types from .net
987 if (typeof (SqlString) == type) {
988 return ((SqlString) value).Value;
991 if (typeof (SqlInt16) == type) {
992 return ((SqlInt16) value).Value;
995 if (typeof (SqlInt32) == type) {
996 return ((SqlInt32) value).Value;
999 if (typeof (SqlDateTime) == type) {
1000 return ((SqlDateTime) value).Value;
1003 if (typeof (SqlInt64) == type) {
1004 return ((SqlInt64) value).Value;
1007 if (typeof (SqlBinary) == type) {
1008 return ((SqlBinary) value).Value;
1011 if (typeof (SqlBytes) == type) {
1012 return ((SqlBytes) value).Value;
1015 if (typeof (SqlChars) == type) {
1016 return ((SqlChars) value).Value;
1019 if (typeof (SqlBoolean) == type) {
1020 return ((SqlBoolean) value).Value;
1023 if (typeof (SqlByte) == type) {
1024 return ((SqlByte) value).Value;
1027 if (typeof (SqlDecimal) == type) {
1028 return ((SqlDecimal) value).Value;
1031 if (typeof (SqlDouble) == type) {
1032 return ((SqlDouble) value).Value;
1035 if (typeof (SqlGuid) == type) {
1036 return ((SqlGuid) value).Value;
1039 if (typeof (SqlMoney) == type) {
1040 return ((SqlMoney) value).Value;
1043 if (typeof (SqlSingle) == type) {
1044 return ((SqlSingle) value).Value;
1050 internal object ConvertToFrameworkType (object value)
1052 if (value == null || value == DBNull.Value)
1054 if (sqlDbType == SqlDbType.Variant)
1055 return metaParameter.Value;
1057 Type frameworkType = SystemType;
1058 if (frameworkType == null)
1059 throw new NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
1061 Type valueType = value.GetType ();
1062 if (valueType == frameworkType)
1065 object sqlvalue = null;
1068 sqlvalue = ConvertToFrameworkType (value, frameworkType);
1069 } catch (FormatException ex) {
1070 throw new FormatException (string.Format (CultureInfo.InvariantCulture,
1071 "Parameter value could not be converted from {0} to {1}.",
1072 valueType.Name, frameworkType.Name), ex);
1078 object ConvertToFrameworkType (object value, Type frameworkType)
1080 if (frameworkType == typeof (string)) {
1081 if (value is DateTime)
1082 return ((DateTime) value).ToString ("yyyy-MM-dd'T'HH':'mm':'ss.fffffff");
1083 if (value is DateTimeOffset)
1084 return ((DateTimeOffset) value).ToString ("yyyy-MM-dd'T'HH':'mm':'ss.fffffffzzz");
1087 object sqlvalue = Convert.ChangeType (value, frameworkType);
1088 switch (sqlDbType) {
1089 case SqlDbType.Money:
1090 case SqlDbType.SmallMoney:
1091 sqlvalue = Decimal.Round ((decimal) sqlvalue, 4);
1097 public override void ResetDbType ()
1099 InferSqlType (Value);
1102 public void ResetSqlDbType ()
1104 InferSqlType (Value);
1107 #endregion // Methods