1. Trang chủ
  2. » Công Nghệ Thông Tin

Adding Standards to Queries

16 327 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Adding standards to queries
Thể loại Chapter
Định dạng
Số trang 16
Dung lượng 330,31 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

153Chapter 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 select

Trang 1

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

Trang 2

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 elestate-ments 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

Trang 3

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

Trang 4

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)

Trang 5

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

Trang 6

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

Trang 7

Updating Data with Parameters: Visual Basic

1 Open the “Chapter 10 VB” project from the installed samples folder The project

in-cludes multiple Windows.Forms classes and a module named General.

2 Open the code for the General module This file 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

ExecuteSQL(commandWrapper)

Catch ex As Exception

MessageBox.Show("Error occurred updating customer name: " &

ex.Message)

Return

End Try

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

Trang 8

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

Using Parameters with Other Providers

The OLE DB and ODBC providers also include support for parameterized queries However, the definitions of both the command text and the associated parameters vary somewhat from the SQL Server implementation Instead of including placeholder names prefixed with

@ signs, each replaceable element appears as a nameless question mark (?) in the command

text Parameters added to the associated OleDbCommand or OdbcCommand instance must

be added in the order indicated by the placeholders Although the command text does not

include parameter names, each added OleDbParameter or OdbcParameter instance should

still include @-prefixed names

C#

string sqlText = @"UPDATE Employee SET Salary = ? WHERE ID = ?";

SqlCommand salaryUpdate = new SqlCommand(sqlText, linkToDB);

salaryUpdate.Parameters.AddWithValue("@NewSalary", 50000m);

salaryUpdate.Parameters.AddWithValue("@EmployeeID", 25L);

Visual Basic

Dim sqlText As String = "UPDATE Employee SET Salary = ? WHERE ID = ?"

Dim salaryUpdate = New SqlCommand(sqlText, linkToDB)

salaryUpdate.Parameters.AddWithValue("@NewSalary", 50000@)

salaryUpdate.Parameters.AddWithValue("@EmployeeID", 25&)

Trang 9

Calls to stored procedures with parameterized queries vary only slightly from those to standard statements There are four main differences you need to consider when

access-ing stored procedures The first is simple: Make sure you set the SqlCommand object’s CommandType property to CommandType.StoredProcedure.

The second difference is equally simple: The command object’s CommandText property

should include only the name of the stored procedure Exclude any arguments or query elements

The third difference is in how you name the parameters As with standard queries, each parameter includes an @-prefixed name and a data type, plus other optional settings you might want to configure Unlike standard queries, you have no flexibility in how you define the parameter names They must match precisely the parameter names used when the stored procedure was defined within SQL Server

The last difference has to do with the direction of a parameter The SqlParameter class in-cludes a Direction property that tells ADO.NET which way data flows from your query’s data value to the stored procedure There are four available System.Data.ParameterDirection

options:

ParameterDirection.Input The parameter value is considered input, flowing from

the application to the stored procedure This is the default for all parameters

ParameterDirection.Output The parameter is used to retrieve data back from the

stored procedure, much like a ByRef (Visual Basic) or out (C#) function argument.

ParameterDirection.InputOutput A combination of the input and output directions

Your application provides an input value that can be modified and returned by the stored procedure

ParameterDirection.ReturnValue For stored procedures or other database features

that sport a return value, this parameter type lets you collect that value

Parameters added to standard query commands also support the Direction property, but in most cases the default of ParameterDirection.Input is the right choice.

The following SQL Server stored procedure includes an input value (@locationName), an out-put value (@newID), and a return value (@@ROWCOUNT):

CREATE PROCEDURE AddLocation (@locationName varchar(50), @newID bigint OUT)

AS

BEGIN

INSERT INTO BuildingLocation (Name) VALUES (@locationName);

SET @newID = SCOPE_IDENTITY();

RETURN @@ROWCOUNT;

END

Trang 10

The following code calls the AddLocation stored procedure, passing it the name of a new

lo-cation and returning the new ID value:

C#

// - Use a stored procedure to add a new building location.

string sqlText = "dbo.AddLocation";

SqlCommand locationCommand = new SqlCommand(sqlText, linkToDB);

locationCommand.CommandType = CommandType.StoredProcedure;

// - Add the input parameter: locationName.

SqlParameter workParameter = locationCommand.Parameters.AddWithValue(

"@locationName", LocationNameField.Text.Trim());

workParameter.Size = 50;

// - Add the output parameter: newID.

workParameter = locationCommand.Parameters.Add("@newID", SqlDbType.BigInt);

workParameter.Direction = ParameterDirection.Output;

// - Add the return value parameter The name is not important.

workParameter = locationCommand.Parameters.Add("@returnValue", SqlDbType.Int);

workParameter.Direction = ParameterDirection.ReturnValue;

// - Add the location.

locationCommand.ExecuteNonQuery();

// - Access returned values as:

// locationCommand.Parameters["@newID"].Value

// locationCommand.Parameters["@returnValue"].Value

Visual Basic

' - Use a stored procedure to add a new building location.

Dim sqlText As String = "dbo.AddLocation"

Dim locationCommand As New SqlCommand(sqlText, linkToDB)

locationCommand.CommandType = CommandType.StoredProcedure

' - Add the input parameter: locationName.

Dim workParameter As SqlParameter =

locationCommand.Parameters.AddWithValue(

"@locationName", LocationNameField.Text.Trim)

workParameter.Size = 50

Ngày đăng: 03/10/2013, 00:20

TỪ KHÓA LIÊN QUAN

w