ADO - Connection.Execute vs Command.Execute

When to use Connection.Execute vs Command.Execute (deep dive)

Short answer up-front:

  • Use Connection.Execute for quick, one-off SQL statements (simple SELECT/UPDATE/INSERT/DELETE) where you don’t need parameters, output values, or repeated execution.

  • Use Command.Execute when you need parameterization, stored-procedure support, prepared statements, output/return parameters, command-level properties (timeout, prepared), or repeated execution for better safety and performance.

Below is a detailed comparison, examples, and best-practice checklist.


What each does

Connection.Execute

  • Method on the Connection object: Connection.Execute(CommandText, RecordsAffected, Options)

  • Runs a SQL string (or text that can be interpreted as SQL).

  • Fast and succinct for ad-hoc SQL.

  • No built-in parameters collection (you must build the SQL string or use positional ? placeholders with provider-specific behavior).

Command.Execute

  • Method on the Command object: Command.Execute(RecordsAffected, Parameters, Options)

  • The Command object exposes Parameters, CommandType, Prepared, CommandTimeout, and other properties.

  • Best for stored procedures, parameterized queries, prepared/repeated execution, output/return values.


Feature-by-feature comparison

  • Parameters

    • Connection.Execute: none (you must inline values or build SQL with ? in some providers — generally awkward and error-prone).

    • Command.Execute: full Parameters collection (CreateParameter, Append) — safe, prevents SQL injection.

  • Stored procedures & output params

    • Connection.Execute: possible by sending EXEC proc ... as text, but handling output params is clumsy or impossible directly.

    • Command.Execute: intended for adCmdStoredProc + parameters (input/output/return value).

  • Prepared statements / repeated execution

    • Connection.Execute: no Prepared support.

    • Command.Execute: cmd.Prepared = True prepares the statement once — faster for many repeated executions.

  • CommandType clarity

    • Connection.Execute: Options parameter can indicate type but usually you pass SQL text.

    • Command.Execute: cmd.CommandType (adCmdText, adCmdStoredProc, adCmdTable, etc.) — explicit and reliable.

  • CommandTimeout

    • Connection and Command both have timeout, but Command exposes it per-command (handy for long-running stored procs).

  • Transactions

    • Both work inside conn.BeginTrans / CommitTrans / RollbackTrans. (Use whichever you prefer; Command is often used inside transactions with stored procedures.)

  • Asynchronous execution

    • Both can support async options (provider-dependent). Use with care; more advanced.

  • Multiple resultsets

    • Both return a Recordset if a resultset is returned. Use rs.NextRecordset to iterate additional sets. Behavior can vary by provider.

  • Performance

    • For single simple statements: Connection.Execute is slightly simpler and minimal overhead.

    • For repeated/executed-often queries: Command with Prepared = True is significantly better.

  • Portability & provider quirks

    • Parameter placeholder behavior (? vs named) and Parameters.Refresh behavior depend on the OLE DB provider. Command is generally more portable when using proper CommandType.


Examples

1) Simple SELECT with Connection.Execute

Dim conn, rs
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open "Provider=SQLOLEDB;Data Source=MyServer;Initial Catalog=MyDB;User Id=sa;Password=pass;"

Set rs = conn.Execute("SELECT FirstName, LastName FROM Employees WHERE Department='Sales'")

Do Until rs.EOF
    Response.Write rs("FirstName") & " " & rs("LastName") & "<br>"
    rs.MoveNext
Loop
rs.Close
conn.Close

2) UPDATE with rows affected using Connection.Execute

Dim conn, rows
Set conn = Server.CreateObject("ADODB.Connection")
conn.Open connString

conn.Execute "UPDATE Employees SET Salary = Salary * 1.05 WHERE Department = 'Sales'", rows
Response.Write rows & " rows updated."
conn.Close

3) Stored procedure with input & output parameters using Command.Execute

Const adCmdStoredProc = 4
Const adInteger = 3
Const adVarChar = 200
Const adParamInput = 1
Const adParamOutput = 2

Dim conn, cmd, rs
Set conn = Server.CreateObject("ADODB.Connection")
Set cmd  = Server.CreateObject("ADODB.Command")
conn.Open connString

Set cmd.ActiveConnection = conn
cmd.CommandText = "usp_GetTotalEmployees"
cmd.CommandType = adCmdStoredProc

cmd.Parameters.Append cmd.CreateParameter("@Dept", adVarChar, adParamInput, 50, "Sales")
cmd.Parameters.Append cmd.CreateParameter("@Total", adInteger, adParamOutput)

Set rs = cmd.Execute()  ' if stored proc returns rows; otherwise rs may be Nothing

' Read output param
Response.Write "Total employees in Sales: " & cmd.Parameters("@Total").Value

If Not rs Is Nothing Then
    rs.Close
End If
conn.Close

4) Prepared command for repeated execution (performance)

Const adCmdText = 1
Const adInteger = 3
Const adParamInput = 1

Dim conn, cmd, i
Set conn = Server.CreateObject("ADODB.Connection")
Set cmd  = Server.CreateObject("ADODB.Command")
conn.Open connString

Set cmd.ActiveConnection = conn
cmd.CommandText = "INSERT INTO AuditLog(UserID, ActionDate) VALUES (?, ?)"
cmd.CommandType = adCmdText

' Create parameters (positional `?` placeholders) — provider rules apply
cmd.Parameters.Append cmd.CreateParameter("UserID", adInteger, adParamInput)
cmd.Parameters.Append cmd.CreateParameter("ActionDate", adDBTimeStamp, adParamInput)

cmd.Prepared = True  ' prepare once

For i = 1 To 1000
    cmd.Parameters("UserID").Value = i
    cmd.Parameters("ActionDate").Value = Now()
    cmd.Execute
Next

conn.Close

Note: The exact parameter naming/ordering behavior when using ? depends on the provider; named parameters with adCmdText may or may not be supported.


Error handling & diagnostics

  • Use On Error Resume Next then check If Err.Number <> 0 and inspect conn.Errors (Errors collection) after a failed command.

  • Command and Connection errors show up in Errors collection; check .Description, .Number, .Source.


Common pitfalls & advice

  1. SQL injection — never concatenate user input into SQL. Use Command + Parameters.

  2. Provider differences — parameter naming and placeholder support vary. Test with your provider (SQLOLEDB vs. SQLNCLI vs others).

  3. Parameters.Refresh — populates parameters from a stored proc automatically, but is slow and provider-dependent; prefer to create parameters explicitly.

  4. Remember to close recordsets and connections to avoid leaks (and rely on connection pooling for efficiency).

  5. For stored procedures with output params, use Command — handling outputs with Connection.Execute is awkward or impossible.

  6. Use cmd.Prepared = True when executing the same statement many times to reduce server parse overhead.

  7. When you don’t need parameters or reuse: Connection.Execute keeps code simple and readable.


Decision checklist (quick)

  • Do I need to pass parameters (safe, typed)? → Use Command

  • Do I need output/return parameters? → Use Command

  • Will I execute the same statement many times? → Use Command (Prepared)

  • Is this a one-off simple SELECT/UPDATE with no user input? → Connection.Execute is fine

  • Is this a stored procedure that returns values? → Use Command

  • Is performance for repeated operations important? → Use Command.Prepared

  • Convert any of the examples into your exact environment (SQL Server version, provider, or Classic ASP page), or

  • Show a full pattern with proper On Error handling and conn.Errors inspection, or

  • Produce a tiny cheat-sheet you can copy into your codebase.