Tải bản đầy đủ (.pdf) (16 trang)

Adding Standards to Queries

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (330.31 KB, 16 trang )

153
Chapter 10
Adding Standards to Queries
After completing this chapter, you will be able to:

Understand why parameters are important in queries

Add parameters to standard selection and data update queries

Call stored procedures that include both in and out parameters
In ADO.NET, queries pass to external data sources as strings. These strings include not only
essential command keywords and syntactical elements but also the data values used to limit
and fulfill each query. Building command strings is an art long practiced by developers in
many programming languages, but it’s quite different from .NET’s promise of strongly typed
data management. Why store values as distinct data types at all if you are eventually going
to convert everything to ASCII text?
To push aside these and other deficiencies that stem from inserting all types of data values
into SQL statements, ADO.NET includes the parameter, an object that bridges the gap be-
tween the text-based needs of the external data source’s command processing system and
the intelligent data type system that epitomizes .NET development. This chapter demon-
strates query parameters and their uses in SQL Server database queries.
Note
This chapter focuses on parameters as implemented in the SQL Server provider. Although
the OLE DB and ODBC providers also implement parameters, there are some minor differences
that will be pointed out within the chapter.
The exercises in this chapter all use the same sample project, a tool that uses parameters to re-
trieve and update database values. Although you can run the application after each exercise,
the expected results for the full application might not appear until you complete all exercises in
the chapter.
Developing Parameterized Queries
In the SQL Server provider, parameters appear as the System.Data.SqlClient.SqlParameter


class. By creating relevant parameters and attaching them to SqlCommand instances, ordi-
nary text queries become parameterized queries.
Dwonloaded from: iDATA.ws
154
Microsoft ADO.NET 4 Step by Step
Note
In the OLE DB provider, the parameter class appears as System.Data.OleDb.
OleDbParameter. The ODBC equivalent is System.Data.Odbc.OdbcParameter. Both of these
classes and the SqlParameter class in the SQL Server provider derive from System.Data.Common.
DbParameter.
Understanding the Need for Parameters
As mentioned in the “Connection String Builders” section on page 124 of Chapter 8,
“Establishing External Connections,” there are certain risks involved in building SQL state-
ments and related string elements. A key risk is the SQL injection attack, in which a user
can inadvertently or deliberately alter the intent of a SQL statement by supplying corrupted
content. Consider the following statement, which modifies the Employee.Salary value for a
specific employee record:
UPDATE Employee SET Salary = XXX WHERE ID = 5;
It works well if the user provides 50000 or a similar number as the value of XXX. But what if
resourceful employee John Doe replaces XXX with the following SQL fragments?
150000 WHERE FirstName = 'John' AND LastName = 'Doe';
UPDATE Employee SET Salary = 50000
The user-supplied content includes a semicolon, effectively turning one statement into a
batch of two statements. Most programmers design their code to avoid such scenarios, but
this type of situation still manages to show up from time to time. Parameters help reduce
such issues by using typed substitution placeholders instead of unchecked plain-text gaps
in SQL strings. Parameters understand how to properly format their replacement values so
that SQL injection attacks and other mishaps don’t occur.
Parameters solve these problems by making changes to both the SQL statement and the
data destined for that statement. Instead of piecing together workable SQL statements from

a combination of programmer and user-supplied parts, parameterized query statements ex-
ist in a standardized form, free of unknown and unsafe user data. Portions of the statement
that require user input exist as named placeholders, @name elements that get replaced
with the final type-specific data values after they have been transmitted to the database.
Dwonloaded from: iDATA.ws
Chapter 10 Adding Standards to Queries
155
This process provides for a more generic command text, and a logical separation between
the command and its data.
Removing ever-changing data values from SQL statements also increases performance within
SQL Server. Like many advanced relational database systems, SQL Server compiles each state-
ment into an internal format, one that doesn’t require it to constantly parse a text string
to determine its actions. If SQL Server encounters the same SQL statement twice, it doesn’t
need to go through the time-consuming compilation process again. For example, the follow-
ing three SQL statements are different in the compiler’s view:
UPDATE Employee SET Salary = 50000 WHERE ID = 5;
UPDATE Employee SET Salary = 56000 WHERE ID = 12;
UPDATE Employee SET Salary = 52000 WHERE ID = 8;
Parameterized queries replace these three instance-specific versions with a generic version of
the statement, free of the varying data portions. Removing dynamic data values from what
would otherwise be standard SQL command structures allows applications to send a much
more limited number of queries to SQL Server, queries that show up again and again, and
that don’t need to be recompiled every time.
Implementing Standard Queries
The UPDATE statement shown previously modifies the salary for an employee record based
on that record’s primary key.
UPDATE Employee SET Salary = 50000 WHERE ID = 25;
To prepare the statement for parameters, all elements destined for substitution by the
parameter values get replaced with “@” identifiers.
UPDATE Employee SET Salary = @NewSalary WHERE ID = @EmployeeID;

In standard SQL statements (all statements other than stored procedures), the names you
provide are up to you, so being descriptive is best. Each placeholder must begin with the @
sign followed by a unique name. Parameter names are not case-sensitive.
Dwonloaded from: iDATA.ws
156
Microsoft ADO.NET 4 Step by Step
As with nonparameterized queries, this enhanced statement gets wrapped up in a
SqlCommand object:
C#
string sqlText = @"UPDATE Employee SET Salary = @NewSalary
WHERE ID = @EmployeeID";
SqlCommand salaryUpdate = new SqlCommand(sqlText, linkToDB);
Visual Basic
Dim sqlText As String =
"UPDATE Employee SET Salary = @NewSalary WHERE ID = @EmployeeID"
Dim salaryUpdate = New SqlCommand(sqlText, linkToDB)
The SqlCommand class includes a Parameters collection to which you add the specific re-
placement values for each placeholder. You wrap up each parameter in an instance of
SqlParameter, setting its properties as needed, and adding it to the SqlCommand.Parameters
collection. When you execute the command, ADO.NET passes both the placeholder-laden
SQL text and the parameter collection to the database for evaluation.
Each parameter includes the elements you would expect: the parameter name (which must
match a placeholder name in the SQL statement), the data type along with any data type-
specific settings (such as the length of string parameters), the actual data content to be
included in the processed command, and a few other generic settings. To add a parameter to
a command, create a SqlParameter instance and add it to the SqlCommand object.
C#
SqlParameter paramValue = new SqlParameter("@NewSalary", SqlDbType.Money);
paramValue.Value = 50000m;
salaryUpdate.Parameters.Add(paramValue);

paramValue = new SqlParameter("@EmployeeID", SqlDbType.BigInt);
paramValue.Value = 25L;
salaryUpdate.Parameters.Add(paramValue);
Visual Basic
Dim paramValue As New SqlParameter("@NewSalary", SqlDbType.Money)
paramValue.Value = 50000@
salaryUpdate.Parameters.Add(paramValue)
paramValue = New SqlParameter("@EmployeeID", SqlDbType.BigInt)
paramValue.Value = 25&
salaryUpdate.Parameters.Add(paramValue)
Dwonloaded from: iDATA.ws
Chapter 10 Adding Standards to Queries
157
SqlParameter includes lots of constructor options for setting the data type of the passed
data, plus other settings. Or you can go the traditional route and update the object’s indi-
vidual properties directly, including the following:

ParameterName The name of the parameter; that is, the placeholder. Don’t forget to
include the @ sign at the start of the name.

DbType or SqlDbType One of the System.Data.SqlDbType enumeration values, which
all parallel the available data types in SQL Server. For example, SqlDbType.VarChar maps
to SQL Server’s varchar column type. Both DbType and SqlDbType refer to the same
property; update either one as needed.

IsNullable Indicates whether the parameter accepts NULL values.

Precision and Scale Some of SQL Server’s numeric data types require specific preci-
sion and scale values. Use these properties to configure the data from ADO.NET’s point
of view.


Size Similar to Precision and Scale, Size is commonly used for text and binary data
types. It affects only the amount of data sent to SQL Server with a query. If your query
sends data back through a parameter (described below), it ignores this Size setting.

Value and SqlValue The actual value that will replace the placeholder in the SQL
statement. Use Value to work with data defined using the standard .NET data types.
Use the SqlValue property instead to work with data in a format that more closely re-
sembles SQL Server’s data types, and as expressed through the classes in the System.
Data.SqlTypes namespace.
If your data needs are simple, you can let the SqlCommand.Parameters collection define the
data type of your parameters for you. The collection’s AddWithValue method accepts the
parameter name and the intended value and adds a new SqlParameter instance to the com-
mand using the specified settings.
C#
salaryUpdate.Parameters.AddWithValue("@NewSalary", 50000m);
salaryUpdate.Parameters.AddWithValue("@EmployeeID", 25L);
Visual Basic
salaryUpdate.Parameters.AddWithValue("@NewSalary", 50000@)
salaryUpdate.Parameters.AddWithValue("@EmployeeID", 25&)
Once the parameters are all in place, calling one of the command’s Execute methods processes
the command on the database, and returns any results as with nonparameterized queries.
Dwonloaded from: iDATA.ws
158
Microsoft ADO.NET 4 Step by Step
C#
salaryUpdate.ExecuteNonQuery();
Visual Basic
salaryUpdate.ExecuteNonQuery()
Updating Data with Parameters: C#

1. Open the “Chapter 10 CSharp” project from the installed samples folder. The project
includes multiple Windows.Forms classes and a sealed class named General.
2. Open the code for the General class. This class centralizes much of the database func-
tionality for the sample application. Locate the GetConnectionString function, a routine
that uses a SqlConnectionStringBuilder to create a valid connection string to the sample
database. It currently includes the following statements:
builder.DataSource = @"(local)\SQLExpress";
builder.InitialCatalog = "StepSample";
builder.IntegratedSecurity = true;
Adjust these statements as needed to provide access to your own test database.
3. Open the code for the RenameCustomer form. This form lets the user modify the
FullName value for a single record in the Customer database table. Locate the ActOK_
Click event handler. This routine does the actual update of the record. Just after the
“Save the new name” comment, add the following code:
sqlText = "UPDATE Customer SET FullName = @NewName WHERE ID = @CustID";
commandWrapper = new SqlCommand(sqlText);
commandWrapper.Parameters.AddWithValue("@NewName", NewName.Text.Trim());
commandWrapper.Parameters.AddWithValue("@CustID", ActiveCustomerID);
try
{
General.ExecuteSQL(commandWrapper);
}
catch (Exception ex)
{
MessageBox.Show("Error occurred updating customer name: " +
ex.Message);
return;
}
These statements create a SqlCommand object with a SQL statement that includes two
placeholders: @NewName and @CustID. The code then adds two matching parameters

to the command and sends it to the database for processing.
4. Run the program. On the Customer Management form, select a customer from the list
of customers and then click Rename Customer. When the Rename Customer form ap-
pears, enter a new value in the New Name field and then click OK. This process updates
the database using the newly added code.
Dwonloaded from: iDATA.ws

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×