const int DEFAULT_COMMAND_TIMEOUT = 30;
- bool disposed;
int commandTimeout;
bool designTimeVisible;
string commandText;
SqlParameterCollection parameters;
string preparedStatement;
#if NET_2_0
+ bool disposed;
SqlNotificationRequest notification;
bool notificationAutoEnlist;
#endif
set {
if (value != commandText && preparedStatement != null)
Unprepare ();
- commandText = value;
+ commandText = value;
}
}
return new SqlParameter ();
}
+ private string EscapeProcName (string name, bool schema)
+ {
+ string procName;
+ string tmpProcName = name.Trim ();
+ int procNameLen = tmpProcName.Length;
+ char[] brkts = new char [] {'[', ']'};
+ bool foundMatching = false;
+ int start = 0, count = procNameLen;
+ int sindex = -1, eindex = -1;
+
+ // We try to match most of the "brackets" combination here, however
+ // there could be other combinations that may generate a different type
+ // of exception in MS.NET
+
+ if (procNameLen > 1) {
+ if ((sindex = tmpProcName.IndexOf ('[')) <= 0)
+ foundMatching = true;
+ else
+ foundMatching = false;
+
+ if (foundMatching == true && sindex > -1) {
+ eindex = tmpProcName.IndexOf (']');
+ if (sindex > eindex && eindex != -1) {
+ foundMatching = false;
+ } else if (eindex == procNameLen-1) {
+ if (tmpProcName.IndexOfAny (brkts, 1, procNameLen-2) != -1) {
+ foundMatching = false;
+ } else {
+ start = 1;
+ count = procNameLen - 2;
+ }
+ } else if (eindex == -1 && schema) {
+ foundMatching = true;
+ } else {
+ foundMatching = false;
+ }
+ }
+
+ if (foundMatching)
+ procName = tmpProcName.Substring (start, count);
+ else
+ throw new ArgumentException (String.Format ("SqlCommand.CommandText property value is an invalid multipart name {0}, incorrect usage of quotes", CommandText));
+ } else {
+ procName = tmpProcName;
+ }
+
+ return procName;
+ }
internal void DeriveParameters ()
{
if (commandType != CommandType.StoredProcedure)
string procName = CommandText;
string schemaName = String.Empty;
- int dotPosition = procName.IndexOf ('.');
+ int dotPosition = procName.LastIndexOf ('.');
+
+ // Procedure name can be: [database].[user].[procname]
if (dotPosition >= 0) {
schemaName = procName.Substring (0, dotPosition);
procName = procName.Substring (dotPosition + 1);
+ if ((dotPosition = schemaName.LastIndexOf ('.')) >= 0)
+ schemaName = schemaName.Substring (dotPosition + 1);
}
+ procName = EscapeProcName (procName, false);
+ schemaName = EscapeProcName (schemaName, true);
+
SqlParameterCollection localParameters = new SqlParameterCollection (this);
localParameters.Add ("@procedure_name", SqlDbType.NVarChar, procName.Length).Value = procName;
if (schemaName.Length > 0)
try {
Connection.Tds.ExecProc (sql, localParameters.MetaParameters, 0, true);
} catch (TdsTimeoutException ex) {
+ Connection.Tds.Reset ();
throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
} catch (TdsInternalException ex) {
Connection.Close ();
// 1) Network is down/server is down/not reachable
// 2) Somebody has an exclusive lock on Table/DB
// In any of these cases, don't close the connection. Let the user do it
+ Connection.Tds.Reset ();
throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
} catch (TdsInternalException ex) {
Connection.Close ();
try {
Connection.Tds.Execute (sql, parms, CommandTimeout, wantResults);
} catch (TdsTimeoutException ex) {
+ Connection.Tds.Reset ();
throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
} catch (TdsInternalException ex) {
Connection.Close ();
try {
Connection.Tds.ExecPrepared (preparedStatement, parms, CommandTimeout, wantResults);
} catch (TdsTimeoutException ex) {
- throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
+ Connection.Tds.Reset ();
+ throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
} catch (TdsInternalException ex) {
Connection.Close ();
throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
Execute (false);
result = Connection.Tds.RecordsAffected;
} catch (TdsTimeoutException e) {
+ Connection.Tds.Reset ();
throw SqlException.FromTdsInternalException ((TdsInternalException) e);
}
this.behavior = behavior;
if ((behavior & CommandBehavior.SequentialAccess) != 0)
Tds.SequentialAccess = true;
- Execute (true);
- Connection.DataReader = new SqlDataReader (this);
-
- return Connection.DataReader;
+ try {
+ Execute (true);
+ Connection.DataReader = new SqlDataReader (this);
+ return Connection.DataReader;
+ } catch {
+ if ((behavior & CommandBehavior.CloseConnection) != 0)
+ Connection.Close ();
+ throw;
+ }
}
public
GetOutputParameters ();
}
} catch (TdsTimeoutException ex) {
+ Connection.Tds.Reset ();
throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
} catch (TdsInternalException ex) {
Connection.Close ();
try {
Execute (true);
} catch (TdsTimeoutException e) {
+ Connection.Tds.Reset ();
throw SqlException.FromTdsInternalException ((TdsInternalException) e);
}
if (disposed) return;
if (disposing) {
parameters.Clear();
+ if (Connection != null)
+ Connection.DataReader = null;
}
base.Dispose (disposing);
disposed = true;
if (Connection.State != ConnectionState.Open)
throw new InvalidOperationException (String.Format ("{0} requires an open connection to continue. This connection is closed.", method));
if (CommandText.Length == 0)
- throw new InvalidOperationException ("The command text for this Command has not been set.");
+ throw new InvalidOperationException (String.Format ("{0}: CommandText has not been set for this Command.", method));
if (Connection.DataReader != null)
throw new InvalidOperationException ("There is already an open DataReader associated with this Connection which must be closed first.");
if (Connection.XmlReader != null)
callback,
state);
} catch (TdsTimeoutException ex) {
+ Connection.Tds.Reset ();
throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
} catch (TdsInternalException ex) {
Connection.Close ();
else
ar = Connection.Tds.BeginExecuteNonQuery (sql, parms, callback, state);
} catch (TdsTimeoutException ex) {
+ Connection.Tds.Reset ();
throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
} catch (TdsInternalException ex) {
Connection.Close ();
try {
Connection.Tds.ExecPrepared (preparedStatement, parms, CommandTimeout, wantResults);
} catch (TdsTimeoutException ex) {
+ Connection.Tds.Reset ();
throw SqlException.FromTdsInternalException ((TdsInternalException) ex);
} catch (TdsInternalException ex) {
Connection.Close ();