Subscribe

RSS Feed (xml)

Execute SQL Command or Stored Procedure

The IDbCommand interface represents a database command, and each data provider includes a unique implementation. Here is the list of IDbCommand implementations for the five standard data providers.

  • System.Data.Odbc.OdbcCommand

  • System.Data.OleDb.OleDbCommand

  • System.Data.OracleClient.OracleCommand

  • System.Data.SqlServerCe.SqlCeCommand

  • System.Data.SqlClient.SqlCommand

To execute a command against a database you must have an open connection and a properly configured command object appropriate to the type of database you are accessing. You can create command objects directly using a constructor, but a simpler approach is to use the CreateCommand factory method of a connection object. The CreateCommand method returns a command object of the correct type for the data provider and configures it with basic information obtained from the connection you used to create the command. Before executing the command, you must configure the properties described in Table, which are common to all command implementations.

Table: Common Command Object Properties

Property

Description

CommandText

A string containing the text of the SQL command to execute or the name of a stored procedure. The content of the CommandText property must be compatible with the value you specify in the CommandType property.

CommandTimeout

An int that specifies the number of seconds to wait for the command to return before timing out and raising an exception. Defaults to 30 seconds.

CommandType

A value of the System.Data.CommandType enumeration that specifies the type of command represented by the command object. For most data providers, valid values are StoredProcedure, when you want to execute a stored procedure, and Text, when you want to execute a SQL text command. If you are using the OLE DB Data Provider, you can specify TableDirect when you want to return the entire contents of one or more tables; refer to the .NET Framework SDK documentation for more details. Defaults to Text.

Connection

An IDbConnection instance that provides the connection to the database on which you will execute the command. If you create the command using the IDbConnection.CreateCommand method, this property will be automatically set to the IDbConnection instance from which you created the command.

Parameters

A System.Data.IDataParameterCollection instance containing the set of parameters to substitute into the command.

Transaction

A System.Data.IDbTransaction instance representing the transaction into which to enlist the command. (See the .NET Framework SDK documentation for details about transactions.)

Once you have configured your command object, there are a number of ways to execute it depending on the nature of the command, the type of data returned by the command, and the format in which you want to process the data.

To execute a command, such as INSERT, DELETE, or CREATE TABLE, that doesn't return database data, call ExecuteNonQuery. For the UPDATE, INSERT, and DELETE commands, ExecuteNonQuery method returns an int that specifies the number of rows affected by the command. For other commands, such as CREATE TABLE, ExecuteNonQuery returns the value -1. Here is an example that uses UPDATE to modify a record.

public static void ExecuteNonQueryExample(IDbConnection con) {

    // Create and configure a new command.
    IDbCommand com = con.CreateCommand();
    com.CommandType = CommandType.Text;
    com.CommandText = "UPDATE Employees SET Title = 'Sales Director'" +
        " WHERE EmployeeId = '5'";

    // Execute the command and process the result.
    int result = com.ExecuteNonQuery();

    if (result == 1) {
        Console.WriteLine("Employee title updated.");
    } else {
        Console.WriteLine("Employee title not updated.");
    }
}

To execute a command that returns a result set, such as a SELECT statement or stored procedure, use the ExecuteReader method. ExecuteReader returns an IDataReader instance through which you have access to the result data. Most data providers also allow you to execute multiple SQL commands in a single call to the ExecuteReader method. This code excerpt uses the ExecuteReader method to execute the Ten Most Expensive Products stored procedure from the Northwind database and display the results to the console.

public static void ExecuteReaderExample(IDbConnection con) {

    // Create and configure a new command.
    IDbCommand com = con.CreateCommand();
    com.CommandType = CommandType.StoredProcedure;
    com.CommandText = "Ten Most Expensive Products";

    // Execute the command and process the results
    using (IDataReader reader = com.ExecuteReader()) {

        Console.WriteLine("Price of the Ten Most Expensive Products.");

        while (reader.Read()) {

            // Display the product details.
            Console.WriteLine("  {0} = {1}", 
                reader["TenMostExpensiveProducts"],
                reader["UnitPrice"]);
        }
    }
}

If you want to execute a query but only need the value from the first column of the first row of result data, use the ExecuteScalar method. The value is returned as an object reference that you must cast to the correct type. Here is an example.

public static void ExecuteScalarExample(IDbConnection con) {

    // Create and configure a new command.
    IDbCommand com = con.CreateCommand();
    com.CommandType = CommandType.Text;
    com.CommandText = "SELECT COUNT(*) FROM Employees";

    // Execute the command and cast the result.
    int result = (int)com.ExecuteScalar();

    Console.WriteLine("Employee count = " + result);
}

Connection Pooling

Connection pooling significantly reduces the overhead associated with creating and destroying database connections. Connection pooling also improves the scalability of solutions by reducing the number of concurrent connections a database must maintain-many of which sit idle for a significant portion of their lifetimes. With connection pooling, instead of creating and opening a new connection object whenever you need one, you take an already open connection from the connection pool. When you have finished using the connection, instead of closing it, you return it to the pool and allow other code to use it.

The SQL Server and Oracle data providers encapsulate connection- pooling functionality that they enable by default. One connection pool exists for each unique connection string you specify when you open a new connection. Each time you open a new connection with a connection string that you have used previously, the connection is taken from the existing pool. Only if you specify a different connection string will the data provider create a new connection pool. You can control some characteristics of your pool using the connection string settings described in below table.

Table: Connection String Settings That Control Connection Pooling

Setting

Description

Connection Lifetime

Specifies the maximum time in seconds that a connection is allowed to live in the pool before it's closed. The age of a connection is tested only when the connection is returned to the pool. This setting is useful for minimizing pool size if the pool isn't heavily used and also ensures optimal load balancing is achieved in clustered database environments. The default value is 0, which means connections exist for the life of the current process.

Connection Reset

Supported only by the SQL Server data provider. Specifies whether connections are reset as they are taken from the pool. A value of "True" ensures a connection's state is reset but requires an additional communication with the database. The default value is "True".

Max Pool Size

Specifies the maximum number of connections that should be in the pool. Connections are created and added to the pool as required until this figure is reached. If a request for a connection is made but there are no free connections, the caller will block until a connection becomes available. The default value is 100.

Min Pool Size

Specifies the minimum number of connections that should be in the pool. On pool creation, this number of connections are created and added to the pool. During periodic maintenance, or when a connection is requested, connections are added to the pool to ensure the minimum number of connections is available. The default value is 0.

Pooling

Set to "False" to obtain a non-pooled connection. The default value is "True".

This code excerpt from the sample code for this recipe demonstrates the configuration of a connection pool that contains a minimum of 5 and a maximum of 15 connections. Connections expire after 10 minutes (600 seconds) and are reset each time a connection is obtained from the pool.

// Obtain a pooled connection.
using (SqlConnection con = new SqlConnection()) {

    // Configure the SqlConnection object's connection string.
    con.ConnectionString = 
        "Data Source = localhost;" +    // local SQL Server instance
        "Database = Northwind;" +       // the sample Northwind DB
        "Integrated Security = SSPI;" + // integrated Windows security
        "Min Pool Size = 5;" +          // configure minimum pool size
        "Max Pool Size = 15;" +         // configure maximum pool size
        "Connection Reset = True;" +    // reset connections each use
        "Connection Lifetime = 600";    // set maximum connection lifetime

    // Open the Database connection.
    con.Open();

    // Access the database...
    

    // At the end of the using block, the Dispose calls Close, which
    // returns the connection to the pool for reuse.
}

This code excerpt demonstrates how to use the Pooling setting to obtain a connection object that isn't from a pool. This is useful if your application uses a single long-lived connection to a database.

// Obtain a non-pooled connection.
using (SqlConnection con = new SqlConnection()) {

    // Configure the SqlConnection object's connection string.
    con.ConnectionString = 
        "Data Source = localhost;" +    // local SQL Server instance
        "Database = Northwind;" +       // the sample Northwind DB
        "Integrated Security = SSPI;" + // integrated Windows security
        "Pooling = False";              // specify non-pooled connection

    // Open the Database connection.
    con.Open();

    // Access the database...
    

    // At the end of the using block, the Dispose calls Close, which
    // closes the non-pooled connection.
}

The ODBC and OLE DB data providers also support connection pooling, but they don't implement connection pooling within managed .NET classes and you don't configure the pool in the same way as for the SQL Server or Oracle data providers. ODBC connection pooling is managed by the ODBC Driver Manager and configured using the ODBC Data Source Administrator tool in the Control Panel. OLE DB connection pooling is managed by the native OLE DB implementation; the most you can do is disable pooling by including the setting "OLE DB Services=-4;" in your connection string. The SQL Server CE data provider doesn't support connection pooling because SQL Server CE supports only a single concurrent connection.

Connecting to Database

The first step in database access is to open a connection to the database. The IDbConnection interface represents a database connection, and each data provider includes a unique implementation. Here is the list of IDbConnection implementations for the five standard data providers.

  • System.Data.Odbc.OdbcConnection

  • System.Data.OleDb.OleDbConnection

  • System.Data.OracleClient.OracleConnection

  • System.Data.SqlServerCe.SqlCeConnection

  • System.Data.SqlClient.SqlConnection

You configure a connection object using a connection string. A connection string is a set of semicolon-separated name value pairs. You can supply a connection string either as a constructor argument or by setting a connection object's ConnectionString property before opening the connection. Each connection class implementation requires that you provide different information in the connection string. Refer to the ConnectionString property documentation for each implementation to see the values you can specify. Possible settings include the following:

  • The name of the target database server

  • The name of the database to open initially

  • Connection timeout values

  • Connection-pooling behavior

  • Authentication mechanisms to use when connecting to secured databases, including provision of user names and passwords

Once configured, call the connection object's Open method to open the connection to the database. You can then use the connection object to execute commands against the data source. The properties of a connection object also allow you to retrieve information about the state of a connection and the settings used to open the connection. When you're finished with a connection, you should always call its Close method to free up the underlying database connection and system resources. IDbConnection extends System.IDisposable, meaning that each connection class implements the Dispose method. Dispose automatically calls Close, making the using statement a very clean and efficient way of using connection objects in your code.

You achieve optimum scalability by opening your database connection as late as possible and closing it again as soon as you have finished. This ensures that you don't tie up database connections for long periods and give all code the maximum opportunity to obtain a connection. This is especially important if you are using connection pooling.

The code shown here demonstrates how to use the SqlConnection class to open a connection to a SQL Server database running on the local machine that uses integrated Windows security. To access a remote machine, simply change the data source name from localhost to the name of your database instance.

// Create an empty SqlConnection object.
using (SqlConnection con = new SqlConnection()) {

    // Configure the SqlConnection object's connection string.
    con.ConnectionString = 
        "Data Source = localhost;"+ // local SQL Server instance
        "Database = Northwind;" +   // the sample Northwind DB
        "Integrated Security=SSPI"; // integrated Windows security

    // Open the Database connection.
    con.Open();

    // Display information about the connection.
    if (con.State == ConnectionState.Open) {
        Console.WriteLine("SqlConnection Information:");
        Console.WriteLine("  Connection State = " + con.State);
        Console.WriteLine("  Connection String = " + 
            con.ConnectionString);
        Console.WriteLine("  Database Source = " + con.DataSource);
        Console.WriteLine("  Database = " + con.Database);
        Console.WriteLine("  Server Version = " + con.ServerVersion);
        Console.WriteLine("  Workstation Id = " + con.WorkstationId);
        Console.WriteLine("  Timeout = " + con.ConnectionTimeout);
        Console.WriteLine("  Packet Size = " + con.PacketSize);
    } else {
        Console.WriteLine("SqlConnection failed to open.");
        Console.WriteLine("  Connection State = " + con.State);
    }
    // At the end of the using block Dispose() calls Close().
}

As another example, the following program shows the connection string used to open a connection to the same database if you were using the OLE DB data provider to provide connectivity.

// Create an empty OleDbConnection object.
using (OleDbConnection con = new OleDbConnection()) {

    // Configure the OleDbConnection object's connection string.
    con.ConnectionString = 
        "Provider = SQLOLEDB;" +         // OLE DB Provider for SQL Server
        "Data Source = localhost;" +     // local SQL Server instance
        "Initial Catalog = Northwind;" + // the sample Northwind DB
        "Integrated Security=SSPI";      // integrated Windows security

    // Open the Database connection.
    con.Open();

}

LocalsAdda.com-Variety In Web World

Fun Mail - Fun in the Mail