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
59 TdsMetaParameter metaParameter;
61 SqlParameterCollection container;
63 ParameterDirection direction = ParameterDirection.Input;
68 DataRowVersion sourceVersion;
69 SqlCompareOptions compareInfo;
73 bool sourceColumnNullMapping;
74 string xmlSchemaCollectionDatabase = String.Empty;
75 string xmlSchemaCollectionOwningSchema = String.Empty;
76 string xmlSchemaCollectionName = String.Empty;
78 static Hashtable type_mapping;
85 static SqlParameter ()
87 if (DbTypeMapping == null)
88 DbTypeMapping = new Hashtable ();
90 DbTypeMapping.Add (SqlDbType.BigInt, typeof (long));
91 DbTypeMapping.Add (SqlDbType.Bit, typeof (bool));
92 DbTypeMapping.Add (SqlDbType.Char, typeof (string));
93 DbTypeMapping.Add (SqlDbType.NChar, typeof (string));
94 DbTypeMapping.Add (SqlDbType.Text, typeof (string));
95 DbTypeMapping.Add (SqlDbType.NText, typeof (string));
96 DbTypeMapping.Add (SqlDbType.VarChar, typeof (string));
97 DbTypeMapping.Add (SqlDbType.NVarChar, typeof (string));
98 DbTypeMapping.Add (SqlDbType.SmallDateTime, typeof (DateTime));
99 DbTypeMapping.Add (SqlDbType.DateTime, typeof (DateTime));
100 DbTypeMapping.Add (SqlDbType.Decimal, typeof (decimal));
101 DbTypeMapping.Add (SqlDbType.Float, typeof (double));
102 DbTypeMapping.Add (SqlDbType.Binary, typeof (byte []));
103 DbTypeMapping.Add (SqlDbType.Image, typeof (byte []));
104 DbTypeMapping.Add (SqlDbType.Money, typeof (decimal));
105 DbTypeMapping.Add (SqlDbType.SmallMoney, typeof (decimal));
106 DbTypeMapping.Add (SqlDbType.VarBinary, typeof (byte []));
107 DbTypeMapping.Add (SqlDbType.TinyInt, typeof (byte));
108 DbTypeMapping.Add (SqlDbType.Int, typeof (int));
109 DbTypeMapping.Add (SqlDbType.Real, typeof (float));
110 DbTypeMapping.Add (SqlDbType.SmallInt, typeof (short));
111 DbTypeMapping.Add (SqlDbType.UniqueIdentifier, typeof (Guid));
112 DbTypeMapping.Add (SqlDbType.Variant, typeof (object));
113 DbTypeMapping.Add (SqlDbType.Xml, typeof (string));
115 type_mapping = new Hashtable ();
117 type_mapping.Add (typeof (long), SqlDbType.BigInt);
118 type_mapping.Add (typeof (SqlTypes.SqlInt64), SqlDbType.BigInt);
120 type_mapping.Add (typeof (bool), SqlDbType.Bit);
121 type_mapping.Add (typeof (SqlTypes.SqlBoolean), SqlDbType.Bit);
123 type_mapping.Add (typeof (char), SqlDbType.NVarChar);
124 type_mapping.Add (typeof (char []), SqlDbType.NVarChar);
125 type_mapping.Add (typeof (SqlTypes.SqlChars), SqlDbType.NVarChar);
127 type_mapping.Add (typeof (string), SqlDbType.NVarChar);
128 type_mapping.Add (typeof (SqlTypes.SqlString), SqlDbType.NVarChar);
130 type_mapping.Add (typeof (DateTime), SqlDbType.DateTime);
131 type_mapping.Add (typeof (SqlTypes.SqlDateTime), SqlDbType.DateTime);
133 type_mapping.Add (typeof (decimal), SqlDbType.Decimal);
134 type_mapping.Add (typeof (SqlTypes.SqlDecimal), SqlDbType.Decimal);
136 type_mapping.Add (typeof (double), SqlDbType.Float);
137 type_mapping.Add (typeof (SqlTypes.SqlDouble), SqlDbType.Float);
139 type_mapping.Add (typeof (byte []), SqlDbType.VarBinary);
140 type_mapping.Add (typeof (SqlTypes.SqlBinary), SqlDbType.VarBinary);
142 type_mapping.Add (typeof (SqlTypes.SqlBytes), SqlDbType.VarBinary);
144 type_mapping.Add (typeof (byte), SqlDbType.TinyInt);
145 type_mapping.Add (typeof (SqlTypes.SqlByte), SqlDbType.TinyInt);
147 type_mapping.Add (typeof (int), SqlDbType.Int);
148 type_mapping.Add (typeof (SqlTypes.SqlInt32), SqlDbType.Int);
150 type_mapping.Add (typeof (float), SqlDbType.Real);
151 type_mapping.Add (typeof (SqlTypes.SqlSingle), SqlDbType.Real);
153 type_mapping.Add (typeof (short), SqlDbType.SmallInt);
154 type_mapping.Add (typeof (SqlTypes.SqlInt16), SqlDbType.SmallInt);
156 type_mapping.Add (typeof (Guid), SqlDbType.UniqueIdentifier);
157 type_mapping.Add (typeof (SqlTypes.SqlGuid), SqlDbType.UniqueIdentifier);
159 type_mapping.Add (typeof (SqlTypes.SqlMoney), SqlDbType.Money);
161 type_mapping.Add (typeof (XmlReader), SqlDbType.Xml);
162 type_mapping.Add (typeof (SqlTypes.SqlXml), SqlDbType.Xml);
164 type_mapping.Add (typeof (object), SqlDbType.Variant);
167 public SqlParameter ()
168 : this (String.Empty, SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
173 public SqlParameter (string parameterName, object value)
175 if (parameterName == null)
176 parameterName = string.Empty;
177 metaParameter = new TdsMetaParameter (parameterName, GetFrameworkValue);
178 metaParameter.RawValue = value;
179 InferSqlType (value);
180 sourceVersion = DataRowVersion.Current;
183 public SqlParameter (string parameterName, SqlDbType dbType)
184 : this (parameterName, dbType, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, null)
188 public SqlParameter (string parameterName, SqlDbType dbType, int size)
189 : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, null)
193 public SqlParameter (string parameterName, SqlDbType dbType, int size, string sourceColumn)
194 : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, sourceColumn, DataRowVersion.Current, null)
198 [EditorBrowsable (EditorBrowsableState.Advanced)]
199 public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
201 if (parameterName == null)
202 parameterName = string.Empty;
204 metaParameter = new TdsMetaParameter (parameterName, size,
205 isNullable, precision,
208 metaParameter.RawValue = value;
209 if (dbType != SqlDbType.Variant)
211 Direction = direction;
212 SourceColumn = sourceColumn;
213 SourceVersion = sourceVersion;
216 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)
217 : this (parameterName, dbType, size, direction, false, precision, scale, sourceColumn, sourceVersion, value)
219 XmlSchemaCollectionDatabase = xmlSchemaCollectionDatabase;
220 XmlSchemaCollectionOwningSchema = xmlSchemaCollectionOwningSchema;
221 XmlSchemaCollectionName = xmlSchemaCollectionName;
222 SourceColumnNullMapping = sourceColumnNullMapping;
225 // This constructor is used internally to construct a
226 // SqlParameter. The value array comes from sp_procedure_params_rowset.
227 // This is in SqlCommand.DeriveParameters.
229 // http://social.msdn.microsoft.com/forums/en-US/transactsql/thread/900756fd-3980-48e3-ae59-a15d7fc15b4c/
230 internal SqlParameter (object[] dbValues)
231 : this (dbValues [3].ToString (), (object) null)
233 ParameterName = (string) dbValues [3];
235 switch ((short) dbValues [5]) {
237 Direction = ParameterDirection.Input;
240 Direction = ParameterDirection.InputOutput;
243 Direction = ParameterDirection.Output;
246 Direction = ParameterDirection.ReturnValue;
249 Direction = ParameterDirection.Input;
253 SqlDbType = (SqlDbType) FrameworkDbTypeFromName ((string) dbValues [16]);
255 if (MetaParameter.IsVariableSizeType) {
256 if (dbValues [10] != DBNull.Value)
257 Size = (int) dbValues [10];
260 if (SqlDbType == SqlDbType.Decimal) {
261 if (dbValues [12] != null && dbValues [12] != DBNull.Value)
262 Precision = (byte) ((short) dbValues [12]);
263 if (dbValues [13] != null && dbValues [13] != DBNull.Value)
264 Scale = (byte) ((short) dbValues [13]);
268 #endregion // Constructors
272 // Used to ensure that only one collection can contain this
274 internal SqlParameterCollection Container {
275 get { return container; }
276 set { container = value; }
279 internal void CheckIfInitialized ()
282 throw new Exception ("all parameters to have an explicity set type");
284 if (MetaParameter.IsVariableSizeType) {
285 if (SqlDbType == SqlDbType.Decimal && Precision == 0)
286 throw new Exception ("Parameter of type 'Decimal' have an explicitly set Precision and Scale");
288 throw new Exception ("all variable length parameters to have an explicitly set non-zero Size");
292 public override DbType DbType {
293 get { return dbType; }
301 [RefreshProperties (RefreshProperties.All)]
303 ParameterDirection Direction {
304 get { return direction; }
307 switch( direction ) {
308 case ParameterDirection.Output:
309 MetaParameter.Direction = TdsParameterDirection.Output;
311 case ParameterDirection.InputOutput:
312 MetaParameter.Direction = TdsParameterDirection.InputOutput;
314 case ParameterDirection.ReturnValue:
315 MetaParameter.Direction = TdsParameterDirection.ReturnValue;
321 internal TdsMetaParameter MetaParameter {
322 get { return metaParameter; }
325 public override bool IsNullable {
326 get { return metaParameter.IsNullable; }
327 set { metaParameter.IsNullable = value; }
331 [EditorBrowsable (EditorBrowsableState.Advanced)]
333 get { return offset; }
334 set { offset = value; }
337 public override string ParameterName {
338 get { return metaParameter.ParameterName; }
341 value = string.Empty;
342 metaParameter.ParameterName = value;
347 public byte Precision {
348 get { return metaParameter.Precision; }
349 set { metaParameter.Precision = value; }
354 get { return metaParameter.Scale; }
355 set { metaParameter.Scale = value; }
358 public override int Size {
359 get { return metaParameter.Size; }
360 set { metaParameter.Size = value; }
363 public override string SourceColumn {
365 if (sourceColumn == null)
369 set { sourceColumn = value; }
372 public override DataRowVersion SourceVersion {
373 get { return sourceVersion; }
374 set { sourceVersion = value; }
377 [RefreshProperties (RefreshProperties.All)]
378 [DbProviderSpecificTypeProperty(true)]
379 public SqlDbType SqlDbType {
380 get { return sqlDbType; }
382 SetSqlDbType (value);
388 [TypeConverterAttribute (typeof (StringConverter))]
389 [RefreshProperties (RefreshProperties.All)]
390 public override object Value {
393 return GetSqlValue (metaParameter.RawValue);
394 return metaParameter.RawValue;
398 InferSqlType (value);
401 if (value is INullable) {
402 sqlType = value.GetType ();
403 value = SqlTypeToFrameworkType (value);
405 metaParameter.RawValue = value;
410 public SqlCompareOptions CompareInfo{
411 get{ return compareInfo; }
412 set{ compareInfo = value; }
416 public int LocaleId {
417 get { return localeId; }
418 set { localeId = value; }
422 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
423 public Object SqlValue {
425 return GetSqlValue (metaParameter.RawValue);
432 public override bool SourceColumnNullMapping {
433 get { return sourceColumnNullMapping; }
434 set { sourceColumnNullMapping = value; }
437 public string XmlSchemaCollectionDatabase {
438 get { return xmlSchemaCollectionDatabase; }
439 set { xmlSchemaCollectionDatabase = (value == null ? String.Empty : value); }
442 public string XmlSchemaCollectionName {
443 get { return xmlSchemaCollectionName; }
445 xmlSchemaCollectionName = (value == null ? String.Empty : value);
449 public string XmlSchemaCollectionOwningSchema {
450 get { return xmlSchemaCollectionOwningSchema; }
452 xmlSchemaCollectionOwningSchema = (value == null ? String.Empty : value);
456 [BrowsableAttribute(false)]
457 public string UdtTypeName { get; set; }
459 #endregion // Properties
463 object ICloneable.Clone ()
465 return new SqlParameter (ParameterName, SqlDbType, Size, Direction, IsNullable, Precision, Scale, SourceColumn, SourceVersion, Value);
468 // If the value is set without the DbType/SqlDbType being set, then we
469 // infer type information.
470 void InferSqlType (object value)
472 if (value == null || value == DBNull.Value) {
473 SetSqlDbType (SqlDbType.NVarChar);
477 Type type = value.GetType ();
479 type = Enum.GetUnderlyingType (type);
480 object t = type_mapping [type];
482 throw new ArgumentException (String.Format ("The parameter data type of {0} is invalid.", type.FullName));
483 SetSqlDbType ((SqlDbType) t);
486 // Returns System.Type corresponding to the underlying SqlDbType
487 internal override Type SystemType {
489 return (Type) DbTypeMapping [sqlDbType];
493 internal override object FrameworkDbType {
501 t = (DbType) DbTypeFromName ((string)value);
502 SetDbType ((DbType)t);
503 } catch (ArgumentException) {
504 t = (SqlDbType)FrameworkDbTypeFromName ((string)value);
505 SetSqlDbType ((SqlDbType) t);
510 DbType DbTypeFromName (string name)
512 switch (name.ToLower ()) {
514 return DbType.AnsiString;
515 case "ansistringfixedlength":
516 return DbType.AnsiStringFixedLength;
518 return DbType.Binary;
520 return DbType.Boolean;
524 return DbType.Currency;
528 return DbType.DateTime;
530 return DbType.Decimal;
532 return DbType.Double;
542 return DbType.Object;
544 return DbType.Single;
546 return DbType.String;
547 case "stringfixedlength":
548 return DbType.StringFixedLength;
554 string exception = String.Format ("No mapping exists from {0} to a known DbType.", name);
555 throw new ArgumentException (exception);
559 // When the DbType is set, we also set the SqlDbType, as well as the SQL Server
560 // string representation of the type name. If the DbType is not convertible
561 // to an SqlDbType, throw an exception.
562 private void SetDbType (DbType type)
565 case DbType.AnsiString:
566 MetaParameter.TypeName = "varchar";
567 sqlDbType = SqlDbType.VarChar;
568 MetaParameter.IsVariableSizeType = true;
570 case DbType.AnsiStringFixedLength:
571 MetaParameter.TypeName = "char";
572 sqlDbType = SqlDbType.Char;
573 MetaParameter.IsVariableSizeType = true;
576 MetaParameter.TypeName = "varbinary";
577 sqlDbType = SqlDbType.VarBinary;
578 MetaParameter.IsVariableSizeType = true;
581 MetaParameter.TypeName = "bit";
582 sqlDbType = SqlDbType.Bit;
585 MetaParameter.TypeName = "tinyint";
586 sqlDbType = SqlDbType.TinyInt;
588 case DbType.Currency:
589 sqlDbType = SqlDbType.Money;
590 MetaParameter.TypeName = "money";
593 case DbType.DateTime:
594 MetaParameter.TypeName = "datetime";
595 sqlDbType = SqlDbType.DateTime;
597 case DbType.DateTime2:
598 MetaParameter.TypeName = "datetime2";
599 sqlDbType = SqlDbType.DateTime2;
602 MetaParameter.TypeName = "decimal";
603 sqlDbType = SqlDbType.Decimal;
606 MetaParameter.TypeName = "float";
607 sqlDbType = SqlDbType.Float;
610 MetaParameter.TypeName = "uniqueidentifier";
611 sqlDbType = SqlDbType.UniqueIdentifier;
614 MetaParameter.TypeName = "smallint";
615 sqlDbType = SqlDbType.SmallInt;
618 MetaParameter.TypeName = "int";
619 sqlDbType = SqlDbType.Int;
622 MetaParameter.TypeName = "bigint";
623 sqlDbType = SqlDbType.BigInt;
626 MetaParameter.TypeName = "sql_variant";
627 sqlDbType = SqlDbType.Variant;
630 MetaParameter.TypeName = "real";
631 sqlDbType = SqlDbType.Real;
634 MetaParameter.TypeName = "nvarchar";
635 sqlDbType = SqlDbType.NVarChar;
636 MetaParameter.IsVariableSizeType = true;
638 case DbType.StringFixedLength:
639 MetaParameter.TypeName = "nchar";
640 sqlDbType = SqlDbType.NChar;
641 MetaParameter.IsVariableSizeType = true;
644 MetaParameter.TypeName = "datetime";
645 sqlDbType = SqlDbType.DateTime;
647 // Handle Xml type as string
649 MetaParameter.TypeName = "xml";
650 sqlDbType = SqlDbType.Xml;
651 MetaParameter.IsVariableSizeType = true;
654 string exception = String.Format ("No mapping exists from DbType {0} to a known SqlDbType.", type);
655 throw new ArgumentException (exception);
660 // Used by internal constructor which has a SQL Server typename
661 private SqlDbType FrameworkDbTypeFromName (string dbTypeName)
663 switch (dbTypeName.ToLower ()) {
665 return SqlDbType.BigInt;
667 return SqlDbType.Binary;
669 return SqlDbType.Bit;
671 return SqlDbType.Char;
673 return SqlDbType.DateTime;
675 return SqlDbType.Decimal;
677 return SqlDbType.Float;
679 return SqlDbType.Image;
681 return SqlDbType.Int;
683 return SqlDbType.Money;
685 return SqlDbType.NChar;
687 return SqlDbType.NText;
689 return SqlDbType.NVarChar;
691 return SqlDbType.Real;
692 case "smalldatetime":
693 return SqlDbType.SmallDateTime;
695 return SqlDbType.SmallInt;
697 return SqlDbType.SmallMoney;
699 return SqlDbType.Text;
701 return SqlDbType.Timestamp;
703 return SqlDbType.TinyInt;
704 case "uniqueidentifier":
705 return SqlDbType.UniqueIdentifier;
707 return SqlDbType.VarBinary;
709 return SqlDbType.VarChar;
711 return SqlDbType.Variant;
713 return SqlDbType.Xml;
715 return SqlDbType.Variant;
719 // When the SqlDbType is set, we also set the DbType, as well as the SQL Server
720 // string representation of the type name. If the SqlDbType is not convertible
721 // to a DbType, throw an exception.
722 internal void SetSqlDbType (SqlDbType type)
725 case SqlDbType.BigInt:
726 MetaParameter.TypeName = "bigint";
727 dbType = DbType.Int64;
729 case SqlDbType.Binary:
730 MetaParameter.TypeName = "binary";
731 dbType = DbType.Binary;
732 MetaParameter.IsVariableSizeType = true;
734 case SqlDbType.Timestamp:
735 MetaParameter.TypeName = "timestamp";
736 dbType = DbType.Binary;
738 case SqlDbType.VarBinary:
739 MetaParameter.TypeName = "varbinary";
740 dbType = DbType.Binary;
741 MetaParameter.IsVariableSizeType = true;
744 MetaParameter.TypeName = "bit";
745 dbType = DbType.Boolean;
748 MetaParameter.TypeName = "char";
749 dbType = DbType.AnsiStringFixedLength;
750 MetaParameter.IsVariableSizeType = true;
752 case SqlDbType.DateTime:
753 MetaParameter.TypeName = "datetime";
754 dbType = DbType.DateTime;
756 case SqlDbType.SmallDateTime:
757 MetaParameter.TypeName = "smalldatetime";
758 dbType = DbType.DateTime;
760 case SqlDbType.Decimal:
761 MetaParameter.TypeName = "decimal";
762 dbType = DbType.Decimal;
764 case SqlDbType.Float:
765 MetaParameter.TypeName = "float";
766 dbType = DbType.Double;
768 case SqlDbType.Image:
769 MetaParameter.TypeName = "image";
770 dbType = DbType.Binary;
771 MetaParameter.IsVariableSizeType = true;
774 MetaParameter.TypeName = "int";
775 dbType = DbType.Int32;
777 case SqlDbType.Money:
778 MetaParameter.TypeName = "money";
779 dbType = DbType.Currency;
781 case SqlDbType.SmallMoney:
782 MetaParameter.TypeName = "smallmoney";
783 dbType = DbType.Currency;
785 case SqlDbType.NChar:
786 MetaParameter.TypeName = "nchar";
787 dbType = DbType.StringFixedLength;
788 MetaParameter.IsVariableSizeType = true;
790 case SqlDbType.NText:
791 MetaParameter.TypeName = "ntext";
792 dbType = DbType.String;
793 MetaParameter.IsVariableSizeType = true;
795 case SqlDbType.NVarChar:
796 MetaParameter.TypeName = "nvarchar";
797 dbType = DbType.String;
798 MetaParameter.IsVariableSizeType = true;
801 MetaParameter.TypeName = "real";
802 dbType = DbType.Single;
804 case SqlDbType.SmallInt:
805 MetaParameter.TypeName = "smallint";
806 dbType = DbType.Int16;
809 MetaParameter.TypeName = "text";
810 dbType = DbType.AnsiString;
811 MetaParameter.IsVariableSizeType = true;
813 case SqlDbType.VarChar:
814 MetaParameter.TypeName = "varchar";
815 dbType = DbType.AnsiString;
816 MetaParameter.IsVariableSizeType = true;
818 case SqlDbType.TinyInt:
819 MetaParameter.TypeName = "tinyint";
820 dbType = DbType.Byte;
822 case SqlDbType.UniqueIdentifier:
823 MetaParameter.TypeName = "uniqueidentifier";
824 dbType = DbType.Guid;
826 case SqlDbType.Variant:
827 MetaParameter.TypeName = "sql_variant";
828 dbType = DbType.Object;
831 MetaParameter.TypeName = "xml";
833 MetaParameter.IsVariableSizeType = true;
836 string exception = String.Format ("No mapping exists from SqlDbType {0} to a known DbType.", type);
837 throw new ArgumentOutOfRangeException ("SqlDbType", exception);
842 public override string ToString()
844 return ParameterName;
847 object GetFrameworkValue (object rawValue, ref bool updated)
851 updated = typeChanged || updated;
853 tdsValue = SqlTypeToFrameworkType (rawValue);
860 // TODO: Code copied from SqlDataReader, need a better approach
861 object GetSqlValue (object value)
866 case SqlDbType.BigInt:
867 if (value == DBNull.Value)
868 return SqlInt64.Null;
869 return (SqlInt64) ((long) value);
870 case SqlDbType.Binary:
871 case SqlDbType.Image:
872 case SqlDbType.VarBinary:
873 case SqlDbType.Timestamp:
874 if (value == DBNull.Value)
875 return SqlBinary.Null;
876 return (SqlBinary) (byte[]) value;
878 if (value == DBNull.Value)
879 return SqlBoolean.Null;
880 return (SqlBoolean) ((bool) value);
882 case SqlDbType.NChar:
883 case SqlDbType.NText:
884 case SqlDbType.NVarChar:
886 case SqlDbType.VarChar:
887 if (value == DBNull.Value)
888 return SqlString.Null;
891 Type type = value.GetType ();
892 if (type == typeof (char))
893 str = value.ToString ();
894 else if (type == typeof (char[]))
895 str = new String ((char[])value);
897 str = ((string)value);
898 return (SqlString) str;
899 case SqlDbType.DateTime:
900 case SqlDbType.SmallDateTime:
901 if (value == DBNull.Value)
902 return SqlDateTime.Null;
903 return (SqlDateTime) ((DateTime) value);
904 case SqlDbType.Decimal:
905 if (value == DBNull.Value)
906 return SqlDecimal.Null;
907 if (value is TdsBigDecimal)
908 return SqlDecimalExtensions.FromTdsBigDecimal ((TdsBigDecimal) value);
909 return (SqlDecimal) ((decimal) value);
910 case SqlDbType.Float:
911 if (value == DBNull.Value)
912 return SqlDouble.Null;
913 return (SqlDouble) ((double) value);
915 if (value == DBNull.Value)
916 return SqlInt32.Null;
917 return (SqlInt32) ((int) value);
918 case SqlDbType.Money:
919 case SqlDbType.SmallMoney:
920 if (value == DBNull.Value)
921 return SqlMoney.Null;
922 return (SqlMoney) ((decimal) value);
924 if (value == DBNull.Value)
925 return SqlSingle.Null;
926 return (SqlSingle) ((float) value);
927 case SqlDbType.UniqueIdentifier:
928 if (value == DBNull.Value)
930 return (SqlGuid) ((Guid) value);
931 case SqlDbType.SmallInt:
932 if (value == DBNull.Value)
933 return SqlInt16.Null;
934 return (SqlInt16) ((short) value);
935 case SqlDbType.TinyInt:
936 if (value == DBNull.Value)
938 return (SqlByte) ((byte) value);
940 if (value == DBNull.Value)
942 return (SqlXml) value;
944 throw new NotImplementedException ("Type '" + sqlDbType + "' not implemented.");
948 object SqlTypeToFrameworkType (object value)
950 INullable nullable = value as INullable;
951 if (nullable == null)
952 return ConvertToFrameworkType (value);
957 Type type = value.GetType ();
958 // Map to .net type, as Mono TDS respects only types from .net
960 if (typeof (SqlString) == type) {
961 return ((SqlString) value).Value;
964 if (typeof (SqlInt16) == type) {
965 return ((SqlInt16) value).Value;
968 if (typeof (SqlInt32) == type) {
969 return ((SqlInt32) value).Value;
972 if (typeof (SqlDateTime) == type) {
973 return ((SqlDateTime) value).Value;
976 if (typeof (SqlInt64) == type) {
977 return ((SqlInt64) value).Value;
980 if (typeof (SqlBinary) == type) {
981 return ((SqlBinary) value).Value;
984 if (typeof (SqlBytes) == type) {
985 return ((SqlBytes) value).Value;
988 if (typeof (SqlChars) == type) {
989 return ((SqlChars) value).Value;
992 if (typeof (SqlBoolean) == type) {
993 return ((SqlBoolean) value).Value;
996 if (typeof (SqlByte) == type) {
997 return ((SqlByte) value).Value;
1000 if (typeof (SqlDecimal) == type) {
1001 return ((SqlDecimal) value).Value;
1004 if (typeof (SqlDouble) == type) {
1005 return ((SqlDouble) value).Value;
1008 if (typeof (SqlGuid) == type) {
1009 return ((SqlGuid) value).Value;
1012 if (typeof (SqlMoney) == type) {
1013 return ((SqlMoney) value).Value;
1016 if (typeof (SqlSingle) == type) {
1017 return ((SqlSingle) value).Value;
1023 internal object ConvertToFrameworkType (object value)
1025 if (value == null || value == DBNull.Value)
1027 if (sqlDbType == SqlDbType.Variant)
1028 return metaParameter.Value;
1030 Type frameworkType = SystemType;
1031 if (frameworkType == null)
1032 throw new NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
1034 Type valueType = value.GetType ();
1035 if (valueType == frameworkType)
1038 object sqlvalue = null;
1041 sqlvalue = ConvertToFrameworkType (value, frameworkType);
1042 } catch (FormatException ex) {
1043 throw new FormatException (string.Format (CultureInfo.InvariantCulture,
1044 "Parameter value could not be converted from {0} to {1}.",
1045 valueType.Name, frameworkType.Name), ex);
1051 object ConvertToFrameworkType (object value, Type frameworkType)
1053 object sqlvalue = Convert.ChangeType (value, frameworkType);
1054 switch (sqlDbType) {
1055 case SqlDbType.Money:
1056 case SqlDbType.SmallMoney:
1057 sqlvalue = Decimal.Round ((decimal) sqlvalue, 4);
1063 public override void ResetDbType ()
1065 InferSqlType (Value);
1068 public void ResetSqlDbType ()
1070 InferSqlType (Value);
1073 #endregion // Methods