SqlParameter.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. //
  2. // System.Data.SqlClient.SqlParameter.cs
  3. //
  4. // Author:
  5. // Rodrigo Moya ([email protected])
  6. // Daniel Morgan ([email protected])
  7. // Tim Coleman ([email protected])
  8. // Diego Caravana ([email protected])
  9. // Umadevi S ([email protected])
  10. // Amit Biswas ([email protected])
  11. //
  12. // (C) Ximian, Inc. 2002
  13. // Copyright (C) Tim Coleman, 2002
  14. //
  15. //
  16. // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
  17. //
  18. // Permission is hereby granted, free of charge, to any person obtaining
  19. // a copy of this software and associated documentation files (the
  20. // "Software"), to deal in the Software without restriction, including
  21. // without limitation the rights to use, copy, modify, merge, publish,
  22. // distribute, sublicense, and/or sell copies of the Software, and to
  23. // permit persons to whom the Software is furnished to do so, subject to
  24. // the following conditions:
  25. //
  26. // The above copyright notice and this permission notice shall be
  27. // included in all copies or substantial portions of the Software.
  28. //
  29. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  30. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  31. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  32. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  33. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  34. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  35. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  36. //
  37. using Mono.Data.Tds;
  38. using Mono.Data.Tds.Protocol;
  39. using System;
  40. using System.ComponentModel;
  41. using System.Data;
  42. using System.Data.Common;
  43. using System.Data.SqlTypes;
  44. using System.Runtime.InteropServices;
  45. using System.Text;
  46. namespace System.Data.SqlClient {
  47. [TypeConverterAttribute (typeof (SqlParameterConverter))]
  48. #if NET_2_0
  49. public sealed class SqlParameter : DbParameter, IDbDataParameter, IDataParameter, ICloneable
  50. #else
  51. public sealed class SqlParameter : MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable
  52. #endif // NET_2_0
  53. {
  54. #region Fields
  55. TdsMetaParameter metaParameter;
  56. SqlParameterCollection container = null;
  57. DbType dbType;
  58. ParameterDirection direction = ParameterDirection.Input;
  59. bool isNullable;
  60. bool isTypeSet = false;
  61. int offset;
  62. SqlDbType sqlDbType;
  63. string sourceColumn;
  64. DataRowVersion sourceVersion;
  65. SqlCompareOptions compareInfo;
  66. int localeId;
  67. Object sqlValue;
  68. string udtTypeName;
  69. #if NET_2_0
  70. bool sourceColumnNullMapping;
  71. string xmlSchemaCollectionDatabase = String.Empty;
  72. string xmlSchemaCollectionOwningSchema = String.Empty;
  73. string xmlSchemaCollectionName = String.Empty;
  74. #endif
  75. #endregion // Fields
  76. #region Constructors
  77. public SqlParameter ()
  78. : this (String.Empty, SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
  79. {
  80. isTypeSet = false;
  81. }
  82. public SqlParameter (string parameterName, object value)
  83. {
  84. metaParameter = new TdsMetaParameter (parameterName, value);
  85. InferSqlType (value);
  86. metaParameter.Value = SqlTypeToFrameworkType(value);
  87. this.sourceVersion = DataRowVersion.Current;
  88. }
  89. public SqlParameter (string parameterName, SqlDbType dbType)
  90. : this (parameterName, dbType, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
  91. {
  92. }
  93. public SqlParameter (string parameterName, SqlDbType dbType, int size)
  94. : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
  95. {
  96. }
  97. public SqlParameter (string parameterName, SqlDbType dbType, int size, string sourceColumn)
  98. : this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, sourceColumn, DataRowVersion.Current, null)
  99. {
  100. }
  101. [EditorBrowsable (EditorBrowsableState.Advanced)]
  102. public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
  103. {
  104. metaParameter = new TdsMetaParameter (parameterName, size,
  105. isNullable, precision,
  106. scale,
  107. value);
  108. if (dbType != SqlDbType.Variant)
  109. SqlDbType = dbType;
  110. metaParameter.Value = SqlTypeToFrameworkType (value);
  111. Direction = direction;
  112. SourceColumn = sourceColumn;
  113. SourceVersion = sourceVersion;
  114. }
  115. #if NET_2_0
  116. 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)
  117. : this (parameterName, dbType, size, direction, false, precision, scale, sourceColumn, sourceVersion, value)
  118. {
  119. XmlSchemaCollectionDatabase = xmlSchemaCollectionDatabase;
  120. XmlSchemaCollectionOwningSchema = xmlSchemaCollectionOwningSchema;
  121. XmlSchemaCollectionName = xmlSchemaCollectionName;
  122. SourceColumnNullMapping = sourceColumnNullMapping;
  123. }
  124. #endif
  125. // This constructor is used internally to construct a
  126. // SqlParameter. The value array comes from sp_procedure_params_rowset.
  127. // This is in SqlCommand.DeriveParameters.
  128. internal SqlParameter (object[] dbValues)
  129. : this (dbValues [3].ToString (), String.Empty)
  130. {
  131. Precision = 0;
  132. Scale = 0;
  133. Direction = ParameterDirection.Input;
  134. ParameterName = (string) dbValues[3];
  135. switch ((short) dbValues[5]) {
  136. case 1:
  137. Direction = ParameterDirection.Input;
  138. break;
  139. case 2:
  140. Direction = ParameterDirection.Output;
  141. break;
  142. case 3:
  143. Direction = ParameterDirection.InputOutput;
  144. break;
  145. case 4:
  146. Direction = ParameterDirection.ReturnValue;
  147. break;
  148. default:
  149. Direction = ParameterDirection.Input;
  150. break;
  151. }
  152. IsNullable = (dbValues [8] != null &&
  153. dbValues [8] != DBNull.Value) ? (bool) dbValues [8] : false;
  154. if (dbValues [12] != null && dbValues [12] != DBNull.Value)
  155. Precision = (byte) ((short) dbValues [12]);
  156. if (dbValues [13] != null && dbValues [13] != DBNull.Value)
  157. Scale = (byte) ( (short) dbValues [13]);
  158. SetDbTypeName ((string) dbValues [16]);
  159. }
  160. #endregion // Constructors
  161. #region Properties
  162. // Used to ensure that only one collection can contain this
  163. // parameter
  164. internal SqlParameterCollection Container {
  165. get { return container; }
  166. set { container = value; }
  167. }
  168. internal void CheckIfInitialized ()
  169. {
  170. if (!isTypeSet)
  171. throw new Exception ("all parameters to have an explicity set type");
  172. if (MetaParameter.IsVariableSizeType) {
  173. if (SqlDbType == SqlDbType.Decimal && Precision == 0)
  174. throw new Exception ("Parameter of type 'Decimal' have an explicitly set Precision and Scale");
  175. else if (Size == 0)
  176. throw new Exception ("all variable length parameters to have an explicitly set non-zero Size");
  177. }
  178. }
  179. #if ONLY_1_0 || ONLY_1_1
  180. [Browsable (false)]
  181. [DataSysDescription ("The parameter generic type.")]
  182. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  183. [RefreshProperties (RefreshProperties.All)]
  184. #endif
  185. [DataCategory ("Data")]
  186. public
  187. #if NET_2_0
  188. override
  189. #endif // NET_2_0
  190. DbType DbType {
  191. get { return dbType; }
  192. set {
  193. SetDbType (value);
  194. isTypeSet = true;
  195. }
  196. }
  197. [DataCategory ("Data")]
  198. #if ONLY_1_0 || ONLY_1_1
  199. [DataSysDescription ("Input, output, or bidirectional parameter.")]
  200. [DefaultValue (ParameterDirection.Input)]
  201. #endif
  202. #if NET_2_0
  203. [RefreshProperties (RefreshProperties.All)]
  204. #endif
  205. public
  206. #if NET_2_0
  207. override
  208. #endif // NET_2_0
  209. ParameterDirection Direction {
  210. get { return direction; }
  211. set {
  212. direction = value;
  213. switch( direction ) {
  214. case ParameterDirection.Output:
  215. MetaParameter.Direction = TdsParameterDirection.Output;
  216. break;
  217. case ParameterDirection.InputOutput:
  218. MetaParameter.Direction = TdsParameterDirection.InputOutput;
  219. break;
  220. case ParameterDirection.ReturnValue:
  221. MetaParameter.Direction = TdsParameterDirection.ReturnValue;
  222. break;
  223. }
  224. }
  225. }
  226. internal TdsMetaParameter MetaParameter {
  227. get { return metaParameter; }
  228. }
  229. #if ONLY_1_0 || ONLY_1_1
  230. [Browsable (false)]
  231. [DataSysDescription ("a design-time property used for strongly typed code-generation.")]
  232. [DefaultValue (false)]
  233. [DesignOnly (true)]
  234. [EditorBrowsable (EditorBrowsableState.Advanced)]
  235. #endif
  236. public
  237. #if NET_2_0
  238. override
  239. #endif // NET_2_0
  240. bool IsNullable {
  241. get { return metaParameter.IsNullable; }
  242. set { metaParameter.IsNullable = value; }
  243. }
  244. [Browsable (false)]
  245. [DataCategory ("Data")]
  246. #if ONLY_1_0 || ONLY_1_1
  247. [DataSysDescription ("Offset in variable length data types.")]
  248. [DefaultValue (0)]
  249. #endif
  250. #if NET_2_0
  251. [EditorBrowsable (EditorBrowsableState.Advanced)]
  252. #endif
  253. public int Offset {
  254. get { return offset; }
  255. set { offset = value; }
  256. }
  257. #if ONLY_1_0 || ONLY_1_1
  258. [DataSysDescription ("Name of the parameter, like '@p1'")]
  259. [DefaultValue ("")]
  260. #endif
  261. public
  262. #if NET_2_0
  263. override
  264. #endif // NET_2_0
  265. string ParameterName {
  266. get { return metaParameter.ParameterName; }
  267. set { metaParameter.ParameterName = value; }
  268. }
  269. [DataCategory ("Data")]
  270. [DefaultValue (0)]
  271. #if ONLY_1_0 || ONLY_1_1
  272. [DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
  273. #else
  274. [Browsable (false)]
  275. [EditorBrowsable (EditorBrowsableState.Never)]
  276. #endif
  277. public byte Precision {
  278. get { return metaParameter.Precision; }
  279. set { metaParameter.Precision = value; }
  280. }
  281. [DataCategory ("Data")]
  282. [DefaultValue (0)]
  283. #if ONLY_1_0 || ONLY_1_1
  284. [DataSysDescription ("For decimal, numeric, varnumeric DBTypes.")]
  285. #else
  286. [Browsable (false)]
  287. [EditorBrowsable (EditorBrowsableState.Never)]
  288. #endif
  289. public byte Scale {
  290. get { return metaParameter.Scale; }
  291. set { metaParameter.Scale = value; }
  292. }
  293. [DataCategory ("Data")]
  294. #if ONLY_1_0 || ONLY_1_1
  295. [DataSysDescription ("Size of variable length data types (string & arrays).")]
  296. [DefaultValue (0)]
  297. #endif
  298. public
  299. #if NET_2_0
  300. override
  301. #endif // NET_2_0
  302. int Size {
  303. get { return metaParameter.Size; }
  304. set { metaParameter.Size = value; }
  305. }
  306. [DataCategory ("Data")]
  307. #if ONLY_1_0 || ONLY_1_1
  308. [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.")]
  309. [DefaultValue ("")]
  310. #endif
  311. public
  312. #if NET_2_0
  313. override
  314. #endif // NET_2_0
  315. string SourceColumn {
  316. get { return sourceColumn; }
  317. set { sourceColumn = value; }
  318. }
  319. [DataCategory ("Data")]
  320. #if ONLY_1_0 || ONLY_1_1
  321. [DataSysDescription ("When used by a DataAdapter.Update (UpdateCommand only), the version of the DataRow value that is used to update the data source.")]
  322. [DefaultValue (DataRowVersion.Current)]
  323. #endif
  324. public
  325. #if NET_2_0
  326. override
  327. #endif // NET_2_0
  328. DataRowVersion SourceVersion {
  329. get { return sourceVersion; }
  330. set { sourceVersion = value; }
  331. }
  332. [DataCategory ("Data")]
  333. #if ONLY_1_0 || ONLY_1_1
  334. [DataSysDescription ("The parameter native type.")]
  335. [DefaultValue (SqlDbType.NVarChar)]
  336. #endif
  337. [RefreshProperties (RefreshProperties.All)]
  338. #if NET_2_0
  339. [DbProviderSpecificTypeProperty(true)]
  340. #endif
  341. public SqlDbType SqlDbType {
  342. get { return sqlDbType; }
  343. set {
  344. SetSqlDbType (value);
  345. isTypeSet = true;
  346. }
  347. }
  348. [DataCategory ("Data")]
  349. #if ONLY_1_0 || ONLY_1_1
  350. [DataSysDescription ("Value of the parameter.")]
  351. [DefaultValue (null)]
  352. #endif
  353. [TypeConverterAttribute (typeof (StringConverter))]
  354. #if NET_2_0
  355. [RefreshProperties (RefreshProperties.All)]
  356. #endif
  357. public
  358. #if NET_2_0
  359. override
  360. #endif // NET_2_0
  361. object Value {
  362. get { return metaParameter.Value; }
  363. set {
  364. if (!isTypeSet)
  365. InferSqlType (value);
  366. metaParameter.Value = SqlTypeToFrameworkType (value);
  367. }
  368. }
  369. #if NET_2_0
  370. [Browsable (false)]
  371. public SqlCompareOptions CompareInfo{
  372. get{ return compareInfo; }
  373. set{ compareInfo = value; }
  374. }
  375. [Browsable (false)]
  376. public int LocaleId {
  377. get { return localeId; }
  378. set { localeId = value; }
  379. }
  380. [Browsable (false)]
  381. [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
  382. public Object SqlValue {
  383. get { return sqlValue; }
  384. set { sqlValue = value; }
  385. }
  386. public override bool SourceColumnNullMapping {
  387. get { return sourceColumnNullMapping; }
  388. set { sourceColumnNullMapping = value; }
  389. }
  390. public string XmlSchemaCollectionDatabase {
  391. get { return xmlSchemaCollectionDatabase; }
  392. set { xmlSchemaCollectionDatabase = (value == null ? String.Empty : value); }
  393. }
  394. public string XmlSchemaCollectionName {
  395. get { return xmlSchemaCollectionName; }
  396. set {
  397. xmlSchemaCollectionName = (value == null ? String.Empty : value);
  398. }
  399. }
  400. public string XmlSchemaCollectionOwningSchema {
  401. get { return xmlSchemaCollectionOwningSchema; }
  402. set {
  403. xmlSchemaCollectionOwningSchema = (value == null ? String.Empty : value);
  404. }
  405. }
  406. #endif
  407. #endregion // Properties
  408. #region Methods
  409. object ICloneable.Clone ()
  410. {
  411. return new SqlParameter (ParameterName, SqlDbType, Size, Direction, IsNullable, Precision, Scale, SourceColumn, SourceVersion, Value);
  412. }
  413. // If the value is set without the DbType/SqlDbType being set, then we
  414. // infer type information.
  415. private void InferSqlType (object value)
  416. {
  417. if (value == null || value == DBNull.Value) {
  418. SetSqlDbType (SqlDbType.NVarChar);
  419. return;
  420. }
  421. Type type = value.GetType ();
  422. string exception = String.Format ("The parameter data type of {0} is invalid.", type.Name);
  423. switch (type.FullName) {
  424. case "System.Int64":
  425. case "System.Data.SqlTypes.SqlInt64":
  426. SetSqlDbType (SqlDbType.BigInt);
  427. break;
  428. case "System.Boolean":
  429. case "System.Data.SqlTypes.SqlBoolean":
  430. SetSqlDbType (SqlDbType.Bit);
  431. break;
  432. case "System.String":
  433. case "System.Data.SqlTypes.SqlString":
  434. SetSqlDbType (SqlDbType.NVarChar);
  435. break;
  436. case "System.DateTime":
  437. case "System.Data.SqlTypes.SqlDateTime":
  438. SetSqlDbType (SqlDbType.DateTime);
  439. break;
  440. case "System.Decimal":
  441. case "System.Data.SqlTypes.SqlDecimal":
  442. SetSqlDbType (SqlDbType.Decimal);
  443. break;
  444. case "System.Double":
  445. case "System.Data.SqlTypes.SqlDouble":
  446. SetSqlDbType (SqlDbType.Float);
  447. break;
  448. case "System.Byte[]":
  449. case "System.Data.SqlTypes.SqlBinary":
  450. SetSqlDbType (SqlDbType.VarBinary);
  451. break;
  452. case "System.Byte":
  453. case "System.Data.SqlTypes.SqlByte":
  454. SetSqlDbType (SqlDbType.TinyInt);
  455. break;
  456. case "System.Int32":
  457. case "System.Data.SqlTypes.SqlInt32":
  458. SetSqlDbType (SqlDbType.Int);
  459. break;
  460. case "System.Single":
  461. case "System.Data.SqlTypes.Single":
  462. SetSqlDbType (SqlDbType.Real);
  463. break;
  464. case "System.Int16":
  465. case "System.Data.SqlTypes.SqlInt16":
  466. SetSqlDbType (SqlDbType.SmallInt);
  467. break;
  468. case "System.Guid":
  469. case "System.Data.SqlTypes.SqlGuid":
  470. SetSqlDbType (SqlDbType.UniqueIdentifier);
  471. break;
  472. case "System.Money":
  473. case "System.SmallMoney":
  474. case "System.Data.SqlTypes.SqlMoney":
  475. SetSqlDbType (SqlDbType.Money);
  476. break;
  477. case "System.Object":
  478. SetSqlDbType (SqlDbType.Variant);
  479. break;
  480. default:
  481. throw new ArgumentException (exception);
  482. }
  483. }
  484. // When the DbType is set, we also set the SqlDbType, as well as the SQL Server
  485. // string representation of the type name. If the DbType is not convertible
  486. // to an SqlDbType, throw an exception.
  487. private void SetDbType (DbType type)
  488. {
  489. string exception = String.Format ("No mapping exists from DbType {0} to a known SqlDbType.", type);
  490. switch (type) {
  491. case DbType.AnsiString:
  492. MetaParameter.TypeName = "varchar";
  493. sqlDbType = SqlDbType.VarChar;
  494. MetaParameter.IsVariableSizeType = true;
  495. break;
  496. case DbType.AnsiStringFixedLength:
  497. MetaParameter.TypeName = "char";
  498. sqlDbType = SqlDbType.Char;
  499. MetaParameter.IsVariableSizeType = true;
  500. break;
  501. case DbType.Binary:
  502. MetaParameter.TypeName = "varbinary";
  503. sqlDbType = SqlDbType.VarBinary;
  504. MetaParameter.IsVariableSizeType = true;
  505. break;
  506. case DbType.Boolean:
  507. MetaParameter.TypeName = "bit";
  508. sqlDbType = SqlDbType.Bit;
  509. break;
  510. case DbType.Byte:
  511. MetaParameter.TypeName = "tinyint";
  512. sqlDbType = SqlDbType.TinyInt;
  513. break;
  514. case DbType.Currency:
  515. sqlDbType = SqlDbType.Money;
  516. MetaParameter.TypeName = "money";
  517. break;
  518. case DbType.Date:
  519. case DbType.DateTime:
  520. MetaParameter.TypeName = "datetime";
  521. sqlDbType = SqlDbType.DateTime;
  522. break;
  523. case DbType.Decimal:
  524. MetaParameter.TypeName = "decimal";
  525. sqlDbType = SqlDbType.Decimal;
  526. break;
  527. case DbType.Double:
  528. MetaParameter.TypeName = "float";
  529. sqlDbType = SqlDbType.Float;
  530. break;
  531. case DbType.Guid:
  532. MetaParameter.TypeName = "uniqueidentifier";
  533. sqlDbType = SqlDbType.UniqueIdentifier;
  534. break;
  535. case DbType.Int16:
  536. MetaParameter.TypeName = "smallint";
  537. sqlDbType = SqlDbType.SmallInt;
  538. break;
  539. case DbType.Int32:
  540. MetaParameter.TypeName = "int";
  541. sqlDbType = SqlDbType.Int;
  542. break;
  543. case DbType.Int64:
  544. MetaParameter.TypeName = "bigint";
  545. sqlDbType = SqlDbType.BigInt;
  546. break;
  547. case DbType.Object:
  548. MetaParameter.TypeName = "sql_variant";
  549. sqlDbType = SqlDbType.Variant;
  550. break;
  551. case DbType.Single:
  552. MetaParameter.TypeName = "real";
  553. sqlDbType = SqlDbType.Real;
  554. break;
  555. case DbType.String:
  556. MetaParameter.TypeName = "nvarchar";
  557. sqlDbType = SqlDbType.NVarChar;
  558. MetaParameter.IsVariableSizeType = true;
  559. break;
  560. case DbType.StringFixedLength:
  561. MetaParameter.TypeName = "nchar";
  562. sqlDbType = SqlDbType.NChar;
  563. MetaParameter.IsVariableSizeType = true;
  564. break;
  565. case DbType.Time:
  566. MetaParameter.TypeName = "datetime";
  567. sqlDbType = SqlDbType.DateTime;
  568. break;
  569. default:
  570. throw new ArgumentException (exception);
  571. }
  572. dbType = type;
  573. }
  574. // Used by internal constructor which has a SQL Server typename
  575. private void SetDbTypeName (string dbTypeName)
  576. {
  577. switch (dbTypeName.ToLower ()) {
  578. case "bigint":
  579. SqlDbType = SqlDbType.BigInt;
  580. break;
  581. case "binary":
  582. SqlDbType = SqlDbType.Binary;
  583. break;
  584. case "bit":
  585. SqlDbType = SqlDbType.Bit;
  586. break;
  587. case "char":
  588. SqlDbType = SqlDbType.Char;
  589. break;
  590. case "datetime":
  591. SqlDbType = SqlDbType.DateTime;
  592. break;
  593. case "decimal":
  594. SqlDbType = SqlDbType.Decimal;
  595. break;
  596. case "float":
  597. SqlDbType = SqlDbType.Float;
  598. break;
  599. case "image":
  600. SqlDbType = SqlDbType.Image;
  601. break;
  602. case "int":
  603. SqlDbType = SqlDbType.Int;
  604. break;
  605. case "money":
  606. SqlDbType = SqlDbType.Money;
  607. break;
  608. case "nchar":
  609. SqlDbType = SqlDbType.NChar;
  610. break;
  611. case "ntext":
  612. SqlDbType = SqlDbType.NText;
  613. break;
  614. case "nvarchar":
  615. SqlDbType = SqlDbType.NVarChar;
  616. break;
  617. case "real":
  618. SqlDbType = SqlDbType.Real;
  619. break;
  620. case "smalldatetime":
  621. SqlDbType = SqlDbType.SmallDateTime;
  622. break;
  623. case "smallint":
  624. SqlDbType = SqlDbType.SmallInt;
  625. break;
  626. case "smallmoney":
  627. SqlDbType = SqlDbType.SmallMoney;
  628. break;
  629. case "text":
  630. SqlDbType = SqlDbType.Text;
  631. break;
  632. case "timestamp":
  633. SqlDbType = SqlDbType.Timestamp;
  634. break;
  635. case "tinyint":
  636. SqlDbType = SqlDbType.TinyInt;
  637. break;
  638. case "uniqueidentifier":
  639. SqlDbType = SqlDbType.UniqueIdentifier;
  640. break;
  641. case "varbinary":
  642. SqlDbType = SqlDbType.VarBinary;
  643. break;
  644. case "varchar":
  645. SqlDbType = SqlDbType.VarChar;
  646. break;
  647. case "sql_variant":
  648. SqlDbType = SqlDbType.Variant;
  649. break;
  650. default:
  651. SqlDbType = SqlDbType.Variant;
  652. break;
  653. }
  654. }
  655. // When the SqlDbType is set, we also set the DbType, as well as the SQL Server
  656. // string representation of the type name. If the SqlDbType is not convertible
  657. // to a DbType, throw an exception.
  658. private void SetSqlDbType (SqlDbType type)
  659. {
  660. string exception = String.Format ("No mapping exists from SqlDbType {0} to a known DbType.", type);
  661. switch (type) {
  662. case SqlDbType.BigInt:
  663. MetaParameter.TypeName = "bigint";
  664. dbType = DbType.Int64;
  665. break;
  666. case SqlDbType.Binary:
  667. MetaParameter.TypeName = "binary";
  668. dbType = DbType.Binary;
  669. MetaParameter.IsVariableSizeType = true;
  670. break;
  671. case SqlDbType.Timestamp:
  672. MetaParameter.TypeName = "timestamp";
  673. dbType = DbType.Binary;
  674. break;
  675. case SqlDbType.VarBinary:
  676. MetaParameter.TypeName = "varbinary";
  677. dbType = DbType.Binary;
  678. MetaParameter.IsVariableSizeType = true;
  679. break;
  680. case SqlDbType.Bit:
  681. MetaParameter.TypeName = "bit";
  682. dbType = DbType.Boolean;
  683. break;
  684. case SqlDbType.Char:
  685. MetaParameter.TypeName = "char";
  686. dbType = DbType.AnsiStringFixedLength;
  687. MetaParameter.IsVariableSizeType = true;
  688. break;
  689. case SqlDbType.DateTime:
  690. MetaParameter.TypeName = "datetime";
  691. dbType = DbType.DateTime;
  692. break;
  693. case SqlDbType.SmallDateTime:
  694. MetaParameter.TypeName = "smalldatetime";
  695. dbType = DbType.DateTime;
  696. break;
  697. case SqlDbType.Decimal:
  698. MetaParameter.TypeName = "decimal";
  699. dbType = DbType.Decimal;
  700. break;
  701. case SqlDbType.Float:
  702. MetaParameter.TypeName = "float";
  703. dbType = DbType.Double;
  704. break;
  705. case SqlDbType.Image:
  706. MetaParameter.TypeName = "image";
  707. dbType = DbType.Binary;
  708. MetaParameter.IsVariableSizeType = true;
  709. break;
  710. case SqlDbType.Int:
  711. MetaParameter.TypeName = "int";
  712. dbType = DbType.Int32;
  713. break;
  714. case SqlDbType.Money:
  715. MetaParameter.TypeName = "money";
  716. dbType = DbType.Currency;
  717. break;
  718. case SqlDbType.SmallMoney:
  719. MetaParameter.TypeName = "smallmoney";
  720. dbType = DbType.Currency;
  721. break;
  722. case SqlDbType.NChar:
  723. MetaParameter.TypeName = "nchar";
  724. dbType = DbType.StringFixedLength;
  725. MetaParameter.IsVariableSizeType = true;
  726. break;
  727. case SqlDbType.NText:
  728. MetaParameter.TypeName = "ntext";
  729. dbType = DbType.String;
  730. MetaParameter.IsVariableSizeType = true;
  731. break;
  732. case SqlDbType.NVarChar:
  733. MetaParameter.TypeName = "nvarchar";
  734. dbType = DbType.String;
  735. MetaParameter.IsVariableSizeType = true;
  736. break;
  737. case SqlDbType.Real:
  738. MetaParameter.TypeName = "real";
  739. dbType = DbType.Single;
  740. break;
  741. case SqlDbType.SmallInt:
  742. MetaParameter.TypeName = "smallint";
  743. dbType = DbType.Int16;
  744. break;
  745. case SqlDbType.Text:
  746. MetaParameter.TypeName = "text";
  747. dbType = DbType.AnsiString;
  748. MetaParameter.IsVariableSizeType = true;
  749. break;
  750. case SqlDbType.VarChar:
  751. MetaParameter.TypeName = "varchar";
  752. dbType = DbType.AnsiString;
  753. MetaParameter.IsVariableSizeType = true;
  754. break;
  755. case SqlDbType.TinyInt:
  756. MetaParameter.TypeName = "tinyint";
  757. dbType = DbType.Byte;
  758. break;
  759. case SqlDbType.UniqueIdentifier:
  760. MetaParameter.TypeName = "uniqueidentifier";
  761. dbType = DbType.Guid;
  762. break;
  763. case SqlDbType.Variant:
  764. MetaParameter.TypeName = "sql_variant";
  765. dbType = DbType.Object;
  766. break;
  767. default:
  768. throw new ArgumentException (exception);
  769. }
  770. sqlDbType = type;
  771. }
  772. public override string ToString()
  773. {
  774. return ParameterName;
  775. }
  776. private object SqlTypeToFrameworkType (object value)
  777. {
  778. if (! (value is INullable)) // if the value is not SqlType
  779. return ConvertToFrameworkType (value);
  780. // Map to .net type, as Mono TDS respects only types from .net
  781. switch (value.GetType ().FullName) {
  782. case "System.Data.SqlTypes.SqlBinary":
  783. return ( (SqlBinary) value).Value;
  784. case "System.Data.SqlTypes.SqlBoolean":
  785. return ( (SqlBoolean) value).Value;
  786. case "System.Data.SqlTypes.SqlByte":
  787. return ( (SqlByte) value).Value;
  788. case "System.Data.SqlTypes.SqlDateTime":
  789. return ( (SqlDateTime) value).Value;
  790. case "System.Data.SqlTypes.SqlDecimal":
  791. return ( (SqlDecimal) value).Value;
  792. case "System.Data.SqlTypes.SqlDouble":
  793. return ( (SqlDouble) value).Value;
  794. case "System.Data.SqlTypes.SqlGuid":
  795. return ( (SqlGuid) value).Value;
  796. case "System.Data.SqlTypes.SqlInt16":
  797. return ( (SqlInt16) value).Value;
  798. case "System.Data.SqlTypes.SqlInt32 ":
  799. return ( (SqlInt32 ) value).Value;
  800. case "System.Data.SqlTypes.SqlInt64":
  801. return ( (SqlInt64) value).Value;
  802. case "System.Data.SqlTypes.SqlMoney":
  803. return ( (SqlMoney) value).Value;
  804. case "System.Data.SqlTypes.SqlSingle":
  805. return ( (SqlSingle) value).Value;
  806. case "System.Data.SqlTypes.SqlString":
  807. return ( (SqlString) value).Value;
  808. }
  809. return value;
  810. }
  811. private object ConvertToFrameworkType (object value)
  812. {
  813. if (value == null || value == DBNull.Value)
  814. return value;
  815. switch (sqlDbType) {
  816. case SqlDbType.BigInt :
  817. return Convert.ChangeType (value, typeof (Int64));
  818. case SqlDbType.Binary:
  819. case SqlDbType.VarBinary:
  820. if (value is byte[])
  821. return value;
  822. break;
  823. case SqlDbType.Bit:
  824. return Convert.ChangeType (value, typeof (bool));
  825. case SqlDbType.Int:
  826. return Convert.ChangeType (value, typeof (Int32));
  827. case SqlDbType.SmallInt :
  828. return Convert.ChangeType (value, typeof (Int16));
  829. case SqlDbType.TinyInt :
  830. return Convert.ChangeType (value, typeof (byte));
  831. case SqlDbType.Float:
  832. return Convert.ChangeType (value, typeof (Double));
  833. case SqlDbType.Real:
  834. return Convert.ChangeType (value, typeof (Single));
  835. case SqlDbType.Decimal:
  836. return Convert.ChangeType (value, typeof (Decimal));
  837. case SqlDbType.Money:
  838. case SqlDbType.SmallMoney:
  839. {
  840. Decimal val = (Decimal)Convert.ChangeType (value, typeof (Decimal));
  841. return Decimal.Round(val, 4);
  842. }
  843. case SqlDbType.DateTime:
  844. case SqlDbType.SmallDateTime:
  845. return Convert.ChangeType (value, typeof (DateTime));
  846. case SqlDbType.VarChar:
  847. case SqlDbType.NVarChar:
  848. case SqlDbType.Char:
  849. case SqlDbType.NChar:
  850. case SqlDbType.Text:
  851. case SqlDbType.NText:
  852. return Convert.ChangeType (value, typeof (string));
  853. case SqlDbType.UniqueIdentifier:
  854. return Convert.ChangeType (value, typeof (Guid));
  855. case SqlDbType.Variant:
  856. return metaParameter.Value;
  857. }
  858. throw new NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
  859. }
  860. #if NET_2_0
  861. public override void ResetDbType ()
  862. {
  863. InferSqlType (metaParameter.Value);
  864. }
  865. public void ResetSqlDbType ()
  866. {
  867. InferSqlType (metaParameter.Value);
  868. }
  869. #endif // NET_2_0
  870. #endregion // Methods
  871. }
  872. }