SqlParameter.cs 26 KB

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