Question

I use IDataReader to call stored procedures without parameters. I am not finding examples of how to do this when parameters are present. Does IDataReader handle parameters of stored procedure?

Please provide an example.

Was it helpful?

Solution

If you're using the Enterprise Library, this style will work well for you:

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;

// ...

SqlDatabase db = new SqlDatabase("YourConnectionString");
DbCommand cmd = db.GetStoredProcCommand("YourProcName");
cmd.Parameters.Add(new SqlParameter("YourParamName", "param value"));

using (IDataReader dr = db.ExecuteReader(cmd))
{
    while (dr.Read())
    {
        // do something with the data
    }
}

OTHER TIPS

It's not the IDataReader that deals with parameters, that would be the IDbCommand (using the CreateParameter method). Then you can get hold of a reader for the command using the ExecuteReader method.

I put together a simple example:

private static void ExecuteCommand(IDbConnection conn)
{
    using (IDbCommand cmd = conn.CreateCommand())
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.CommandText = "ProcedureName";
        IDataParameter param = cmd.CreateParameter();
        param.ParameterName = "@parameterName";
        param.Value = "parameter value";
        cmd.Parameters.Add(param);
        using (IDataReader reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                // get data from the reader
            }
        }
    }
}

Some .NET providers have a static DeriveParameters() method in the command builder implementation. If so, you can use that to retrieve the list of parameters and then fill in the values. It provides a nice way of "discovering" the information:

IDbCommand cmd = conn.CreateCommand();

cmd.CommandText = "SomeProcedure";
cmd.CommandType = CommandType.StoredProcedure;

// to avoid hard coded reference to a specific provider type, get a
// command builder object and use reflection to invoke the derive method
DbCommandBuilder cb = dbfact.CreateCommandBuilder();
MethodInfo mi = cb.GetType().GetMethod( "DeriveParameters", 
                                 BindingFlags.Public | BindingFlags.Static );
mi.Invoke( null, new object[] { cmd } );
// show information about each parameter
foreach ( IDataParameter p in cmd.Parameters )
    Console.WriteLine( "{0}, {1}, {2}", p.ParameterName, 
                       p.DbType.ToString(), p.Direction.ToString() );
IDataParameter prm = (IDataParameter)cmd.Parameters["SomeParam"];
prm.Value = "xyz";
IDataReader rdr = cmd.ExecuteReader();

Below sample has worked for me (passing the parameter name only. I have only tried this for string parameters)

Using drDataReader As IDataReader = _db.ExecuteReader("usp_get_systemsetting", "ORSIniPath")
  Dim iIndex As Int32
  While (drDataReader.Read())
      iIndex = drDataReader.GetOrdinal("SETTING_CHAR")
      If drDataReader.IsDBNull(iIndex) Then
          g_sORSIniPath = ""
      Else
          g_sORSIniPath = drDataReader.GetString(i)
      End If
  End While
End Using
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top