Programmatically Retrieving a Stored Procedure's Parameters 获取Sql Server 存储过程参数

原文

 

Introduction


Stored procedures in SQL Server are similar to methods in C# and Visual Basic code. They encapsulate one or more statements into a single, parameterized construct. Both stored procedures and methods are a form of code reuse and their use help developers adhere to the DRY principle ( Don't Repeat Yourself). But the similarities don't end there. The .NET Framework has a feature called Reflection that enables developers to programmatically retrieve a list of methods for a given class, along with their input parameters and return types. It's also possible to programmatically determine what stored procedures exist in a database, along with each stored procedure's input and output parameters.

Being able to programmatically retrieve a database's stored procedures and determine their parameters are useful in a handful of scenarios. For example, code generators like CodeSmith and the Typed DataSet feature in Visual Studio use these techniques to determine the code to construct to call each stored procedure. These techniques are also useful for allowing ad-hoc stored procedure execution from a page on your website, which can be a useful tool for administrators.

This article shows how to retrieve a list of stored procedures in a database and how to enumerate a selected stored procedure's input and output parameters. We'll also look at how to let the user visiting the page pick a stored procedure, enter values for its parameters, and execute and view the resulting output. Read on to learn more!

 

An Overview of the Demo Application


The download available at the end of this article includes a web page with a DropDownList Web control enumerating the stored procedures in the website's database. Selecting a stored procedure form the DropDownList causes a postback. On postback the stored procedure's input and output parameters are each displayed in a BulletedList control. In addition, the input parameters are listed in a two-column GridView: the first column lists each parameter's name, while the second has a TextBox control. The user visiting the page can enter values for the input parameters into these TextBoxes and then click the "Execute Stored Procedure" Button. Doing so displays the results in another GridView further down on the page.

The following screen shot shows this demo page in action.

Programmatically Retrieving a Stored Procedure's Parameters 获取Sql Server 存储过程参数

The DropDownList at the top of the page lists the stored procedures in the database. In the screen shot below I have selected the aspnet_Membership_GetAllUsers stored procedure, which is one of the stored procedures used by the SqlMembershipProvider. (For more information on ASP.NET's Membership feature, read Examining ASP.NET's Membership, Roles, and Profile.)

The selected stored procedure's input and output parameters are enumerated in bulleted lists. Note that there are three input parameters for this stored procedure: @ApplicationName, @PageIndex, and @PageSize. These input parameters are listed alongside TextBoxes in a GridView further down in the page. A user can enter values for these parameters, click the "Execute Stored Procedure" button, and see the results in a GridView at the bottom of the page. Granted, the GridView contains rather raw-looking, unformatted data, but the data is there nevertheless.

The remainder of this article looks at how various portions of this demo were implemented.

Retrieving a List of Stored Procedures


Every Microsoft SQL Server database includes a number of system tables that catalog the various objects that comprise the database, including the database's tables (and their columns), its triggers, its stored procedures, its UDFs, and so on. The "core" system table, and the one that contains a list of the database's stored procedures, is named sysobjects. Each stored procedure is represented as a row in sysobjects. Likewise, each table and constraint and view and so on are represented by rows in this table. The different database objects can be differentiated by the value in the sysobjects.type column - stored procedures have a type value of P.

The following SQL query returns the name of every stored procedure in the database:

SELECT name
FROM sysobjects
WHERE type = 'P'

The DropDownList in the demo is populated by a SqlDataSource control that runs the above query. It's that simple.

(For more information on using the sysobjects table see Using the sysobjects Table; for more on working with data in an ASP.NET page be sure to read Accessing and Updating Data in ASP.NET.)

Retrieving a Stored Procedure's Parameters


Once a stored procedure has been selected, how do we retrieve its parameters? While this information can be retrieved from SQL Server's system tables, there's an easier way: by calling the SqlCommandBuilder class's DeriveParameters method. This method accepts a SqlCommand object as its input and populates the SqlCommand object's Parameters collection with the specified stored procedure's parameters.

The following code illustrates the SqlCommandBuilder.DeriveParameters method in action. (Note: While this article shows Visual Basic code, the demo available for download at the end of this article includes both a VB and C# version.)

' ... Create SqlConnection object
Dim myCommand As New SqlCommand
myCommand.Connection = myConnection
myCommand.CommandText = stored procedure name
myCommand.CommandType = Data.CommandType.StoredProcedure

myConnection.Open()

SqlCommandBuilder.DeriveParameters(myCommand)


myConnection.Close()
' ...

While I don't show the code in the above snippet, the first step is to create a valid SqlConnection object to the database (which I named myConnection in the code above). Next create a SqlCommand object, and associate it with the SqlConnection object. Set the CommandText property to the name of the stored procedure whose parameters you want and set the CommandType property to StoredProcedure. All that remains is to open a connection to the database and call the SqlCommandBuilder.DeriveParameters method, passing in the SqlCommand object. This populates the passed-in SqlCommand object's Parameters collection with the specified stores procedure's parameter information.

The Parameters property is a collection of SqlParameter objects. Each SqlParameter object represents a parameter in a parameterized query or stored procedure. The most germane properties of the SqlParameter class are:

  • ParameterName - the name of the parameter.
  • SqlDbType - the parameter's data type.
  • Direction - indicates whether the parameter is an input parameter, is an output parameter, or can serve as both an input and output parameter. As discussed in Retrieving Scalar Data from a Stored Procedure, output parameters are useful for returning scalar values from a stored procedure.
  • Value - the parameter's value.

Once you have the parameters you can close the connection to the database and work with the parameters. The following code snippet continued the code from above by enumerating the returned parameters, displaying each parameter (along with its data type) in the appropriate BulletedList control depending on whether the parameter serves as an input or output parameter.

' ...
blInputParameters.Items.Clear()
blOutputParameters.Items.Clear()
For Each param As SqlParameter In myCommand.Parameters
   If param.Direction = Data.ParameterDirection.Input OrElse param.Direction = Data.ParameterDirection.InputOutput Then
      blInputParameters.Items.Add(param.ParameterName & " - " & param.SqlDbType.ToString())
   Else
      blOutputParameters.Items.Add(param.ParameterName & " - " & param.SqlDbType.ToString())
   End If
Next

Prompting the User for Input Parameter Values and Executing the Stored Procedure With Those Values


In addition to the two BulletedList controls the demo page also includes a GridView named gvParameters that lists the selected stored procedure's input parameters along with a TextBox for each parameter. In particular, this GridView is programmatically bound to a list of SqlParameter objects (namely, the set of input parameters returned by SqlCommandBuilder.DeriveParameters) and is composed of two fields:
  • A BoundField that displays each SqlParameter object's ParameterName property, and
  • A TemplateField that contains a TextBox control named ParameterValue.
Additionally, the gvParameters GridView's DataKeyFields property is set to ParameterName.

The page also includes an "Execute Stored Procedure" Button control and another GridView for the stored procedure results. This results GridView is named gvResults. When the "Execute Stored Procedure" Button is clicked the following code runs:

' ... Create SqlConnection object
Dim myCommand As New SqlCommand
myCommand.Connection = myConnection

myCommand.CommandText = stored procedure name


myCommand.CommandType = Data.CommandType.StoredProcedure
'Get the parameter values from the grid
For Each gvRow As GridViewRow In gvParameters.Rows
   'Determine the parameter name
   Dim paramName As String = gvParameters.DataKeys(gvRow.RowIndex).Value.ToString()
   Dim paramValue As Object = DBNull.Value
   'Get the TextBox in the row
   Dim paramValueTextBox As TextBox = CType(gvRow.FindControl("ParameterValue"), TextBox)
   If Not String.IsNullOrEmpty(paramValueTextBox.Text) Then
      paramValue = paramValueTextBox.Text
   End If
   'Add the parameter name/value pair to the SqlCommand
   myCommand.Parameters.AddWithValue(paramName, paramvalue)
Next
myConnection.Open()
gvResults.DataSource = myCommand.ExecuteReader()
gvResults.DataBind()
myConnection.Close()
End Using

The code starts by configuring a SqlCommand object that will execute the specified stored procedure. In this case we don't need to go off and programmatically determine the stored procedure's parameters because they are already encompassed by the gvParameters GridView. Each row in the gvParameters GridView is enumerated and the parameter's name and user-entered value are grabbed and added to the SqlCommand object's Parameters property via the AddWithValue(name, value) method.

After the parameters have been added to the SqlCommand object the results are bound to the gvResults GridView. That's all there is to it!

Conclusion


Programmatically retrieving the list of stored procedures in a database and those stored procedures' parameters are quite easy tasks. The database provides both the stored procedures and their parameters through system tables. Additionally, the parameters for a stored procedure can also be retrieved via the .NET Framework's SqlCommandBuilder.DeriveParameters method.

The demo available at the end of this article implements a quick and dirty dynamic reporting system. In short, it allows the visitor to execute any stored procedure on the database through a single page. Granted, the results are ugly and there's nothing stopping the visitor from executing any stored procedure she chooses, but such a page, when limited to a section accessible only to administrators, might be useful. In fact, with a little more effort it is possible to enhance this functionality to create a more user-friendly and secure general purpose reporting page. A future article will explore such functionality in greater detail.

Happy Programming!

  • By Scott Mitchell
  • Attachments

  • Download the code used in this article

    Further Reading

  • Accessing and Updating Data in ASP.NET
  • Using the sysobjects Table
  • 你可能感兴趣的:(SQL Server)