dbType.Binary and limit of 0-8000 bytes

C

Chukkalove

Can someone explain the following to me please, from the help files. I can't
understand what it means


DbType.Binary
Supported by the .NET Compact Framework.
A variable-length stream of binary data ranging between 1 and 8,000 bytes.
Note ADO.NET cannot correctly infer the type if the byte array is larger
than 8,000 bytes. Explicitly specify the DbType when working with byte
arrays larger than 8,000 bytes.

Its the "Explicitly specify the DbType when working with byte arrays larger
than 8,000 bytes." part that i cant understand.
Where is this specified, if im specifying it already for a byte array?

thanks
 
C

Cowboy \(Gregory A. Beamer\)

There is a byte array: byte[]
And there is the ADO.NET DbType for binary.

What it is stating is your must explicitly set a parameter to a
DBType.Binary instead of byte[] when you have a byte array larger than 8000
bytes.

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

*************************************************
Think outside of the box!
*************************************************
 
C

Chukkalove

Thank you for answering :)

I have a function with a switch statement that tests the type of an object
when it's passed to my IDbDataParameter constructing function and sets the
param.DbType accordingly.
If object type is byte[] I always set the parameter.DbType to DbType.Binary.
The help file isnt clear and may assume the reader already has knowledge.
Since writing this message, I was wondering if it's actually necessary to
set DbType at all unless you're creating a byte[] related parameter that's
over 8000 bytes in size. Is this true? And if so, then this part of the help
article should state that somewhere.

public void CreateParam(ref System.Data.IDbCommand command, string Name,
object value)
{
Hashtable data = Data;
// Add value to Data
data[Name.ToUpper()] = value;
IDbDataParameter Parm = command.CreateParameter();
Parm.ParameterName = Name;
if (value == null)
{
Parm.DbType = DbType.Object;
Parm.Value = null;
}
else
{
string str = value.GetType().ToString().ToUpper();
switch(str)
{
case "SYSTEM.UINT16" :parm.DbType = DbType.UInt16; break;
case "SYSTEM.UINT32" :parm.DbType = DbType.UInt32; break;
case "SYSTEM.DATETIME":parm.DbType = DbType.DateTime; break;
case "SYSTEM.STRING" :parm.DbType = DbType.AnsiString;break;
case "SYSTEM.BYTE" :parm.DbType = DbType.Byte; break;
case "SYSTEM.BYTE[]" :parm.DbType = DbType.Binary; break;
case "SYSTEM.SBYTE" :parm.DbType = DbType.SByte; break;
case "SYSTEM.INT32" :parm.DbType = DbType.Int32; break;
case "SYSTEM.SINGLE" :parm.DbType = DbType.Single; break;
case "SYSTEM.FLOAT" :parm.DbType = DbType.Single; break;
case "SYSTEM.DOUBLE" :parm.DbType = DbType.Double; break;
case "SYSTEM.BOOLEAN" :parm.DbType = DbType.Boolean; break;
// cnh When the value type is dbnull, you cant work out what type it is
// Setting type to DbType.Object seems to work ok
case "SYSTEM.DBNULL" :parm.DbType = DbType.Object; break;
default:throw new Exception("Type '" + str + "' missing from
BaseTable.CreateParam");
}
Parm.Value = value;
}// else
command.Parameters.Add(Parm);
}// function
 
C

Cowboy \(Gregory A. Beamer\)

Necessary? No, but explicit code has value other than necessity. If you set
the DbType on every parameter, you are showing exactly what you mean to the
person who has to take up the code when you leave.

Looking at the code you have, I assume you have a check to ensure the type
of the object is correct for the parameter somewhere else in the program.
For example, consider this stored procedure:

CREATE PROCEDURE dbo.TestMe
(
@myID int
, @myByteArray binary
)
AS

....

You could legally code this without compiler errrors:

byte[] byteArray = new byte[100];
int id = 1;

SqlCommand cmd = new SqlCommand(sqlString, conn);
CreateParam(cmd, "@myID", byteArray);
CreateParam(cmd, "@myByteArray", id);

This is the reason the MS blocks query sprocs and cache the parameter
collection. You then get a blow up before attempting a submit to the
database.

This is not a major deal overall, so don;t recode simply to add protection
on the code layer. :)

--
Gregory A. Beamer
MVP; MCP: +I, SE, SD, DBA

*************************************************
Think outside of the box!
*************************************************
Chukkalove said:
Thank you for answering :)

I have a function with a switch statement that tests the type of an
object when it's passed to my IDbDataParameter constructing function and
sets the param.DbType accordingly.
If object type is byte[] I always set the parameter.DbType to
DbType.Binary.
The help file isnt clear and may assume the reader already has knowledge.
Since writing this message, I was wondering if it's actually necessary to
set DbType at all unless you're creating a byte[] related parameter that's
over 8000 bytes in size. Is this true? And if so, then this part of the
help article should state that somewhere.

public void CreateParam(ref System.Data.IDbCommand command, string Name,
object value)
{
Hashtable data = Data;
// Add value to Data
data[Name.ToUpper()] = value;
IDbDataParameter Parm = command.CreateParameter();
Parm.ParameterName = Name;
if (value == null)
{
Parm.DbType = DbType.Object;
Parm.Value = null;
}
else
{
string str = value.GetType().ToString().ToUpper();
switch(str)
{
case "SYSTEM.UINT16" :parm.DbType = DbType.UInt16; break;
case "SYSTEM.UINT32" :parm.DbType = DbType.UInt32; break;
case "SYSTEM.DATETIME":parm.DbType = DbType.DateTime; break;
case "SYSTEM.STRING" :parm.DbType = DbType.AnsiString;break;
case "SYSTEM.BYTE" :parm.DbType = DbType.Byte; break;
case "SYSTEM.BYTE[]" :parm.DbType = DbType.Binary; break;
case "SYSTEM.SBYTE" :parm.DbType = DbType.SByte; break;
case "SYSTEM.INT32" :parm.DbType = DbType.Int32; break;
case "SYSTEM.SINGLE" :parm.DbType = DbType.Single; break;
case "SYSTEM.FLOAT" :parm.DbType = DbType.Single; break;
case "SYSTEM.DOUBLE" :parm.DbType = DbType.Double; break;
case "SYSTEM.BOOLEAN" :parm.DbType = DbType.Boolean; break;
// cnh When the value type is dbnull, you cant work out what type it is
// Setting type to DbType.Object seems to work ok
case "SYSTEM.DBNULL" :parm.DbType = DbType.Object; break;
default:throw new Exception("Type '" + str + "' missing from
BaseTable.CreateParam");
}
Parm.Value = value;
}// else
command.Parameters.Add(Parm);
}// function
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top