[Sys.Data] reuse our SqlClient implementation.
[mono-project.git] / mcs / class / System.Data / System.Data.SqlClient / SqlParameter.cs
blob346c796ee9bfcfa7b2d0b68b3369d7e7384038b1
1 //
2 // System.Data.SqlClient.SqlParameter.cs
3 //
4 // Author:
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:
27 //
28 // The above copyright notice and this permission notice shall be
29 // included in all copies or substantial portions of the Software.
30 //
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.
40 using Mono.Data.Tds;
41 using Mono.Data.Tds.Protocol;
42 using System;
43 using System.Collections;
44 using System.ComponentModel;
45 using System.Data;
46 using System.Data.Common;
47 using System.Data.SqlTypes;
48 using System.Globalization;
49 using System.Runtime.InteropServices;
50 using System.Text;
51 using System.Xml;
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 {
66 get {
67 return (Type) dbTypeMapping [DbType];
70 #endregion
72 #region Fields
74 TdsMetaParameter metaParameter;
76 SqlParameterCollection container;
77 DbType dbType;
78 ParameterDirection direction = ParameterDirection.Input;
79 bool isTypeSet;
80 int offset;
81 SqlDbType sqlDbType;
82 string sourceColumn;
83 DataRowVersion sourceVersion;
84 SqlCompareOptions compareInfo;
85 int localeId;
86 Type sqlType;
87 bool typeChanged;
88 bool sourceColumnNullMapping;
89 string xmlSchemaCollectionDatabase = String.Empty;
90 string xmlSchemaCollectionOwningSchema = String.Empty;
91 string xmlSchemaCollectionName = String.Empty;
93 static Hashtable type_mapping;
95 #endregion // Fields
97 #region Constructors
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.Decimal, typeof (decimal));
116 DbTypeMapping.Add (SqlDbType.Float, typeof (double));
117 DbTypeMapping.Add (SqlDbType.Binary, typeof (byte []));
118 DbTypeMapping.Add (SqlDbType.Image, typeof (byte []));
119 DbTypeMapping.Add (SqlDbType.Money, typeof (decimal));
120 DbTypeMapping.Add (SqlDbType.SmallMoney, typeof (decimal));
121 DbTypeMapping.Add (SqlDbType.VarBinary, typeof (byte []));
122 DbTypeMapping.Add (SqlDbType.TinyInt, typeof (byte));
123 DbTypeMapping.Add (SqlDbType.Int, typeof (int));
124 DbTypeMapping.Add (SqlDbType.Real, typeof (float));
125 DbTypeMapping.Add (SqlDbType.SmallInt, typeof (short));
126 DbTypeMapping.Add (SqlDbType.UniqueIdentifier, typeof (Guid));
127 DbTypeMapping.Add (SqlDbType.Variant, typeof (object));
128 DbTypeMapping.Add (SqlDbType.Xml, typeof (string));
130 type_mapping = new Hashtable ();
132 type_mapping.Add (typeof (long), SqlDbType.BigInt);
133 type_mapping.Add (typeof (SqlTypes.SqlInt64), SqlDbType.BigInt);
135 type_mapping.Add (typeof (bool), SqlDbType.Bit);
136 type_mapping.Add (typeof (SqlTypes.SqlBoolean), SqlDbType.Bit);
138 type_mapping.Add (typeof (char), SqlDbType.NVarChar);
139 type_mapping.Add (typeof (char []), SqlDbType.NVarChar);
140 type_mapping.Add (typeof (SqlTypes.SqlChars), SqlDbType.NVarChar);
142 type_mapping.Add (typeof (string), SqlDbType.NVarChar);
143 type_mapping.Add (typeof (SqlTypes.SqlString), SqlDbType.NVarChar);
145 type_mapping.Add (typeof (DateTime), SqlDbType.DateTime);
146 type_mapping.Add (typeof (SqlTypes.SqlDateTime), SqlDbType.DateTime);
148 type_mapping.Add (typeof (decimal), SqlDbType.Decimal);
149 type_mapping.Add (typeof (SqlTypes.SqlDecimal), SqlDbType.Decimal);
151 type_mapping.Add (typeof (double), SqlDbType.Float);
152 type_mapping.Add (typeof (SqlTypes.SqlDouble), SqlDbType.Float);
154 type_mapping.Add (typeof (byte []), SqlDbType.VarBinary);
155 type_mapping.Add (typeof (SqlTypes.SqlBinary), SqlDbType.VarBinary);
157 type_mapping.Add (typeof (SqlTypes.SqlBytes), SqlDbType.VarBinary);
159 type_mapping.Add (typeof (byte), SqlDbType.TinyInt);
160 type_mapping.Add (typeof (SqlTypes.SqlByte), SqlDbType.TinyInt);
162 type_mapping.Add (typeof (int), SqlDbType.Int);
163 type_mapping.Add (typeof (SqlTypes.SqlInt32), SqlDbType.Int);
165 type_mapping.Add (typeof (float), SqlDbType.Real);
166 type_mapping.Add (typeof (SqlTypes.SqlSingle), SqlDbType.Real);
168 type_mapping.Add (typeof (short), SqlDbType.SmallInt);
169 type_mapping.Add (typeof (SqlTypes.SqlInt16), SqlDbType.SmallInt);
171 type_mapping.Add (typeof (Guid), SqlDbType.UniqueIdentifier);
172 type_mapping.Add (typeof (SqlTypes.SqlGuid), SqlDbType.UniqueIdentifier);
174 type_mapping.Add (typeof (SqlTypes.SqlMoney), SqlDbType.Money);
176 type_mapping.Add (typeof (XmlReader), SqlDbType.Xml);
177 type_mapping.Add (typeof (SqlTypes.SqlXml), SqlDbType.Xml);
179 type_mapping.Add (typeof (object), SqlDbType.Variant);
182 public SqlParameter ()
183 : this (String.Empty, SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
185 isTypeSet = false;
188 public SqlParameter (string parameterName, object value)
190 if (parameterName == null)
191 parameterName = string.Empty;
192 metaParameter = new TdsMetaParameter (parameterName, GetFrameworkValue);
193 metaParameter.RawValue = value;
194 InferSqlType (value);
195 sourceVersion = DataRowVersion.Current;
198 public SqlParameter (string parameterName, SqlDbType dbType)
199 : this (parameterName, dbType, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, null)
203 public SqlParameter (string parameterName, SqlDbType dbType, int size)
204 : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, null)
208 public SqlParameter (string parameterName, SqlDbType dbType, int size, string sourceColumn)
209 : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, sourceColumn, DataRowVersion.Current, null)
213 [EditorBrowsable (EditorBrowsableState.Advanced)]
214 public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
216 if (parameterName == null)
217 parameterName = string.Empty;
219 metaParameter = new TdsMetaParameter (parameterName, size,
220 isNullable, precision,
221 scale,
222 GetFrameworkValue);
223 metaParameter.RawValue = value;
224 if (dbType != SqlDbType.Variant)
225 SqlDbType = dbType;
226 Direction = direction;
227 SourceColumn = sourceColumn;
228 SourceVersion = sourceVersion;
231 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)
232 : this (parameterName, dbType, size, direction, false, precision, scale, sourceColumn, sourceVersion, value)
234 XmlSchemaCollectionDatabase = xmlSchemaCollectionDatabase;
235 XmlSchemaCollectionOwningSchema = xmlSchemaCollectionOwningSchema;
236 XmlSchemaCollectionName = xmlSchemaCollectionName;
237 SourceColumnNullMapping = sourceColumnNullMapping;
240 // This constructor is used internally to construct a
241 // SqlParameter. The value array comes from sp_procedure_params_rowset.
242 // This is in SqlCommand.DeriveParameters.
244 // http://social.msdn.microsoft.com/forums/en-US/transactsql/thread/900756fd-3980-48e3-ae59-a15d7fc15b4c/
245 internal SqlParameter (object[] dbValues)
246 : this (dbValues [3].ToString (), (object) null)
248 ParameterName = (string) dbValues [3];
250 switch ((short) dbValues [5]) {
251 case 1:
252 Direction = ParameterDirection.Input;
253 break;
254 case 2:
255 Direction = ParameterDirection.InputOutput;
256 break;
257 case 3:
258 Direction = ParameterDirection.Output;
259 break;
260 case 4:
261 Direction = ParameterDirection.ReturnValue;
262 break;
263 default:
264 Direction = ParameterDirection.Input;
265 break;
268 SqlDbType = (SqlDbType) FrameworkDbTypeFromName ((string) dbValues [16]);
270 if (MetaParameter.IsVariableSizeType) {
271 if (dbValues [10] != DBNull.Value)
272 Size = (int) dbValues [10];
275 if (SqlDbType == SqlDbType.Decimal) {
276 if (dbValues [12] != null && dbValues [12] != DBNull.Value)
277 Precision = (byte) ((short) dbValues [12]);
278 if (dbValues [13] != null && dbValues [13] != DBNull.Value)
279 Scale = (byte) ((short) dbValues [13]);
283 #endregion // Constructors
285 #region Properties
287 // Used to ensure that only one collection can contain this
288 // parameter
289 internal SqlParameterCollection Container {
290 get { return container; }
291 set { container = value; }
294 internal void CheckIfInitialized ()
296 if (!isTypeSet)
297 throw new Exception ("all parameters to have an explicity set type");
299 if (MetaParameter.IsVariableSizeType) {
300 if (SqlDbType == SqlDbType.Decimal && Precision == 0)
301 throw new Exception ("Parameter of type 'Decimal' have an explicitly set Precision and Scale");
302 else if (Size == 0)
303 throw new Exception ("all variable length parameters to have an explicitly set non-zero Size");
307 public override DbType DbType {
308 get { return dbType; }
309 set {
310 SetDbType (value);
311 typeChanged = true;
312 isTypeSet = true;
316 [RefreshProperties (RefreshProperties.All)]
317 public override
318 ParameterDirection Direction {
319 get { return direction; }
320 set {
321 direction = value;
322 switch( direction ) {
323 case ParameterDirection.Output:
324 MetaParameter.Direction = TdsParameterDirection.Output;
325 break;
326 case ParameterDirection.InputOutput:
327 MetaParameter.Direction = TdsParameterDirection.InputOutput;
328 break;
329 case ParameterDirection.ReturnValue:
330 MetaParameter.Direction = TdsParameterDirection.ReturnValue;
331 break;
336 internal TdsMetaParameter MetaParameter {
337 get { return metaParameter; }
340 public override bool IsNullable {
341 get { return metaParameter.IsNullable; }
342 set { metaParameter.IsNullable = value; }
345 [Browsable (false)]
346 [EditorBrowsable (EditorBrowsableState.Advanced)]
347 public int Offset {
348 get { return offset; }
349 set { offset = value; }
352 public override string ParameterName {
353 get { return metaParameter.ParameterName; }
354 set {
355 if (value == null)
356 value = string.Empty;
357 metaParameter.ParameterName = value;
361 [DefaultValue (0)]
362 public byte Precision {
363 get { return metaParameter.Precision; }
364 set { metaParameter.Precision = value; }
367 [DefaultValue (0)]
368 public byte Scale {
369 get { return metaParameter.Scale; }
370 set { metaParameter.Scale = value; }
373 public override int Size {
374 get { return metaParameter.Size; }
375 set { metaParameter.Size = value; }
378 public override string SourceColumn {
379 get {
380 if (sourceColumn == null)
381 return string.Empty;
382 return sourceColumn;
384 set { sourceColumn = value; }
387 public override DataRowVersion SourceVersion {
388 get { return sourceVersion; }
389 set { sourceVersion = value; }
392 [RefreshProperties (RefreshProperties.All)]
393 [DbProviderSpecificTypeProperty(true)]
394 public SqlDbType SqlDbType {
395 get { return sqlDbType; }
396 set {
397 SetSqlDbType (value);
398 typeChanged = true;
399 isTypeSet = true;
403 [TypeConverterAttribute (typeof (StringConverter))]
404 [RefreshProperties (RefreshProperties.All)]
405 public override object Value {
406 get {
407 if (sqlType != null)
408 return GetSqlValue (metaParameter.RawValue);
409 return metaParameter.RawValue;
411 set {
412 if (!isTypeSet) {
413 InferSqlType (value);
416 if (value is INullable) {
417 sqlType = value.GetType ();
418 value = SqlTypeToFrameworkType (value);
420 metaParameter.RawValue = value;
424 [Browsable (false)]
425 public SqlCompareOptions CompareInfo{
426 get{ return compareInfo; }
427 set{ compareInfo = value; }
430 [Browsable (false)]
431 public int LocaleId {
432 get { return localeId; }
433 set { localeId = value; }
436 [Browsable (false)]
437 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
438 public Object SqlValue {
439 get {
440 return GetSqlValue (metaParameter.RawValue);
442 set {
443 Value = value;
447 public override bool SourceColumnNullMapping {
448 get { return sourceColumnNullMapping; }
449 set { sourceColumnNullMapping = value; }
452 public string XmlSchemaCollectionDatabase {
453 get { return xmlSchemaCollectionDatabase; }
454 set { xmlSchemaCollectionDatabase = (value == null ? String.Empty : value); }
457 public string XmlSchemaCollectionName {
458 get { return xmlSchemaCollectionName; }
459 set {
460 xmlSchemaCollectionName = (value == null ? String.Empty : value);
464 public string XmlSchemaCollectionOwningSchema {
465 get { return xmlSchemaCollectionOwningSchema; }
466 set {
467 xmlSchemaCollectionOwningSchema = (value == null ? String.Empty : value);
471 [BrowsableAttribute(false)]
472 public string UdtTypeName { get; set; }
474 #endregion // Properties
476 #region Methods
478 object ICloneable.Clone ()
480 return new SqlParameter (ParameterName, SqlDbType, Size, Direction, IsNullable, Precision, Scale, SourceColumn, SourceVersion, Value);
483 // If the value is set without the DbType/SqlDbType being set, then we
484 // infer type information.
485 void InferSqlType (object value)
487 if (value == null || value == DBNull.Value) {
488 SetSqlDbType (SqlDbType.NVarChar);
489 return;
492 Type type = value.GetType ();
493 if (type.IsEnum)
494 type = Enum.GetUnderlyingType (type);
495 object t = type_mapping [type];
496 if (t == null)
497 throw new ArgumentException (String.Format ("The parameter data type of {0} is invalid.", type.FullName));
498 SetSqlDbType ((SqlDbType) t);
502 // Returns System.Type corresponding to the underlying SqlDbType
503 internal override Type SystemType {
504 get {
505 return (Type) DbTypeMapping [sqlDbType];
509 internal override object FrameworkDbType {
510 get {
511 return sqlDbType;
514 set {
515 object t;
516 try {
517 t = (DbType) DbTypeFromName ((string)value);
518 SetDbType ((DbType)t);
519 } catch (ArgumentException) {
520 t = (SqlDbType)FrameworkDbTypeFromName ((string)value);
521 SetSqlDbType ((SqlDbType) t);
527 DbType DbTypeFromName (string name)
529 switch (name.ToLower ()) {
530 case "ansistring":
531 return DbType.AnsiString;
532 case "ansistringfixedlength":
533 return DbType.AnsiStringFixedLength;
534 case "binary":
535 return DbType.Binary;
536 case "boolean":
537 return DbType.Boolean;
538 case "byte":
539 return DbType.Byte;
540 case "currency":
541 return DbType.Currency;
542 case "date":
543 return DbType.Date;
544 case "datetime":
545 return DbType.DateTime;
546 case "decimal":
547 return DbType.Decimal;
548 case "double":
549 return DbType.Double;
550 case "guid":
551 return DbType.Guid;
552 case "int16":
553 return DbType.Int16;
554 case "int32":
555 return DbType.Int32;
556 case "int64":
557 return DbType.Int64;
558 case "object":
559 return DbType.Object;
560 case "single":
561 return DbType.Single;
562 case "string":
563 return DbType.String;
564 case "stringfixedlength":
565 return DbType.StringFixedLength;
566 case "time":
567 return DbType.Time;
568 case "xml":
569 return DbType.Xml;
570 default:
571 string exception = String.Format ("No mapping exists from {0} to a known DbType.", name);
572 throw new ArgumentException (exception);
576 // When the DbType is set, we also set the SqlDbType, as well as the SQL Server
577 // string representation of the type name. If the DbType is not convertible
578 // to an SqlDbType, throw an exception.
579 private void SetDbType (DbType type)
581 switch (type) {
582 case DbType.AnsiString:
583 MetaParameter.TypeName = "varchar";
584 sqlDbType = SqlDbType.VarChar;
585 MetaParameter.IsVariableSizeType = true;
586 break;
587 case DbType.AnsiStringFixedLength:
588 MetaParameter.TypeName = "char";
589 sqlDbType = SqlDbType.Char;
590 MetaParameter.IsVariableSizeType = true;
591 break;
592 case DbType.Binary:
593 MetaParameter.TypeName = "varbinary";
594 sqlDbType = SqlDbType.VarBinary;
595 MetaParameter.IsVariableSizeType = true;
596 break;
597 case DbType.Boolean:
598 MetaParameter.TypeName = "bit";
599 sqlDbType = SqlDbType.Bit;
600 break;
601 case DbType.Byte:
602 MetaParameter.TypeName = "tinyint";
603 sqlDbType = SqlDbType.TinyInt;
604 break;
605 case DbType.Currency:
606 sqlDbType = SqlDbType.Money;
607 MetaParameter.TypeName = "money";
608 break;
609 case DbType.Date:
610 case DbType.DateTime:
611 MetaParameter.TypeName = "datetime";
612 sqlDbType = SqlDbType.DateTime;
613 break;
614 case DbType.DateTime2:
615 MetaParameter.TypeName = "datetime2";
616 sqlDbType = SqlDbType.DateTime2;
617 break;
618 case DbType.Decimal:
619 MetaParameter.TypeName = "decimal";
620 sqlDbType = SqlDbType.Decimal;
621 break;
622 case DbType.Double:
623 MetaParameter.TypeName = "float";
624 sqlDbType = SqlDbType.Float;
625 break;
626 case DbType.Guid:
627 MetaParameter.TypeName = "uniqueidentifier";
628 sqlDbType = SqlDbType.UniqueIdentifier;
629 break;
630 case DbType.Int16:
631 MetaParameter.TypeName = "smallint";
632 sqlDbType = SqlDbType.SmallInt;
633 break;
634 case DbType.Int32:
635 MetaParameter.TypeName = "int";
636 sqlDbType = SqlDbType.Int;
637 break;
638 case DbType.Int64:
639 MetaParameter.TypeName = "bigint";
640 sqlDbType = SqlDbType.BigInt;
641 break;
642 case DbType.Object:
643 MetaParameter.TypeName = "sql_variant";
644 sqlDbType = SqlDbType.Variant;
645 break;
646 case DbType.Single:
647 MetaParameter.TypeName = "real";
648 sqlDbType = SqlDbType.Real;
649 break;
650 case DbType.String:
651 MetaParameter.TypeName = "nvarchar";
652 sqlDbType = SqlDbType.NVarChar;
653 MetaParameter.IsVariableSizeType = true;
654 break;
655 case DbType.StringFixedLength:
656 MetaParameter.TypeName = "nchar";
657 sqlDbType = SqlDbType.NChar;
658 MetaParameter.IsVariableSizeType = true;
659 break;
660 case DbType.Time:
661 MetaParameter.TypeName = "datetime";
662 sqlDbType = SqlDbType.DateTime;
663 break;
664 // Handle Xml type as string
665 case DbType.Xml:
666 MetaParameter.TypeName = "xml";
667 sqlDbType = SqlDbType.Xml;
668 MetaParameter.IsVariableSizeType = true;
669 break;
670 default:
671 string exception = String.Format ("No mapping exists from DbType {0} to a known SqlDbType.", type);
672 throw new ArgumentException (exception);
674 dbType = type;
677 // Used by internal constructor which has a SQL Server typename
678 private SqlDbType FrameworkDbTypeFromName (string dbTypeName)
680 switch (dbTypeName.ToLower ()) {
681 case "bigint":
682 return SqlDbType.BigInt;
683 case "binary":
684 return SqlDbType.Binary;
685 case "bit":
686 return SqlDbType.Bit;
687 case "char":
688 return SqlDbType.Char;
689 case "datetime":
690 return SqlDbType.DateTime;
691 case "decimal":
692 return SqlDbType.Decimal;
693 case "float":
694 return SqlDbType.Float;
695 case "image":
696 return SqlDbType.Image;
697 case "int":
698 return SqlDbType.Int;
699 case "money":
700 return SqlDbType.Money;
701 case "nchar":
702 return SqlDbType.NChar;
703 case "ntext":
704 return SqlDbType.NText;
705 case "nvarchar":
706 return SqlDbType.NVarChar;
707 case "real":
708 return SqlDbType.Real;
709 case "smalldatetime":
710 return SqlDbType.SmallDateTime;
711 case "smallint":
712 return SqlDbType.SmallInt;
713 case "smallmoney":
714 return SqlDbType.SmallMoney;
715 case "text":
716 return SqlDbType.Text;
717 case "timestamp":
718 return SqlDbType.Timestamp;
719 case "tinyint":
720 return SqlDbType.TinyInt;
721 case "uniqueidentifier":
722 return SqlDbType.UniqueIdentifier;
723 case "varbinary":
724 return SqlDbType.VarBinary;
725 case "varchar":
726 return SqlDbType.VarChar;
727 case "sql_variant":
728 return SqlDbType.Variant;
729 case "xml":
730 return SqlDbType.Xml;
731 default:
732 return SqlDbType.Variant;
736 // When the SqlDbType is set, we also set the DbType, as well as the SQL Server
737 // string representation of the type name. If the SqlDbType is not convertible
738 // to a DbType, throw an exception.
739 internal void SetSqlDbType (SqlDbType type)
741 switch (type) {
742 case SqlDbType.BigInt:
743 MetaParameter.TypeName = "bigint";
744 dbType = DbType.Int64;
745 break;
746 case SqlDbType.Binary:
747 MetaParameter.TypeName = "binary";
748 dbType = DbType.Binary;
749 MetaParameter.IsVariableSizeType = true;
750 break;
751 case SqlDbType.Timestamp:
752 MetaParameter.TypeName = "timestamp";
753 dbType = DbType.Binary;
754 break;
755 case SqlDbType.VarBinary:
756 MetaParameter.TypeName = "varbinary";
757 dbType = DbType.Binary;
758 MetaParameter.IsVariableSizeType = true;
759 break;
760 case SqlDbType.Bit:
761 MetaParameter.TypeName = "bit";
762 dbType = DbType.Boolean;
763 break;
764 case SqlDbType.Char:
765 MetaParameter.TypeName = "char";
766 dbType = DbType.AnsiStringFixedLength;
767 MetaParameter.IsVariableSizeType = true;
768 break;
769 case SqlDbType.DateTime:
770 MetaParameter.TypeName = "datetime";
771 dbType = DbType.DateTime;
772 break;
773 case SqlDbType.SmallDateTime:
774 MetaParameter.TypeName = "smalldatetime";
775 dbType = DbType.DateTime;
776 break;
777 case SqlDbType.Decimal:
778 MetaParameter.TypeName = "decimal";
779 dbType = DbType.Decimal;
780 break;
781 case SqlDbType.Float:
782 MetaParameter.TypeName = "float";
783 dbType = DbType.Double;
784 break;
785 case SqlDbType.Image:
786 MetaParameter.TypeName = "image";
787 dbType = DbType.Binary;
788 MetaParameter.IsVariableSizeType = true;
789 break;
790 case SqlDbType.Int:
791 MetaParameter.TypeName = "int";
792 dbType = DbType.Int32;
793 break;
794 case SqlDbType.Money:
795 MetaParameter.TypeName = "money";
796 dbType = DbType.Currency;
797 break;
798 case SqlDbType.SmallMoney:
799 MetaParameter.TypeName = "smallmoney";
800 dbType = DbType.Currency;
801 break;
802 case SqlDbType.NChar:
803 MetaParameter.TypeName = "nchar";
804 dbType = DbType.StringFixedLength;
805 MetaParameter.IsVariableSizeType = true;
806 break;
807 case SqlDbType.NText:
808 MetaParameter.TypeName = "ntext";
809 dbType = DbType.String;
810 MetaParameter.IsVariableSizeType = true;
811 break;
812 case SqlDbType.NVarChar:
813 MetaParameter.TypeName = "nvarchar";
814 dbType = DbType.String;
815 MetaParameter.IsVariableSizeType = true;
816 break;
817 case SqlDbType.Real:
818 MetaParameter.TypeName = "real";
819 dbType = DbType.Single;
820 break;
821 case SqlDbType.SmallInt:
822 MetaParameter.TypeName = "smallint";
823 dbType = DbType.Int16;
824 break;
825 case SqlDbType.Text:
826 MetaParameter.TypeName = "text";
827 dbType = DbType.AnsiString;
828 MetaParameter.IsVariableSizeType = true;
829 break;
830 case SqlDbType.VarChar:
831 MetaParameter.TypeName = "varchar";
832 dbType = DbType.AnsiString;
833 MetaParameter.IsVariableSizeType = true;
834 break;
835 case SqlDbType.TinyInt:
836 MetaParameter.TypeName = "tinyint";
837 dbType = DbType.Byte;
838 break;
839 case SqlDbType.UniqueIdentifier:
840 MetaParameter.TypeName = "uniqueidentifier";
841 dbType = DbType.Guid;
842 break;
843 case SqlDbType.Variant:
844 MetaParameter.TypeName = "sql_variant";
845 dbType = DbType.Object;
846 break;
847 case SqlDbType.Xml:
848 MetaParameter.TypeName = "xml";
849 dbType = DbType.Xml;
850 MetaParameter.IsVariableSizeType = true;
851 break;
852 default:
853 string exception = String.Format ("No mapping exists from SqlDbType {0} to a known DbType.", type);
854 throw new ArgumentOutOfRangeException ("SqlDbType", exception);
856 sqlDbType = type;
859 public override string ToString()
861 return ParameterName;
864 object GetFrameworkValue (object rawValue, ref bool updated)
866 object tdsValue;
868 updated = typeChanged || updated;
869 if (updated) {
870 tdsValue = SqlTypeToFrameworkType (rawValue);
871 typeChanged = false;
872 } else
873 tdsValue = null;
874 return tdsValue;
877 // TODO: Code copied from SqlDataReader, need a better approach
878 object GetSqlValue (object value)
880 if (value == null)
881 return value;
882 switch (sqlDbType) {
883 case SqlDbType.BigInt:
884 if (value == DBNull.Value)
885 return SqlInt64.Null;
886 return (SqlInt64) ((long) value);
887 case SqlDbType.Binary:
888 case SqlDbType.Image:
889 case SqlDbType.VarBinary:
890 case SqlDbType.Timestamp:
891 if (value == DBNull.Value)
892 return SqlBinary.Null;
893 return (SqlBinary) (byte[]) value;
894 case SqlDbType.Bit:
895 if (value == DBNull.Value)
896 return SqlBoolean.Null;
897 return (SqlBoolean) ((bool) value);
898 case SqlDbType.Char:
899 case SqlDbType.NChar:
900 case SqlDbType.NText:
901 case SqlDbType.NVarChar:
902 case SqlDbType.Text:
903 case SqlDbType.VarChar:
904 if (value == DBNull.Value)
905 return SqlString.Null;
907 string str;
908 Type type = value.GetType ();
909 if (type == typeof (char))
910 str = value.ToString ();
911 else if (type == typeof (char[]))
912 str = new String ((char[])value);
913 else
914 str = ((string)value);
915 return (SqlString) str;
916 case SqlDbType.DateTime:
917 case SqlDbType.SmallDateTime:
918 if (value == DBNull.Value)
919 return SqlDateTime.Null;
920 return (SqlDateTime) ((DateTime) value);
921 case SqlDbType.Decimal:
922 if (value == DBNull.Value)
923 return SqlDecimal.Null;
924 if (value is TdsBigDecimal)
925 return SqlDecimalExtensions.FromTdsBigDecimal ((TdsBigDecimal) value);
926 return (SqlDecimal) ((decimal) value);
927 case SqlDbType.Float:
928 if (value == DBNull.Value)
929 return SqlDouble.Null;
930 return (SqlDouble) ((double) value);
931 case SqlDbType.Int:
932 if (value == DBNull.Value)
933 return SqlInt32.Null;
934 return (SqlInt32) ((int) value);
935 case SqlDbType.Money:
936 case SqlDbType.SmallMoney:
937 if (value == DBNull.Value)
938 return SqlMoney.Null;
939 return (SqlMoney) ((decimal) value);
940 case SqlDbType.Real:
941 if (value == DBNull.Value)
942 return SqlSingle.Null;
943 return (SqlSingle) ((float) value);
944 case SqlDbType.UniqueIdentifier:
945 if (value == DBNull.Value)
946 return SqlGuid.Null;
947 return (SqlGuid) ((Guid) value);
948 case SqlDbType.SmallInt:
949 if (value == DBNull.Value)
950 return SqlInt16.Null;
951 return (SqlInt16) ((short) value);
952 case SqlDbType.TinyInt:
953 if (value == DBNull.Value)
954 return SqlByte.Null;
955 return (SqlByte) ((byte) value);
956 case SqlDbType.Xml:
957 if (value == DBNull.Value)
958 return SqlXml.Null;
959 return (SqlXml) value;
960 default:
961 throw new NotImplementedException ("Type '" + sqlDbType + "' not implemented.");
965 object SqlTypeToFrameworkType (object value)
967 INullable nullable = value as INullable;
968 if (nullable == null)
969 return ConvertToFrameworkType (value);
971 if (nullable.IsNull)
972 return DBNull.Value;
974 Type type = value.GetType ();
975 // Map to .net type, as Mono TDS respects only types from .net
977 if (typeof (SqlString) == type) {
978 return ((SqlString) value).Value;
981 if (typeof (SqlInt16) == type) {
982 return ((SqlInt16) value).Value;
985 if (typeof (SqlInt32) == type) {
986 return ((SqlInt32) value).Value;
989 if (typeof (SqlDateTime) == type) {
990 return ((SqlDateTime) value).Value;
993 if (typeof (SqlInt64) == type) {
994 return ((SqlInt64) value).Value;
997 if (typeof (SqlBinary) == type) {
998 return ((SqlBinary) value).Value;
1001 if (typeof (SqlBytes) == type) {
1002 return ((SqlBytes) value).Value;
1005 if (typeof (SqlChars) == type) {
1006 return ((SqlChars) value).Value;
1009 if (typeof (SqlBoolean) == type) {
1010 return ((SqlBoolean) value).Value;
1013 if (typeof (SqlByte) == type) {
1014 return ((SqlByte) value).Value;
1017 if (typeof (SqlDecimal) == type) {
1018 return ((SqlDecimal) value).Value;
1021 if (typeof (SqlDouble) == type) {
1022 return ((SqlDouble) value).Value;
1025 if (typeof (SqlGuid) == type) {
1026 return ((SqlGuid) value).Value;
1029 if (typeof (SqlMoney) == type) {
1030 return ((SqlMoney) value).Value;
1033 if (typeof (SqlSingle) == type) {
1034 return ((SqlSingle) value).Value;
1037 return value;
1040 internal object ConvertToFrameworkType (object value)
1042 if (value == null || value == DBNull.Value)
1043 return value;
1044 if (sqlDbType == SqlDbType.Variant)
1045 return metaParameter.Value;
1047 Type frameworkType = SystemType;
1048 if (frameworkType == null)
1049 throw new NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
1051 Type valueType = value.GetType ();
1052 if (valueType == frameworkType)
1053 return value;
1055 object sqlvalue = null;
1057 try {
1058 sqlvalue = ConvertToFrameworkType (value, frameworkType);
1059 } catch (FormatException ex) {
1060 throw new FormatException (string.Format (CultureInfo.InvariantCulture,
1061 "Parameter value could not be converted from {0} to {1}.",
1062 valueType.Name, frameworkType.Name), ex);
1065 return sqlvalue;
1068 object ConvertToFrameworkType (object value, Type frameworkType)
1070 object sqlvalue = Convert.ChangeType (value, frameworkType);
1071 switch (sqlDbType) {
1072 case SqlDbType.Money:
1073 case SqlDbType.SmallMoney:
1074 sqlvalue = Decimal.Round ((decimal) sqlvalue, 4);
1075 break;
1077 return sqlvalue;
1080 public override void ResetDbType ()
1082 InferSqlType (Value);
1085 public void ResetSqlDbType ()
1087 InferSqlType (Value);
1090 #endregion // Methods