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)
9 // (C) Ximian, Inc. 2002
10 // Copyright (C) Tim Coleman, 2002
13 using Mono.Data.TdsClient.Internal;
15 using System.ComponentModel;
17 using System.Data.Common;
18 using System.Runtime.InteropServices;
21 namespace System.Data.SqlClient {
23 /// Represents a parameter to a Command object, and optionally,
24 /// its mapping to DataSet columns; and is implemented by .NET
25 /// data providers that access data sources.
27 public sealed class SqlParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
39 ParameterDirection direction = ParameterDirection.Input;
43 DataRowVersion sourceVersion;
51 public SqlParameter ()
52 : this (String.Empty, SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
56 public SqlParameter (string parameterName, object value)
58 this.parmName = parameterName;
59 this.objValue = value;
60 this.sourceVersion = DataRowVersion.Current;
61 SetType (value.GetType ());
64 public SqlParameter (string parameterName, SqlDbType dbType)
65 : this (parameterName, dbType, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
69 public SqlParameter (string parameterName, SqlDbType dbType, int size)
70 : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
74 public SqlParameter (string parameterName, SqlDbType dbType, int size, string sourceColumn)
75 : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, sourceColumn, DataRowVersion.Current, null)
79 [EditorBrowsable (EditorBrowsableState.Advanced)]
80 public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
82 this.parmName = parameterName;
84 this.sourceColumn = sourceColumn;
85 this.direction = direction;
86 this.isNullable = isNullable;
87 this.precision = precision;
89 this.sourceVersion = sourceVersion;
90 this.objValue = value;
94 internal SqlParameter (object[] dbValues)
98 direction = ParameterDirection.Input;
100 parmName = (string) dbValues[3];
102 switch ((short) dbValues[5]) {
104 direction = ParameterDirection.Input;
107 direction = ParameterDirection.Output;
110 direction = ParameterDirection.InputOutput;
113 direction = ParameterDirection.ReturnValue;
117 isNullable = (bool) dbValues[8];
119 if (dbValues[12] != null)
120 precision = (byte) ((short) dbValues[12]);
121 if (dbValues[13] != null)
122 scale = (byte) ((short) dbValues[13]);
124 SetDbTypeName ((string) dbValues[16]);
127 #endregion // Constructors
132 [DataCategory ("Data")]
133 [DataSysDescription ("The parameter generic type.")]
134 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
135 [RefreshProperties (RefreshProperties.All)]
136 public DbType DbType {
137 get { return dbType; }
138 set { SetDbType (value); }
141 [DataCategory ("Data")]
142 [DataSysDescription ("Input, output, or bidirectional parameter.")]
143 [DefaultValue (ParameterDirection.Input)]
144 public ParameterDirection Direction {
145 get { return direction; }
146 set { direction = value; }
149 string IDataParameter.ParameterName {
150 get { return parmName; }
151 set { parmName = value; }
155 [DataSysDescription ("a design-time property used for strongly typed code-generation.")]
156 [DefaultValue (false)]
158 [EditorBrowsable (EditorBrowsableState.Advanced)]
159 public bool IsNullable {
160 get { return isNullable; }
161 set { isNullable = value; }
165 [DataCategory ("Data")]
166 [DataSysDescription ("Offset in variable length data types.")]
169 get { return offset; }
170 set { offset = value; }
173 [DataSysDescription ("Name of the parameter, like '@p1'")]
175 public string ParameterName {
176 get { return parmName; }
177 set { parmName = value; }
180 [DataCategory ("Data")]
181 [DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
183 public byte Precision {
184 get { return precision; }
185 set { precision = value; }
188 [DataCategory ("Data")]
189 [DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
192 get { return scale; }
193 set { scale = value; }
196 [DataCategory ("Data")]
197 [DataSysDescription ("Size of variable length datatypes (strings & arrays).")]
207 [DataCategory ("Data")]
208 [DataSysDescription ("When used by a DataAdapter.Update, the source column name that is used to find the DataSetColumn name in the ColumnMappings. This is to copy a value between the parameter and a datarow.")]
210 public string SourceColumn {
211 get { return sourceColumn; }
212 set { sourceColumn = value; }
215 [DataCategory ("Data")]
216 [DataSysDescription ("When used by a DataAdapter.Update (UpdateCommand only), the version of the DataRow value that is used to update the data source.")]
217 [DefaultValue (DataRowVersion.Current)]
218 public DataRowVersion SourceVersion {
219 get { return sourceVersion; }
220 set { sourceVersion = value; }
223 [DataCategory ("Data")]
224 [DataSysDescription ("The parameter native type.")]
225 [DefaultValue (SqlDbType.NVarChar)]
226 [RefreshProperties (RefreshProperties.All)]
227 public SqlDbType SqlDbType {
228 get { return sqlDbType; }
229 set { SetSqlDbType (value); }
232 [DataCategory ("Data")]
233 [DataSysDescription ("Value of the parameter.")]
234 [DefaultValue (null)]
235 public object Value {
236 get { return objValue; }
237 set { objValue = value; }
240 #endregion // Properties
244 object ICloneable.Clone ()
246 return new SqlParameter (ParameterName, SqlDbType, Size, Direction, IsNullable, Precision, Scale, SourceColumn, SourceVersion, Value);
249 internal string Prepare (string name)
251 StringBuilder result = new StringBuilder ();
252 result.Append (name);
254 result.Append (typeName);
257 case SqlDbType.Image :
258 case SqlDbType.VarBinary :
259 case SqlDbType.NVarChar :
260 case SqlDbType.VarChar :
261 if (!sizeSet || size == 0)
262 throw new InvalidOperationException ("All variable length parameters must have an explicitly set non-zero size.");
264 result.Append (size.ToString ());
267 case SqlDbType.NChar :
268 case SqlDbType.Char :
269 case SqlDbType.Binary :
272 result.Append (size.ToString ());
276 case SqlDbType.Decimal :
277 case SqlDbType.Money :
278 case SqlDbType.SmallMoney :
280 result.Append (precision.ToString ());
282 result.Append (scale.ToString ());
289 return result.ToString ();
292 private void SetDbType (DbType type)
294 string exception = String.Format ("No mapping exists from DbType {0} to a known SqlDbType.", type);
297 case DbType.AnsiString:
298 sqlDbType = SqlDbType.VarChar;
300 case DbType.AnsiStringFixedLength:
301 sqlDbType = SqlDbType.Char;
304 sqlDbType = SqlDbType.VarBinary;
307 sqlDbType = SqlDbType.Bit;
310 sqlDbType = SqlDbType.TinyInt;
312 case DbType.Currency:
313 sqlDbType = SqlDbType.Money;
316 case DbType.DateTime:
317 sqlDbType = SqlDbType.DateTime;
320 sqlDbType = SqlDbType.Decimal;
323 sqlDbType = SqlDbType.Float;
326 sqlDbType = SqlDbType.UniqueIdentifier;
329 sqlDbType = SqlDbType.SmallInt;
332 sqlDbType = SqlDbType.Int;
335 sqlDbType = SqlDbType.BigInt;
338 sqlDbType = SqlDbType.Variant;
341 sqlDbType = SqlDbType.Real;
344 sqlDbType = SqlDbType.NVarChar;
346 case DbType.StringFixedLength:
347 sqlDbType = SqlDbType.NChar;
350 sqlDbType = SqlDbType.DateTime;
353 throw new ArgumentException (exception);
358 // Used by internal constructor which has a SQL Server typename
359 private void SetDbTypeName (string dbTypeName)
361 switch (dbTypeName.ToLower ()) {
363 SqlDbType = SqlDbType.BigInt;
366 SqlDbType = SqlDbType.Binary;
369 SqlDbType = SqlDbType.Bit;
372 SqlDbType = SqlDbType.Char;
375 SqlDbType = SqlDbType.DateTime;
378 SqlDbType = SqlDbType.Decimal;
381 SqlDbType = SqlDbType.Float;
384 SqlDbType = SqlDbType.Image;
387 SqlDbType = SqlDbType.Int;
390 SqlDbType = SqlDbType.Money;
393 SqlDbType = SqlDbType.NChar;
396 SqlDbType = SqlDbType.NText;
399 SqlDbType = SqlDbType.NVarChar;
402 SqlDbType = SqlDbType.Real;
404 case "smalldatetime":
405 SqlDbType = SqlDbType.SmallDateTime;
408 SqlDbType = SqlDbType.SmallInt;
411 SqlDbType = SqlDbType.SmallMoney;
414 SqlDbType = SqlDbType.Text;
417 SqlDbType = SqlDbType.Timestamp;
420 SqlDbType = SqlDbType.TinyInt;
422 case "uniqueidentifier":
423 SqlDbType = SqlDbType.UniqueIdentifier;
426 SqlDbType = SqlDbType.VarBinary;
429 SqlDbType = SqlDbType.VarChar;
432 SqlDbType = SqlDbType.Variant;
437 private void SetSqlDbType (SqlDbType type)
439 string exception = String.Format ("No mapping exists from SqlDbType {0} to a known DbType.", type);
442 case SqlDbType.BigInt:
444 dbType = DbType.Int64;
446 case SqlDbType.Binary:
448 dbType = DbType.Binary;
450 case SqlDbType.Timestamp:
451 typeName = "timestamp";
452 dbType = DbType.Binary;
454 case SqlDbType.VarBinary:
455 typeName = "varbinary";
456 dbType = DbType.Binary;
460 dbType = DbType.Boolean;
464 dbType = DbType.AnsiStringFixedLength;
466 case SqlDbType.DateTime:
467 typeName = "datetime";
468 dbType = DbType.DateTime;
470 case SqlDbType.SmallDateTime:
471 typeName = "smalldatetime";
472 dbType = DbType.DateTime;
474 case SqlDbType.Decimal:
475 typeName = "decimal";
476 dbType = DbType.Decimal;
478 case SqlDbType.Float:
480 dbType = DbType.Double;
482 case SqlDbType.Image:
484 dbType = DbType.Binary;
488 dbType = DbType.Int32;
490 case SqlDbType.Money:
492 dbType = DbType.Currency;
494 case SqlDbType.SmallMoney:
495 typeName = "smallmoney";
496 dbType = DbType.Currency;
498 case SqlDbType.NChar:
500 dbType = DbType.StringFixedLength;
502 case SqlDbType.NText:
504 dbType = DbType.String;
506 case SqlDbType.NVarChar:
507 typeName = "nvarchar";
508 dbType = DbType.String;
512 dbType = DbType.Single;
514 case SqlDbType.SmallInt:
515 typeName = "smallint";
516 dbType = DbType.Int16;
520 dbType = DbType.AnsiString;
522 case SqlDbType.VarChar:
523 typeName = "varchar";
524 dbType = DbType.AnsiString;
526 case SqlDbType.TinyInt:
527 typeName = "tinyint";
528 dbType = DbType.Byte;
530 case SqlDbType.UniqueIdentifier:
531 typeName = "uniqueidentifier";
532 dbType = DbType.Guid;
534 case SqlDbType.Variant:
535 typeName = "variant";
536 dbType = DbType.Object;
539 throw new ArgumentException (exception);
544 private void SetType (Type type)
546 string exception = String.Format ("The parameter data type of {0} is invalid.", type.Name);
548 switch (type.FullName) {
550 SetSqlDbType (SqlDbType.BigInt);
552 case "System.Boolean":
553 SetSqlDbType (SqlDbType.Bit);
555 case "System.String":
556 SetSqlDbType (SqlDbType.NVarChar);
558 case "System.DateTime":
559 SetSqlDbType (SqlDbType.DateTime);
561 case "System.Decimal":
562 SetSqlDbType (SqlDbType.Decimal);
564 case "System.Double":
565 SetSqlDbType (SqlDbType.Float);
567 case "System.Byte[]":
568 SetSqlDbType (SqlDbType.VarBinary);
571 SetSqlDbType (SqlDbType.TinyInt);
574 SetSqlDbType (SqlDbType.Int);
576 case "System.Single":
577 SetSqlDbType (SqlDbType.Real);
580 SetSqlDbType (SqlDbType.SmallInt);
583 SetSqlDbType (SqlDbType.UniqueIdentifier);
585 case "System.Object":
586 SetSqlDbType (SqlDbType.Variant);
589 throw new ArgumentException (exception);
593 public override string ToString()
598 #endregion // Methods