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;
598 MetaParameter.TypeName = "decimal";
599 sqlDbType = SqlDbType.Decimal;
602 MetaParameter.TypeName = "float";
603 sqlDbType = SqlDbType.Float;
606 MetaParameter.TypeName = "uniqueidentifier";
607 sqlDbType = SqlDbType.UniqueIdentifier;
610 MetaParameter.TypeName = "smallint";
611 sqlDbType = SqlDbType.SmallInt;
614 MetaParameter.TypeName = "int";
615 sqlDbType = SqlDbType.Int;
618 MetaParameter.TypeName = "bigint";
619 sqlDbType = SqlDbType.BigInt;
622 MetaParameter.TypeName = "sql_variant";
623 sqlDbType = SqlDbType.Variant;
626 MetaParameter.TypeName = "real";
627 sqlDbType = SqlDbType.Real;
630 MetaParameter.TypeName = "nvarchar";
631 sqlDbType = SqlDbType.NVarChar;
632 MetaParameter.IsVariableSizeType = true;
634 case DbType.StringFixedLength:
635 MetaParameter.TypeName = "nchar";
636 sqlDbType = SqlDbType.NChar;
637 MetaParameter.IsVariableSizeType = true;
640 MetaParameter.TypeName = "datetime";
641 sqlDbType = SqlDbType.DateTime;
643 // Handle Xml type as string
645 MetaParameter.TypeName = "xml";
646 sqlDbType = SqlDbType.Xml;
647 MetaParameter.IsVariableSizeType = true;
650 string exception = String.Format ("No mapping exists from DbType {0} to a known SqlDbType.", type);
651 throw new ArgumentException (exception);
656 // Used by internal constructor which has a SQL Server typename
657 private SqlDbType FrameworkDbTypeFromName (string dbTypeName)
659 switch (dbTypeName.ToLower ()) {
661 return SqlDbType.BigInt;
663 return SqlDbType.Binary;
665 return SqlDbType.Bit;
667 return SqlDbType.Char;
669 return SqlDbType.DateTime;
671 return SqlDbType.Decimal;
673 return SqlDbType.Float;
675 return SqlDbType.Image;
677 return SqlDbType.Int;
679 return SqlDbType.Money;
681 return SqlDbType.NChar;
683 return SqlDbType.NText;
685 return SqlDbType.NVarChar;
687 return SqlDbType.Real;
688 case "smalldatetime":
689 return SqlDbType.SmallDateTime;
691 return SqlDbType.SmallInt;
693 return SqlDbType.SmallMoney;
695 return SqlDbType.Text;
697 return SqlDbType.Timestamp;
699 return SqlDbType.TinyInt;
700 case "uniqueidentifier":
701 return SqlDbType.UniqueIdentifier;
703 return SqlDbType.VarBinary;
705 return SqlDbType.VarChar;
707 return SqlDbType.Variant;
709 return SqlDbType.Xml;
711 return SqlDbType.Variant;
715 // When the SqlDbType is set, we also set the DbType, as well as the SQL Server
716 // string representation of the type name. If the SqlDbType is not convertible
717 // to a DbType, throw an exception.
718 internal void SetSqlDbType (SqlDbType type)
721 case SqlDbType.BigInt:
722 MetaParameter.TypeName = "bigint";
723 dbType = DbType.Int64;
725 case SqlDbType.Binary:
726 MetaParameter.TypeName = "binary";
727 dbType = DbType.Binary;
728 MetaParameter.IsVariableSizeType = true;
730 case SqlDbType.Timestamp:
731 MetaParameter.TypeName = "timestamp";
732 dbType = DbType.Binary;
734 case SqlDbType.VarBinary:
735 MetaParameter.TypeName = "varbinary";
736 dbType = DbType.Binary;
737 MetaParameter.IsVariableSizeType = true;
740 MetaParameter.TypeName = "bit";
741 dbType = DbType.Boolean;
744 MetaParameter.TypeName = "char";
745 dbType = DbType.AnsiStringFixedLength;
746 MetaParameter.IsVariableSizeType = true;
748 case SqlDbType.DateTime:
749 MetaParameter.TypeName = "datetime";
750 dbType = DbType.DateTime;
752 case SqlDbType.SmallDateTime:
753 MetaParameter.TypeName = "smalldatetime";
754 dbType = DbType.DateTime;
756 case SqlDbType.Decimal:
757 MetaParameter.TypeName = "decimal";
758 dbType = DbType.Decimal;
760 case SqlDbType.Float:
761 MetaParameter.TypeName = "float";
762 dbType = DbType.Double;
764 case SqlDbType.Image:
765 MetaParameter.TypeName = "image";
766 dbType = DbType.Binary;
767 MetaParameter.IsVariableSizeType = true;
770 MetaParameter.TypeName = "int";
771 dbType = DbType.Int32;
773 case SqlDbType.Money:
774 MetaParameter.TypeName = "money";
775 dbType = DbType.Currency;
777 case SqlDbType.SmallMoney:
778 MetaParameter.TypeName = "smallmoney";
779 dbType = DbType.Currency;
781 case SqlDbType.NChar:
782 MetaParameter.TypeName = "nchar";
783 dbType = DbType.StringFixedLength;
784 MetaParameter.IsVariableSizeType = true;
786 case SqlDbType.NText:
787 MetaParameter.TypeName = "ntext";
788 dbType = DbType.String;
789 MetaParameter.IsVariableSizeType = true;
791 case SqlDbType.NVarChar:
792 MetaParameter.TypeName = "nvarchar";
793 dbType = DbType.String;
794 MetaParameter.IsVariableSizeType = true;
797 MetaParameter.TypeName = "real";
798 dbType = DbType.Single;
800 case SqlDbType.SmallInt:
801 MetaParameter.TypeName = "smallint";
802 dbType = DbType.Int16;
805 MetaParameter.TypeName = "text";
806 dbType = DbType.AnsiString;
807 MetaParameter.IsVariableSizeType = true;
809 case SqlDbType.VarChar:
810 MetaParameter.TypeName = "varchar";
811 dbType = DbType.AnsiString;
812 MetaParameter.IsVariableSizeType = true;
814 case SqlDbType.TinyInt:
815 MetaParameter.TypeName = "tinyint";
816 dbType = DbType.Byte;
818 case SqlDbType.UniqueIdentifier:
819 MetaParameter.TypeName = "uniqueidentifier";
820 dbType = DbType.Guid;
822 case SqlDbType.Variant:
823 MetaParameter.TypeName = "sql_variant";
824 dbType = DbType.Object;
827 MetaParameter.TypeName = "xml";
829 MetaParameter.IsVariableSizeType = true;
832 string exception = String.Format ("No mapping exists from SqlDbType {0} to a known DbType.", type);
833 throw new ArgumentOutOfRangeException ("SqlDbType", exception);
838 public override string ToString()
840 return ParameterName;
843 object GetFrameworkValue (object rawValue, ref bool updated)
847 updated = typeChanged || updated;
849 tdsValue = SqlTypeToFrameworkType (rawValue);
856 // TODO: Code copied from SqlDataReader, need a better approach
857 object GetSqlValue (object value)
862 case SqlDbType.BigInt:
863 if (value == DBNull.Value)
864 return SqlInt64.Null;
865 return (SqlInt64) ((long) value);
866 case SqlDbType.Binary:
867 case SqlDbType.Image:
868 case SqlDbType.VarBinary:
869 case SqlDbType.Timestamp:
870 if (value == DBNull.Value)
871 return SqlBinary.Null;
872 return (SqlBinary) (byte[]) value;
874 if (value == DBNull.Value)
875 return SqlBoolean.Null;
876 return (SqlBoolean) ((bool) value);
878 case SqlDbType.NChar:
879 case SqlDbType.NText:
880 case SqlDbType.NVarChar:
882 case SqlDbType.VarChar:
883 if (value == DBNull.Value)
884 return SqlString.Null;
887 Type type = value.GetType ();
888 if (type == typeof (char))
889 str = value.ToString ();
890 else if (type == typeof (char[]))
891 str = new String ((char[])value);
893 str = ((string)value);
894 return (SqlString) str;
895 case SqlDbType.DateTime:
896 case SqlDbType.SmallDateTime:
897 if (value == DBNull.Value)
898 return SqlDateTime.Null;
899 return (SqlDateTime) ((DateTime) value);
900 case SqlDbType.Decimal:
901 if (value == DBNull.Value)
902 return SqlDecimal.Null;
903 if (value is TdsBigDecimal)
904 return SqlDecimal.FromTdsBigDecimal ((TdsBigDecimal) value);
905 return (SqlDecimal) ((decimal) value);
906 case SqlDbType.Float:
907 if (value == DBNull.Value)
908 return SqlDouble.Null;
909 return (SqlDouble) ((double) value);
911 if (value == DBNull.Value)
912 return SqlInt32.Null;
913 return (SqlInt32) ((int) value);
914 case SqlDbType.Money:
915 case SqlDbType.SmallMoney:
916 if (value == DBNull.Value)
917 return SqlMoney.Null;
918 return (SqlMoney) ((decimal) value);
920 if (value == DBNull.Value)
921 return SqlSingle.Null;
922 return (SqlSingle) ((float) value);
923 case SqlDbType.UniqueIdentifier:
924 if (value == DBNull.Value)
926 return (SqlGuid) ((Guid) value);
927 case SqlDbType.SmallInt:
928 if (value == DBNull.Value)
929 return SqlInt16.Null;
930 return (SqlInt16) ((short) value);
931 case SqlDbType.TinyInt:
932 if (value == DBNull.Value)
934 return (SqlByte) ((byte) value);
936 if (value == DBNull.Value)
938 return (SqlXml) value;
940 throw new NotImplementedException ("Type '" + sqlDbType + "' not implemented.");
944 object SqlTypeToFrameworkType (object value)
946 INullable nullable = value as INullable;
947 if (nullable == null)
948 return ConvertToFrameworkType (value);
953 Type type = value.GetType ();
954 // Map to .net type, as Mono TDS respects only types from .net
956 if (typeof (SqlString) == type) {
957 return ((SqlString) value).Value;
960 if (typeof (SqlInt16) == type) {
961 return ((SqlInt16) value).Value;
964 if (typeof (SqlInt32) == type) {
965 return ((SqlInt32) value).Value;
968 if (typeof (SqlDateTime) == type) {
969 return ((SqlDateTime) value).Value;
972 if (typeof (SqlInt64) == type) {
973 return ((SqlInt64) value).Value;
976 if (typeof (SqlBinary) == type) {
977 return ((SqlBinary) value).Value;
980 if (typeof (SqlBytes) == type) {
981 return ((SqlBytes) value).Value;
984 if (typeof (SqlChars) == type) {
985 return ((SqlChars) value).Value;
988 if (typeof (SqlBoolean) == type) {
989 return ((SqlBoolean) value).Value;
992 if (typeof (SqlByte) == type) {
993 return ((SqlByte) value).Value;
996 if (typeof (SqlDecimal) == type) {
997 return ((SqlDecimal) value).Value;
1000 if (typeof (SqlDouble) == type) {
1001 return ((SqlDouble) value).Value;
1004 if (typeof (SqlGuid) == type) {
1005 return ((SqlGuid) value).Value;
1008 if (typeof (SqlMoney) == type) {
1009 return ((SqlMoney) value).Value;
1012 if (typeof (SqlSingle) == type) {
1013 return ((SqlSingle) value).Value;
1019 internal object ConvertToFrameworkType (object value)
1021 if (value == null || value == DBNull.Value)
1023 if (sqlDbType == SqlDbType.Variant)
1024 return metaParameter.Value;
1026 Type frameworkType = SystemType;
1027 if (frameworkType == null)
1028 throw new NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
1030 Type valueType = value.GetType ();
1031 if (valueType == frameworkType)
1034 object sqlvalue = null;
1037 sqlvalue = ConvertToFrameworkType (value, frameworkType);
1038 } catch (FormatException ex) {
1039 throw new FormatException (string.Format (CultureInfo.InvariantCulture,
1040 "Parameter value could not be converted from {0} to {1}.",
1041 valueType.Name, frameworkType.Name), ex);
1047 object ConvertToFrameworkType (object value, Type frameworkType)
1049 object sqlvalue = Convert.ChangeType (value, frameworkType);
1050 switch (sqlDbType) {
1051 case SqlDbType.Money:
1052 case SqlDbType.SmallMoney:
1053 sqlvalue = Decimal.Round ((decimal) sqlvalue, 4);
1059 public override void ResetDbType ()
1061 InferSqlType (Value);
1064 public void ResetSqlDbType ()
1066 InferSqlType (Value);
1069 #endregion // Methods