//Comm.Append (empty, 3, pad);
//byte[] version = {0x00, 0x0, 0x0, 0x71};
+ //Console.WriteLine ("Version: {0}", ClientVersion[3]);
Comm.Append (ClientVersion); // TDS Version 7
Comm.Append ((int)this.PacketSize); // Set the Block Size
Comm.Append (empty, 3, pad);
// Set "reset-connection" bit for the next message packet
Comm.ResetConnection = true;
-
+ base.Reset ();
return true;
}
public override void ExecPrepared (string commandText, TdsMetaParameterCollection parameters, int timeout, bool wantResults)
{
Parameters = parameters;
- ExecuteQuery (BuildPreparedQuery (commandText), timeout, wantResults);
+ if (Parameters != null && Parameters.Count > 0)
+ ExecRPC (TdsRpcProcId.ExecuteSql, commandText, parameters, timeout, wantResults);
+ else
+ ExecuteQuery (BuildPreparedQuery (commandText), timeout, wantResults);
}
public override void ExecProc (string commandText, TdsMetaParameterCollection parameters, int timeout, bool wantResults)
ExecRPC (commandText, parameters, timeout, wantResults);
}
- protected override void ExecRPC (string rpcName, TdsMetaParameterCollection parameters,
- int timeout, bool wantResults)
+ private void WriteRpcParameterInfo (TdsMetaParameterCollection parameters)
{
- // clean up
- InitExec ();
- Comm.StartPacket (TdsPacketType.RPC);
-
- Comm.Append ( (short) rpcName.Length);
- Comm.Append (rpcName);
- Comm.Append ( (short) 0); //no meta data
if (parameters != null) {
foreach (TdsMetaParameter param in parameters) {
if (param.Direction == TdsParameterDirection.ReturnValue)
WriteParameterInfo (param);
}
}
+ }
+
+ private void WritePreparedParameterInfo (TdsMetaParameterCollection parameters)
+ {
+ if (parameters == null)
+ return;
+
+ string param = BuildPreparedParameters ();
+ Comm.Append ((byte) 0x00); // no param meta data name
+ Comm.Append ((byte) 0x00); // no status flags
+
+ // Type_info - parameter info
+ WriteParameterInfo (new TdsMetaParameter ("prep_params",
+ param.Length > 4000 ? "ntext" : "nvarchar",
+ param));
+ }
+
+ private void ExecRPC (TdsRpcProcId rpcId, string sql,
+ TdsMetaParameterCollection parameters,
+ int timeout, bool wantResults)
+ {
+ // clean up
+ InitExec ();
+ Comm.StartPacket (TdsPacketType.RPC);
+
+ Comm.Append ((ushort) 0xFFFF);
+ Comm.Append ((ushort) rpcId);
+ Comm.Append ((short) 0x02); // no meta data
+
+ Comm.Append ((byte) 0x00); // no param meta data name
+ Comm.Append ((byte) 0x00); // no status flags
+
+ // Write sql as a parameter value - UCS2
+ TdsMetaParameter param = new TdsMetaParameter ("sql",
+ sql.Length > 4000 ? "ntext":"nvarchar",
+ sql);
+ WriteParameterInfo (param);
+
+ // Write Parameter infos - name and type
+ WritePreparedParameterInfo (parameters);
+
+ // Write parameter/value info
+ WriteRpcParameterInfo (parameters);
+ Comm.SendPacket ();
+ CheckForData (timeout);
+ if (!wantResults)
+ SkipToEnd ();
+ }
+
+ protected override void ExecRPC (string rpcName, TdsMetaParameterCollection parameters,
+ int timeout, bool wantResults)
+ {
+ // clean up
+ InitExec ();
+ Comm.StartPacket (TdsPacketType.RPC);
+
+ Comm.Append ( (short) rpcName.Length);
+ Comm.Append (rpcName);
+ Comm.Append ( (short) 0); //no meta data
+ WriteRpcParameterInfo (parameters);
Comm.SendPacket ();
CheckForData (timeout);
if (!wantResults)
TdsColumnType colType = param.GetMetaType ();
param.IsNullable = false;
- Comm.Append ((byte)colType); // type
-
+ bool partLenType = false;
int size = param.Size;
- if (size == 0)
+ if (size < 1) {
+ if (size < 0)
+ partLenType = true;
size = param.GetActualSize ();
+ }
- /*
- If column type is SqlDbType.NVarChar the size of parameter is multiplied by 2
- FIXME: Need to check for other types
+ // Change colType according to the following table
+ /*
+ * Original Type Maxlen New Type
+ *
+ * NVarChar 4000 UCS2 NText
+ * BigVarChar 8000 ASCII Text
+ * BigVarBinary 8000 bytes Image
+ *
*/
- if (colType == TdsColumnType.BigNVarChar)
- size <<= 1;
+ TdsColumnType origColType = colType;
+ if (colType == TdsColumnType.BigNVarChar) {
+ // param.GetActualSize() returns len*2
+ if (size == param.Size)
+ size <<= 1;
+ if ((size >> 1) > 4000)
+ colType = TdsColumnType.NText;
+ } else if (colType == TdsColumnType.BigVarChar) {
+ if (size > 8000)
+ colType = TdsColumnType.Text;
+ } else if (colType == TdsColumnType.BigVarBinary) {
+ if (size > 8000)
+ colType = TdsColumnType.Image;
+ }
+ // Calculation of TypeInfo field
+ /*
+ * orig size value TypeInfo field
+ *
+ * >= 0 <= Maxlen origColType + content len
+ * > Maxlen NewType as per above table + content len
+ * -1 origColType + USHORTMAXLEN (0xFFFF) + content len (TDS 9)
+ *
+ */
+ // Write updated colType, iff partLenType == false
+ if (TdsVersion > TdsVersion.tds81 && partLenType) {
+ Comm.Append ((byte)origColType);
+ Comm.Append ((short)-1);
+ } else if (ServerTdsVersion > TdsVersion.tds70
+ && origColType == TdsColumnType.Decimal) {
+ Comm.Append ((byte)TdsColumnType.Numeric);
+ } else {
+ Comm.Append ((byte)colType);
+ }
+
if (IsLargeType (colType))
Comm.Append ((short)size); // Parameter size passed in SqlParameter
else if (IsBlobType (colType))
// Precision and Scale are non-zero for only decimal/numeric
if ( param.TypeName == "decimal" || param.TypeName == "numeric") {
- Comm.Append ((param.Precision !=0 ) ? param.Precision : (byte) 28);
+ Comm.Append ((param.Precision !=0 ) ? param.Precision : (byte) 29);
Comm.Append (param.Scale);
+ // Convert the decimal value according to Scale
+ if (param.Value != null && param.Value != DBNull.Value &&
+ ((decimal)param.Value) != Decimal.MaxValue &&
+ ((decimal)param.Value) != Decimal.MinValue) {
+ decimal expo = new Decimal (System.Math.Pow (10, (double)param.Scale));
+ int pVal = (int)(((decimal)param.Value) * expo);
+ param.Value = (decimal)pVal;
+ }
}
+
+ /* VARADHAN: TDS 8 Debugging */
/*
- * VARADHAN: TDS 8 Debugging *
if (Collation != null) {
Console.WriteLine ("Collation is not null");
Console.WriteLine ("Column Type: {0}", colType);
Console.WriteLine ("Collation bytes: {0} {1} {2} {3} {4}", Collation[0], Collation[1], Collation[2],
Collation[3], Collation[4]);
+ } else {
+ Console.WriteLine ("Collation is null");
}
*/
colType == TdsColumnType.NVarChar || colType == TdsColumnType.Text ||
colType == TdsColumnType.NText))
Comm.Append (Collation);
-
- size = param.GetActualSize ();
+
+ // LAMESPEC: size should be 0xFFFF for any bigvarchar, bignvarchar and bigvarbinary
+ // types if param value is NULL
+ if ((colType == TdsColumnType.BigVarChar ||
+ colType == TdsColumnType.BigNVarChar ||
+ colType == TdsColumnType.BigVarBinary) &&
+ (param.Value == null || param.Value == DBNull.Value))
+ size = -1;
+ else
+ size = param.GetActualSize ();
+
if (IsLargeType (colType))
- Comm.Append ((short)size);
+ Comm.Append ((short)size);
else if (IsBlobType (colType))
- Comm.Append (size);
+ Comm.Append (size);
else
Comm.Append ((byte)size);
{
Parameters = parameters;
string sql = commandText;
- if (wantResults || (Parameters != null && Parameters.Count > 0))
- sql = BuildExec (commandText);
- ExecuteQuery (sql, timeout, wantResults);
+
+ if (Parameters != null && Parameters.Count > 0) {
+ ExecRPC (TdsRpcProcId.ExecuteSql, commandText, parameters, timeout, wantResults);
+ } else {
+ if (wantResults)
+ sql = BuildExec (commandText);
+ ExecuteQuery (sql, timeout, wantResults);
+ }
}
private string FormatParameter (TdsMetaParameter parameter)
//return ColumnValues [0].ToString ();
}
- protected override TdsDataColumnCollection ProcessColumnInfo ()
+ protected override void ProcessColumnInfo ()
{
- TdsDataColumnCollection result = new TdsDataColumnCollection ();
int numColumns = Comm.GetTdsShort ();
for (int i = 0; i < numColumns; i += 1) {
byte[] flagData = new byte[4];
string columnName = Comm.GetString (Comm.GetByte ());
TdsDataColumn col = new TdsDataColumn ();
- result.Add (col);
+ Columns.Add (col);
#if NET_2_0
col.ColumnType = columnType;
col.ColumnName = columnName;
col.IsReadOnly = !writable;
col.AllowDBNull = nullable;
col.BaseTableName = tableName;
+ col.DataTypeName = Enum.GetName (typeof (TdsColumnType), xColumnType);
#else
col ["ColumnType"] = columnType;
col ["ColumnName"] = columnName;
col ["IsReadOnly"] = !writable;
col ["AllowDBNull"] = nullable;
col ["BaseTableName"] = tableName;
+ col ["DataTypeName"] = Enum.GetName (typeof (TdsColumnType), xColumnType);
#endif
}
- return result;
}
public override void Unprepare (string statementId)