a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
1076 lines
30 KiB
C#
1076 lines
30 KiB
C#
//
|
|
// System.Data.SqlClient.SqlParameter.cs
|
|
//
|
|
// Author:
|
|
// Rodrigo Moya (rodrigo@ximian.com)
|
|
// Daniel Morgan (danmorg@sc.rr.com)
|
|
// Tim Coleman (tim@timcoleman.com)
|
|
// Diego Caravana (diego@toth.it)
|
|
// Umadevi S (sumadevi@novell.com)
|
|
// Amit Biswas (amit@amitbiswas.com)
|
|
// Veerapuram Varadhan (vvaradhan@novell.com)
|
|
//
|
|
// (C) Ximian, Inc. 2002
|
|
// Copyright (C) Tim Coleman, 2002
|
|
//
|
|
|
|
//
|
|
// Copyright (C) 2004, 2008, 2009 Novell, Inc (http://www.novell.com)
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
|
|
using Mono.Data.Tds;
|
|
using Mono.Data.Tds.Protocol;
|
|
using System;
|
|
using System.Collections;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Data.Common;
|
|
using System.Data.SqlTypes;
|
|
using System.Globalization;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Xml;
|
|
|
|
namespace System.Data.SqlClient {
|
|
[TypeConverterAttribute ("System.Data.SqlClient.SqlParameter+SqlParameterConverter, " + Consts.AssemblySystem_Data)]
|
|
public sealed class SqlParameter : DbParameter, IDbDataParameter, IDataParameter, ICloneable
|
|
{
|
|
#region Fields
|
|
|
|
TdsMetaParameter metaParameter;
|
|
|
|
SqlParameterCollection container;
|
|
DbType dbType;
|
|
ParameterDirection direction = ParameterDirection.Input;
|
|
bool isTypeSet;
|
|
int offset;
|
|
SqlDbType sqlDbType;
|
|
string sourceColumn;
|
|
DataRowVersion sourceVersion;
|
|
SqlCompareOptions compareInfo;
|
|
int localeId;
|
|
Type sqlType;
|
|
bool typeChanged;
|
|
bool sourceColumnNullMapping;
|
|
string xmlSchemaCollectionDatabase = String.Empty;
|
|
string xmlSchemaCollectionOwningSchema = String.Empty;
|
|
string xmlSchemaCollectionName = String.Empty;
|
|
|
|
static Hashtable type_mapping;
|
|
|
|
#endregion // Fields
|
|
|
|
#region Constructors
|
|
|
|
|
|
static SqlParameter ()
|
|
{
|
|
if (DbTypeMapping == null)
|
|
DbTypeMapping = new Hashtable ();
|
|
|
|
DbTypeMapping.Add (SqlDbType.BigInt, typeof (long));
|
|
DbTypeMapping.Add (SqlDbType.Bit, typeof (bool));
|
|
DbTypeMapping.Add (SqlDbType.Char, typeof (string));
|
|
DbTypeMapping.Add (SqlDbType.NChar, typeof (string));
|
|
DbTypeMapping.Add (SqlDbType.Text, typeof (string));
|
|
DbTypeMapping.Add (SqlDbType.NText, typeof (string));
|
|
DbTypeMapping.Add (SqlDbType.VarChar, typeof (string));
|
|
DbTypeMapping.Add (SqlDbType.NVarChar, typeof (string));
|
|
DbTypeMapping.Add (SqlDbType.SmallDateTime, typeof (DateTime));
|
|
DbTypeMapping.Add (SqlDbType.DateTime, typeof (DateTime));
|
|
DbTypeMapping.Add (SqlDbType.Decimal, typeof (decimal));
|
|
DbTypeMapping.Add (SqlDbType.Float, typeof (double));
|
|
DbTypeMapping.Add (SqlDbType.Binary, typeof (byte []));
|
|
DbTypeMapping.Add (SqlDbType.Image, typeof (byte []));
|
|
DbTypeMapping.Add (SqlDbType.Money, typeof (decimal));
|
|
DbTypeMapping.Add (SqlDbType.SmallMoney, typeof (decimal));
|
|
DbTypeMapping.Add (SqlDbType.VarBinary, typeof (byte []));
|
|
DbTypeMapping.Add (SqlDbType.TinyInt, typeof (byte));
|
|
DbTypeMapping.Add (SqlDbType.Int, typeof (int));
|
|
DbTypeMapping.Add (SqlDbType.Real, typeof (float));
|
|
DbTypeMapping.Add (SqlDbType.SmallInt, typeof (short));
|
|
DbTypeMapping.Add (SqlDbType.UniqueIdentifier, typeof (Guid));
|
|
DbTypeMapping.Add (SqlDbType.Variant, typeof (object));
|
|
DbTypeMapping.Add (SqlDbType.Xml, typeof (string));
|
|
|
|
type_mapping = new Hashtable ();
|
|
|
|
type_mapping.Add (typeof (long), SqlDbType.BigInt);
|
|
type_mapping.Add (typeof (SqlTypes.SqlInt64), SqlDbType.BigInt);
|
|
|
|
type_mapping.Add (typeof (bool), SqlDbType.Bit);
|
|
type_mapping.Add (typeof (SqlTypes.SqlBoolean), SqlDbType.Bit);
|
|
|
|
type_mapping.Add (typeof (char), SqlDbType.NVarChar);
|
|
type_mapping.Add (typeof (char []), SqlDbType.NVarChar);
|
|
type_mapping.Add (typeof (SqlTypes.SqlChars), SqlDbType.NVarChar);
|
|
|
|
type_mapping.Add (typeof (string), SqlDbType.NVarChar);
|
|
type_mapping.Add (typeof (SqlTypes.SqlString), SqlDbType.NVarChar);
|
|
|
|
type_mapping.Add (typeof (DateTime), SqlDbType.DateTime);
|
|
type_mapping.Add (typeof (SqlTypes.SqlDateTime), SqlDbType.DateTime);
|
|
|
|
type_mapping.Add (typeof (decimal), SqlDbType.Decimal);
|
|
type_mapping.Add (typeof (SqlTypes.SqlDecimal), SqlDbType.Decimal);
|
|
|
|
type_mapping.Add (typeof (double), SqlDbType.Float);
|
|
type_mapping.Add (typeof (SqlTypes.SqlDouble), SqlDbType.Float);
|
|
|
|
type_mapping.Add (typeof (byte []), SqlDbType.VarBinary);
|
|
type_mapping.Add (typeof (SqlTypes.SqlBinary), SqlDbType.VarBinary);
|
|
|
|
type_mapping.Add (typeof (SqlTypes.SqlBytes), SqlDbType.VarBinary);
|
|
|
|
type_mapping.Add (typeof (byte), SqlDbType.TinyInt);
|
|
type_mapping.Add (typeof (SqlTypes.SqlByte), SqlDbType.TinyInt);
|
|
|
|
type_mapping.Add (typeof (int), SqlDbType.Int);
|
|
type_mapping.Add (typeof (SqlTypes.SqlInt32), SqlDbType.Int);
|
|
|
|
type_mapping.Add (typeof (float), SqlDbType.Real);
|
|
type_mapping.Add (typeof (SqlTypes.SqlSingle), SqlDbType.Real);
|
|
|
|
type_mapping.Add (typeof (short), SqlDbType.SmallInt);
|
|
type_mapping.Add (typeof (SqlTypes.SqlInt16), SqlDbType.SmallInt);
|
|
|
|
type_mapping.Add (typeof (Guid), SqlDbType.UniqueIdentifier);
|
|
type_mapping.Add (typeof (SqlTypes.SqlGuid), SqlDbType.UniqueIdentifier);
|
|
|
|
type_mapping.Add (typeof (SqlTypes.SqlMoney), SqlDbType.Money);
|
|
|
|
type_mapping.Add (typeof (XmlReader), SqlDbType.Xml);
|
|
type_mapping.Add (typeof (SqlTypes.SqlXml), SqlDbType.Xml);
|
|
|
|
type_mapping.Add (typeof (object), SqlDbType.Variant);
|
|
}
|
|
|
|
public SqlParameter ()
|
|
: this (String.Empty, SqlDbType.NVarChar, 0, ParameterDirection.Input, false, 0, 0, String.Empty, DataRowVersion.Current, null)
|
|
{
|
|
isTypeSet = false;
|
|
}
|
|
|
|
public SqlParameter (string parameterName, object value)
|
|
{
|
|
if (parameterName == null)
|
|
parameterName = string.Empty;
|
|
metaParameter = new TdsMetaParameter (parameterName, GetFrameworkValue);
|
|
metaParameter.RawValue = value;
|
|
InferSqlType (value);
|
|
sourceVersion = DataRowVersion.Current;
|
|
}
|
|
|
|
public SqlParameter (string parameterName, SqlDbType dbType)
|
|
: this (parameterName, dbType, 0, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, null)
|
|
{
|
|
}
|
|
|
|
public SqlParameter (string parameterName, SqlDbType dbType, int size)
|
|
: this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, null, DataRowVersion.Current, null)
|
|
{
|
|
}
|
|
|
|
public SqlParameter (string parameterName, SqlDbType dbType, int size, string sourceColumn)
|
|
: this (parameterName, dbType, size, ParameterDirection.Input, false, 0, 0, sourceColumn, DataRowVersion.Current, null)
|
|
{
|
|
}
|
|
|
|
[EditorBrowsable (EditorBrowsableState.Advanced)]
|
|
public SqlParameter (string parameterName, SqlDbType dbType, int size, ParameterDirection direction, bool isNullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)
|
|
{
|
|
if (parameterName == null)
|
|
parameterName = string.Empty;
|
|
|
|
metaParameter = new TdsMetaParameter (parameterName, size,
|
|
isNullable, precision,
|
|
scale,
|
|
GetFrameworkValue);
|
|
metaParameter.RawValue = value;
|
|
if (dbType != SqlDbType.Variant)
|
|
SqlDbType = dbType;
|
|
Direction = direction;
|
|
SourceColumn = sourceColumn;
|
|
SourceVersion = sourceVersion;
|
|
}
|
|
|
|
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)
|
|
: this (parameterName, dbType, size, direction, false, precision, scale, sourceColumn, sourceVersion, value)
|
|
{
|
|
XmlSchemaCollectionDatabase = xmlSchemaCollectionDatabase;
|
|
XmlSchemaCollectionOwningSchema = xmlSchemaCollectionOwningSchema;
|
|
XmlSchemaCollectionName = xmlSchemaCollectionName;
|
|
SourceColumnNullMapping = sourceColumnNullMapping;
|
|
}
|
|
|
|
// This constructor is used internally to construct a
|
|
// SqlParameter. The value array comes from sp_procedure_params_rowset.
|
|
// This is in SqlCommand.DeriveParameters.
|
|
//
|
|
// http://social.msdn.microsoft.com/forums/en-US/transactsql/thread/900756fd-3980-48e3-ae59-a15d7fc15b4c/
|
|
internal SqlParameter (object[] dbValues)
|
|
: this (dbValues [3].ToString (), (object) null)
|
|
{
|
|
ParameterName = (string) dbValues [3];
|
|
|
|
switch ((short) dbValues [5]) {
|
|
case 1:
|
|
Direction = ParameterDirection.Input;
|
|
break;
|
|
case 2:
|
|
Direction = ParameterDirection.InputOutput;
|
|
break;
|
|
case 3:
|
|
Direction = ParameterDirection.Output;
|
|
break;
|
|
case 4:
|
|
Direction = ParameterDirection.ReturnValue;
|
|
break;
|
|
default:
|
|
Direction = ParameterDirection.Input;
|
|
break;
|
|
}
|
|
|
|
SqlDbType = (SqlDbType) FrameworkDbTypeFromName ((string) dbValues [16]);
|
|
|
|
if (MetaParameter.IsVariableSizeType) {
|
|
if (dbValues [10] != DBNull.Value)
|
|
Size = (int) dbValues [10];
|
|
}
|
|
|
|
if (SqlDbType == SqlDbType.Decimal) {
|
|
if (dbValues [12] != null && dbValues [12] != DBNull.Value)
|
|
Precision = (byte) ((short) dbValues [12]);
|
|
if (dbValues [13] != null && dbValues [13] != DBNull.Value)
|
|
Scale = (byte) ((short) dbValues [13]);
|
|
}
|
|
}
|
|
|
|
#endregion // Constructors
|
|
|
|
#region Properties
|
|
|
|
// Used to ensure that only one collection can contain this
|
|
// parameter
|
|
internal SqlParameterCollection Container {
|
|
get { return container; }
|
|
set { container = value; }
|
|
}
|
|
|
|
internal void CheckIfInitialized ()
|
|
{
|
|
if (!isTypeSet)
|
|
throw new Exception ("all parameters to have an explicity set type");
|
|
|
|
if (MetaParameter.IsVariableSizeType) {
|
|
if (SqlDbType == SqlDbType.Decimal && Precision == 0)
|
|
throw new Exception ("Parameter of type 'Decimal' have an explicitly set Precision and Scale");
|
|
else if (Size == 0)
|
|
throw new Exception ("all variable length parameters to have an explicitly set non-zero Size");
|
|
}
|
|
}
|
|
|
|
public override DbType DbType {
|
|
get { return dbType; }
|
|
set {
|
|
SetDbType (value);
|
|
typeChanged = true;
|
|
isTypeSet = true;
|
|
}
|
|
}
|
|
|
|
[RefreshProperties (RefreshProperties.All)]
|
|
public override
|
|
ParameterDirection Direction {
|
|
get { return direction; }
|
|
set {
|
|
direction = value;
|
|
switch( direction ) {
|
|
case ParameterDirection.Output:
|
|
MetaParameter.Direction = TdsParameterDirection.Output;
|
|
break;
|
|
case ParameterDirection.InputOutput:
|
|
MetaParameter.Direction = TdsParameterDirection.InputOutput;
|
|
break;
|
|
case ParameterDirection.ReturnValue:
|
|
MetaParameter.Direction = TdsParameterDirection.ReturnValue;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
internal TdsMetaParameter MetaParameter {
|
|
get { return metaParameter; }
|
|
}
|
|
|
|
public override bool IsNullable {
|
|
get { return metaParameter.IsNullable; }
|
|
set { metaParameter.IsNullable = value; }
|
|
}
|
|
|
|
[Browsable (false)]
|
|
[EditorBrowsable (EditorBrowsableState.Advanced)]
|
|
public int Offset {
|
|
get { return offset; }
|
|
set { offset = value; }
|
|
}
|
|
|
|
public override string ParameterName {
|
|
get { return metaParameter.ParameterName; }
|
|
set {
|
|
if (value == null)
|
|
value = string.Empty;
|
|
metaParameter.ParameterName = value;
|
|
}
|
|
}
|
|
|
|
[DefaultValue (0)]
|
|
public byte Precision {
|
|
get { return metaParameter.Precision; }
|
|
set { metaParameter.Precision = value; }
|
|
}
|
|
|
|
[DefaultValue (0)]
|
|
public byte Scale {
|
|
get { return metaParameter.Scale; }
|
|
set { metaParameter.Scale = value; }
|
|
}
|
|
|
|
public override int Size {
|
|
get { return metaParameter.Size; }
|
|
set { metaParameter.Size = value; }
|
|
}
|
|
|
|
public override string SourceColumn {
|
|
get {
|
|
if (sourceColumn == null)
|
|
return string.Empty;
|
|
return sourceColumn;
|
|
}
|
|
set { sourceColumn = value; }
|
|
}
|
|
|
|
public override DataRowVersion SourceVersion {
|
|
get { return sourceVersion; }
|
|
set { sourceVersion = value; }
|
|
}
|
|
|
|
[RefreshProperties (RefreshProperties.All)]
|
|
[DbProviderSpecificTypeProperty(true)]
|
|
public SqlDbType SqlDbType {
|
|
get { return sqlDbType; }
|
|
set {
|
|
SetSqlDbType (value);
|
|
typeChanged = true;
|
|
isTypeSet = true;
|
|
}
|
|
}
|
|
|
|
[TypeConverterAttribute (typeof (StringConverter))]
|
|
[RefreshProperties (RefreshProperties.All)]
|
|
public override object Value {
|
|
get {
|
|
if (sqlType != null)
|
|
return GetSqlValue (metaParameter.RawValue);
|
|
return metaParameter.RawValue;
|
|
}
|
|
set {
|
|
if (!isTypeSet) {
|
|
InferSqlType (value);
|
|
}
|
|
|
|
if (value is INullable) {
|
|
sqlType = value.GetType ();
|
|
value = SqlTypeToFrameworkType (value);
|
|
}
|
|
metaParameter.RawValue = value;
|
|
}
|
|
}
|
|
|
|
[Browsable (false)]
|
|
public SqlCompareOptions CompareInfo{
|
|
get{ return compareInfo; }
|
|
set{ compareInfo = value; }
|
|
}
|
|
|
|
[Browsable (false)]
|
|
public int LocaleId {
|
|
get { return localeId; }
|
|
set { localeId = value; }
|
|
}
|
|
|
|
[Browsable (false)]
|
|
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
|
|
public Object SqlValue {
|
|
get {
|
|
return GetSqlValue (metaParameter.RawValue);
|
|
}
|
|
set {
|
|
Value = value;
|
|
}
|
|
}
|
|
|
|
public override bool SourceColumnNullMapping {
|
|
get { return sourceColumnNullMapping; }
|
|
set { sourceColumnNullMapping = value; }
|
|
}
|
|
|
|
public string XmlSchemaCollectionDatabase {
|
|
get { return xmlSchemaCollectionDatabase; }
|
|
set { xmlSchemaCollectionDatabase = (value == null ? String.Empty : value); }
|
|
}
|
|
|
|
public string XmlSchemaCollectionName {
|
|
get { return xmlSchemaCollectionName; }
|
|
set {
|
|
xmlSchemaCollectionName = (value == null ? String.Empty : value);
|
|
}
|
|
}
|
|
|
|
public string XmlSchemaCollectionOwningSchema {
|
|
get { return xmlSchemaCollectionOwningSchema; }
|
|
set {
|
|
xmlSchemaCollectionOwningSchema = (value == null ? String.Empty : value);
|
|
}
|
|
}
|
|
|
|
[BrowsableAttribute(false)]
|
|
public string UdtTypeName { get; set; }
|
|
|
|
#endregion // Properties
|
|
|
|
#region Methods
|
|
|
|
object ICloneable.Clone ()
|
|
{
|
|
return new SqlParameter (ParameterName, SqlDbType, Size, Direction, IsNullable, Precision, Scale, SourceColumn, SourceVersion, Value);
|
|
}
|
|
|
|
// If the value is set without the DbType/SqlDbType being set, then we
|
|
// infer type information.
|
|
void InferSqlType (object value)
|
|
{
|
|
if (value == null || value == DBNull.Value) {
|
|
SetSqlDbType (SqlDbType.NVarChar);
|
|
return;
|
|
}
|
|
|
|
Type type = value.GetType ();
|
|
if (type.IsEnum)
|
|
type = Enum.GetUnderlyingType (type);
|
|
object t = type_mapping [type];
|
|
if (t == null)
|
|
throw new ArgumentException (String.Format ("The parameter data type of {0} is invalid.", type.FullName));
|
|
SetSqlDbType ((SqlDbType) t);
|
|
}
|
|
|
|
// Returns System.Type corresponding to the underlying SqlDbType
|
|
internal override Type SystemType {
|
|
get {
|
|
return (Type) DbTypeMapping [sqlDbType];
|
|
}
|
|
}
|
|
|
|
internal override object FrameworkDbType {
|
|
get {
|
|
return sqlDbType;
|
|
}
|
|
|
|
set {
|
|
object t;
|
|
try {
|
|
t = (DbType) DbTypeFromName ((string)value);
|
|
SetDbType ((DbType)t);
|
|
} catch (ArgumentException) {
|
|
t = (SqlDbType)FrameworkDbTypeFromName ((string)value);
|
|
SetSqlDbType ((SqlDbType) t);
|
|
}
|
|
}
|
|
}
|
|
|
|
DbType DbTypeFromName (string name)
|
|
{
|
|
switch (name.ToLower ()) {
|
|
case "ansistring":
|
|
return DbType.AnsiString;
|
|
case "ansistringfixedlength":
|
|
return DbType.AnsiStringFixedLength;
|
|
case "binary":
|
|
return DbType.Binary;
|
|
case "boolean":
|
|
return DbType.Boolean;
|
|
case "byte":
|
|
return DbType.Byte;
|
|
case "currency":
|
|
return DbType.Currency;
|
|
case "date":
|
|
return DbType.Date;
|
|
case "datetime":
|
|
return DbType.DateTime;
|
|
case "decimal":
|
|
return DbType.Decimal;
|
|
case "double":
|
|
return DbType.Double;
|
|
case "guid":
|
|
return DbType.Guid;
|
|
case "int16":
|
|
return DbType.Int16;
|
|
case "int32":
|
|
return DbType.Int32;
|
|
case "int64":
|
|
return DbType.Int64;
|
|
case "object":
|
|
return DbType.Object;
|
|
case "single":
|
|
return DbType.Single;
|
|
case "string":
|
|
return DbType.String;
|
|
case "stringfixedlength":
|
|
return DbType.StringFixedLength;
|
|
case "time":
|
|
return DbType.Time;
|
|
case "xml":
|
|
return DbType.Xml;
|
|
default:
|
|
string exception = String.Format ("No mapping exists from {0} to a known DbType.", name);
|
|
throw new ArgumentException (exception);
|
|
}
|
|
}
|
|
|
|
// When the DbType is set, we also set the SqlDbType, as well as the SQL Server
|
|
// string representation of the type name. If the DbType is not convertible
|
|
// to an SqlDbType, throw an exception.
|
|
private void SetDbType (DbType type)
|
|
{
|
|
switch (type) {
|
|
case DbType.AnsiString:
|
|
MetaParameter.TypeName = "varchar";
|
|
sqlDbType = SqlDbType.VarChar;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case DbType.AnsiStringFixedLength:
|
|
MetaParameter.TypeName = "char";
|
|
sqlDbType = SqlDbType.Char;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case DbType.Binary:
|
|
MetaParameter.TypeName = "varbinary";
|
|
sqlDbType = SqlDbType.VarBinary;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case DbType.Boolean:
|
|
MetaParameter.TypeName = "bit";
|
|
sqlDbType = SqlDbType.Bit;
|
|
break;
|
|
case DbType.Byte:
|
|
MetaParameter.TypeName = "tinyint";
|
|
sqlDbType = SqlDbType.TinyInt;
|
|
break;
|
|
case DbType.Currency:
|
|
sqlDbType = SqlDbType.Money;
|
|
MetaParameter.TypeName = "money";
|
|
break;
|
|
case DbType.Date:
|
|
case DbType.DateTime:
|
|
MetaParameter.TypeName = "datetime";
|
|
sqlDbType = SqlDbType.DateTime;
|
|
break;
|
|
case DbType.DateTime2:
|
|
MetaParameter.TypeName = "datetime2";
|
|
sqlDbType = SqlDbType.DateTime2;
|
|
break;
|
|
case DbType.Decimal:
|
|
MetaParameter.TypeName = "decimal";
|
|
sqlDbType = SqlDbType.Decimal;
|
|
break;
|
|
case DbType.Double:
|
|
MetaParameter.TypeName = "float";
|
|
sqlDbType = SqlDbType.Float;
|
|
break;
|
|
case DbType.Guid:
|
|
MetaParameter.TypeName = "uniqueidentifier";
|
|
sqlDbType = SqlDbType.UniqueIdentifier;
|
|
break;
|
|
case DbType.Int16:
|
|
MetaParameter.TypeName = "smallint";
|
|
sqlDbType = SqlDbType.SmallInt;
|
|
break;
|
|
case DbType.Int32:
|
|
MetaParameter.TypeName = "int";
|
|
sqlDbType = SqlDbType.Int;
|
|
break;
|
|
case DbType.Int64:
|
|
MetaParameter.TypeName = "bigint";
|
|
sqlDbType = SqlDbType.BigInt;
|
|
break;
|
|
case DbType.Object:
|
|
MetaParameter.TypeName = "sql_variant";
|
|
sqlDbType = SqlDbType.Variant;
|
|
break;
|
|
case DbType.Single:
|
|
MetaParameter.TypeName = "real";
|
|
sqlDbType = SqlDbType.Real;
|
|
break;
|
|
case DbType.String:
|
|
MetaParameter.TypeName = "nvarchar";
|
|
sqlDbType = SqlDbType.NVarChar;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case DbType.StringFixedLength:
|
|
MetaParameter.TypeName = "nchar";
|
|
sqlDbType = SqlDbType.NChar;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case DbType.Time:
|
|
MetaParameter.TypeName = "datetime";
|
|
sqlDbType = SqlDbType.DateTime;
|
|
break;
|
|
// Handle Xml type as string
|
|
case DbType.Xml:
|
|
MetaParameter.TypeName = "xml";
|
|
sqlDbType = SqlDbType.Xml;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
default:
|
|
string exception = String.Format ("No mapping exists from DbType {0} to a known SqlDbType.", type);
|
|
throw new ArgumentException (exception);
|
|
}
|
|
dbType = type;
|
|
}
|
|
|
|
// Used by internal constructor which has a SQL Server typename
|
|
private SqlDbType FrameworkDbTypeFromName (string dbTypeName)
|
|
{
|
|
switch (dbTypeName.ToLower ()) {
|
|
case "bigint":
|
|
return SqlDbType.BigInt;
|
|
case "binary":
|
|
return SqlDbType.Binary;
|
|
case "bit":
|
|
return SqlDbType.Bit;
|
|
case "char":
|
|
return SqlDbType.Char;
|
|
case "datetime":
|
|
return SqlDbType.DateTime;
|
|
case "decimal":
|
|
return SqlDbType.Decimal;
|
|
case "float":
|
|
return SqlDbType.Float;
|
|
case "image":
|
|
return SqlDbType.Image;
|
|
case "int":
|
|
return SqlDbType.Int;
|
|
case "money":
|
|
return SqlDbType.Money;
|
|
case "nchar":
|
|
return SqlDbType.NChar;
|
|
case "ntext":
|
|
return SqlDbType.NText;
|
|
case "nvarchar":
|
|
return SqlDbType.NVarChar;
|
|
case "real":
|
|
return SqlDbType.Real;
|
|
case "smalldatetime":
|
|
return SqlDbType.SmallDateTime;
|
|
case "smallint":
|
|
return SqlDbType.SmallInt;
|
|
case "smallmoney":
|
|
return SqlDbType.SmallMoney;
|
|
case "text":
|
|
return SqlDbType.Text;
|
|
case "timestamp":
|
|
return SqlDbType.Timestamp;
|
|
case "tinyint":
|
|
return SqlDbType.TinyInt;
|
|
case "uniqueidentifier":
|
|
return SqlDbType.UniqueIdentifier;
|
|
case "varbinary":
|
|
return SqlDbType.VarBinary;
|
|
case "varchar":
|
|
return SqlDbType.VarChar;
|
|
case "sql_variant":
|
|
return SqlDbType.Variant;
|
|
case "xml":
|
|
return SqlDbType.Xml;
|
|
default:
|
|
return SqlDbType.Variant;
|
|
}
|
|
}
|
|
|
|
// When the SqlDbType is set, we also set the DbType, as well as the SQL Server
|
|
// string representation of the type name. If the SqlDbType is not convertible
|
|
// to a DbType, throw an exception.
|
|
internal void SetSqlDbType (SqlDbType type)
|
|
{
|
|
switch (type) {
|
|
case SqlDbType.BigInt:
|
|
MetaParameter.TypeName = "bigint";
|
|
dbType = DbType.Int64;
|
|
break;
|
|
case SqlDbType.Binary:
|
|
MetaParameter.TypeName = "binary";
|
|
dbType = DbType.Binary;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case SqlDbType.Timestamp:
|
|
MetaParameter.TypeName = "timestamp";
|
|
dbType = DbType.Binary;
|
|
break;
|
|
case SqlDbType.VarBinary:
|
|
MetaParameter.TypeName = "varbinary";
|
|
dbType = DbType.Binary;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case SqlDbType.Bit:
|
|
MetaParameter.TypeName = "bit";
|
|
dbType = DbType.Boolean;
|
|
break;
|
|
case SqlDbType.Char:
|
|
MetaParameter.TypeName = "char";
|
|
dbType = DbType.AnsiStringFixedLength;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case SqlDbType.DateTime:
|
|
MetaParameter.TypeName = "datetime";
|
|
dbType = DbType.DateTime;
|
|
break;
|
|
case SqlDbType.SmallDateTime:
|
|
MetaParameter.TypeName = "smalldatetime";
|
|
dbType = DbType.DateTime;
|
|
break;
|
|
case SqlDbType.Decimal:
|
|
MetaParameter.TypeName = "decimal";
|
|
dbType = DbType.Decimal;
|
|
break;
|
|
case SqlDbType.Float:
|
|
MetaParameter.TypeName = "float";
|
|
dbType = DbType.Double;
|
|
break;
|
|
case SqlDbType.Image:
|
|
MetaParameter.TypeName = "image";
|
|
dbType = DbType.Binary;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case SqlDbType.Int:
|
|
MetaParameter.TypeName = "int";
|
|
dbType = DbType.Int32;
|
|
break;
|
|
case SqlDbType.Money:
|
|
MetaParameter.TypeName = "money";
|
|
dbType = DbType.Currency;
|
|
break;
|
|
case SqlDbType.SmallMoney:
|
|
MetaParameter.TypeName = "smallmoney";
|
|
dbType = DbType.Currency;
|
|
break;
|
|
case SqlDbType.NChar:
|
|
MetaParameter.TypeName = "nchar";
|
|
dbType = DbType.StringFixedLength;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case SqlDbType.NText:
|
|
MetaParameter.TypeName = "ntext";
|
|
dbType = DbType.String;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case SqlDbType.NVarChar:
|
|
MetaParameter.TypeName = "nvarchar";
|
|
dbType = DbType.String;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case SqlDbType.Real:
|
|
MetaParameter.TypeName = "real";
|
|
dbType = DbType.Single;
|
|
break;
|
|
case SqlDbType.SmallInt:
|
|
MetaParameter.TypeName = "smallint";
|
|
dbType = DbType.Int16;
|
|
break;
|
|
case SqlDbType.Text:
|
|
MetaParameter.TypeName = "text";
|
|
dbType = DbType.AnsiString;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case SqlDbType.VarChar:
|
|
MetaParameter.TypeName = "varchar";
|
|
dbType = DbType.AnsiString;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
case SqlDbType.TinyInt:
|
|
MetaParameter.TypeName = "tinyint";
|
|
dbType = DbType.Byte;
|
|
break;
|
|
case SqlDbType.UniqueIdentifier:
|
|
MetaParameter.TypeName = "uniqueidentifier";
|
|
dbType = DbType.Guid;
|
|
break;
|
|
case SqlDbType.Variant:
|
|
MetaParameter.TypeName = "sql_variant";
|
|
dbType = DbType.Object;
|
|
break;
|
|
case SqlDbType.Xml:
|
|
MetaParameter.TypeName = "xml";
|
|
dbType = DbType.Xml;
|
|
MetaParameter.IsVariableSizeType = true;
|
|
break;
|
|
default:
|
|
string exception = String.Format ("No mapping exists from SqlDbType {0} to a known DbType.", type);
|
|
throw new ArgumentOutOfRangeException ("SqlDbType", exception);
|
|
}
|
|
sqlDbType = type;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return ParameterName;
|
|
}
|
|
|
|
object GetFrameworkValue (object rawValue, ref bool updated)
|
|
{
|
|
object tdsValue;
|
|
|
|
updated = typeChanged || updated;
|
|
if (updated) {
|
|
tdsValue = SqlTypeToFrameworkType (rawValue);
|
|
typeChanged = false;
|
|
} else
|
|
tdsValue = null;
|
|
return tdsValue;
|
|
}
|
|
|
|
// TODO: Code copied from SqlDataReader, need a better approach
|
|
object GetSqlValue (object value)
|
|
{
|
|
if (value == null)
|
|
return value;
|
|
switch (sqlDbType) {
|
|
case SqlDbType.BigInt:
|
|
if (value == DBNull.Value)
|
|
return SqlInt64.Null;
|
|
return (SqlInt64) ((long) value);
|
|
case SqlDbType.Binary:
|
|
case SqlDbType.Image:
|
|
case SqlDbType.VarBinary:
|
|
case SqlDbType.Timestamp:
|
|
if (value == DBNull.Value)
|
|
return SqlBinary.Null;
|
|
return (SqlBinary) (byte[]) value;
|
|
case SqlDbType.Bit:
|
|
if (value == DBNull.Value)
|
|
return SqlBoolean.Null;
|
|
return (SqlBoolean) ((bool) value);
|
|
case SqlDbType.Char:
|
|
case SqlDbType.NChar:
|
|
case SqlDbType.NText:
|
|
case SqlDbType.NVarChar:
|
|
case SqlDbType.Text:
|
|
case SqlDbType.VarChar:
|
|
if (value == DBNull.Value)
|
|
return SqlString.Null;
|
|
|
|
string str;
|
|
Type type = value.GetType ();
|
|
if (type == typeof (char))
|
|
str = value.ToString ();
|
|
else if (type == typeof (char[]))
|
|
str = new String ((char[])value);
|
|
else
|
|
str = ((string)value);
|
|
return (SqlString) str;
|
|
case SqlDbType.DateTime:
|
|
case SqlDbType.SmallDateTime:
|
|
if (value == DBNull.Value)
|
|
return SqlDateTime.Null;
|
|
return (SqlDateTime) ((DateTime) value);
|
|
case SqlDbType.Decimal:
|
|
if (value == DBNull.Value)
|
|
return SqlDecimal.Null;
|
|
if (value is TdsBigDecimal)
|
|
return SqlDecimal.FromTdsBigDecimal ((TdsBigDecimal) value);
|
|
return (SqlDecimal) ((decimal) value);
|
|
case SqlDbType.Float:
|
|
if (value == DBNull.Value)
|
|
return SqlDouble.Null;
|
|
return (SqlDouble) ((double) value);
|
|
case SqlDbType.Int:
|
|
if (value == DBNull.Value)
|
|
return SqlInt32.Null;
|
|
return (SqlInt32) ((int) value);
|
|
case SqlDbType.Money:
|
|
case SqlDbType.SmallMoney:
|
|
if (value == DBNull.Value)
|
|
return SqlMoney.Null;
|
|
return (SqlMoney) ((decimal) value);
|
|
case SqlDbType.Real:
|
|
if (value == DBNull.Value)
|
|
return SqlSingle.Null;
|
|
return (SqlSingle) ((float) value);
|
|
case SqlDbType.UniqueIdentifier:
|
|
if (value == DBNull.Value)
|
|
return SqlGuid.Null;
|
|
return (SqlGuid) ((Guid) value);
|
|
case SqlDbType.SmallInt:
|
|
if (value == DBNull.Value)
|
|
return SqlInt16.Null;
|
|
return (SqlInt16) ((short) value);
|
|
case SqlDbType.TinyInt:
|
|
if (value == DBNull.Value)
|
|
return SqlByte.Null;
|
|
return (SqlByte) ((byte) value);
|
|
case SqlDbType.Xml:
|
|
if (value == DBNull.Value)
|
|
return SqlXml.Null;
|
|
return (SqlXml) value;
|
|
default:
|
|
throw new NotImplementedException ("Type '" + sqlDbType + "' not implemented.");
|
|
}
|
|
}
|
|
|
|
object SqlTypeToFrameworkType (object value)
|
|
{
|
|
INullable nullable = value as INullable;
|
|
if (nullable == null)
|
|
return ConvertToFrameworkType (value);
|
|
|
|
if (nullable.IsNull)
|
|
return DBNull.Value;
|
|
|
|
Type type = value.GetType ();
|
|
// Map to .net type, as Mono TDS respects only types from .net
|
|
|
|
if (typeof (SqlString) == type) {
|
|
return ((SqlString) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlInt16) == type) {
|
|
return ((SqlInt16) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlInt32) == type) {
|
|
return ((SqlInt32) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlDateTime) == type) {
|
|
return ((SqlDateTime) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlInt64) == type) {
|
|
return ((SqlInt64) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlBinary) == type) {
|
|
return ((SqlBinary) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlBytes) == type) {
|
|
return ((SqlBytes) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlChars) == type) {
|
|
return ((SqlChars) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlBoolean) == type) {
|
|
return ((SqlBoolean) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlByte) == type) {
|
|
return ((SqlByte) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlDecimal) == type) {
|
|
return ((SqlDecimal) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlDouble) == type) {
|
|
return ((SqlDouble) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlGuid) == type) {
|
|
return ((SqlGuid) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlMoney) == type) {
|
|
return ((SqlMoney) value).Value;
|
|
}
|
|
|
|
if (typeof (SqlSingle) == type) {
|
|
return ((SqlSingle) value).Value;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
internal object ConvertToFrameworkType (object value)
|
|
{
|
|
if (value == null || value == DBNull.Value)
|
|
return value;
|
|
if (sqlDbType == SqlDbType.Variant)
|
|
return metaParameter.Value;
|
|
|
|
Type frameworkType = SystemType;
|
|
if (frameworkType == null)
|
|
throw new NotImplementedException ("Type Not Supported : " + sqlDbType.ToString());
|
|
|
|
Type valueType = value.GetType ();
|
|
if (valueType == frameworkType)
|
|
return value;
|
|
|
|
object sqlvalue = null;
|
|
|
|
try {
|
|
sqlvalue = ConvertToFrameworkType (value, frameworkType);
|
|
} catch (FormatException ex) {
|
|
throw new FormatException (string.Format (CultureInfo.InvariantCulture,
|
|
"Parameter value could not be converted from {0} to {1}.",
|
|
valueType.Name, frameworkType.Name), ex);
|
|
}
|
|
|
|
return sqlvalue;
|
|
}
|
|
|
|
object ConvertToFrameworkType (object value, Type frameworkType)
|
|
{
|
|
object sqlvalue = Convert.ChangeType (value, frameworkType);
|
|
switch (sqlDbType) {
|
|
case SqlDbType.Money:
|
|
case SqlDbType.SmallMoney:
|
|
sqlvalue = Decimal.Round ((decimal) sqlvalue, 4);
|
|
break;
|
|
}
|
|
return sqlvalue;
|
|
}
|
|
|
|
public override void ResetDbType ()
|
|
{
|
|
InferSqlType (Value);
|
|
}
|
|
|
|
public void ResetSqlDbType ()
|
|
{
|
|
InferSqlType (Value);
|
|
}
|
|
|
|
#endregion // Methods
|
|
}
|
|
}
|