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

Querying Databases

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 (359.4 KB, 18 trang )

Chapter 9
Querying Databases
After completing this chapter, you will be able to:

Issue data-modifying queries on external data sources

Retrieve a table of records from a SQL Server database

Return the primary key value for a newly inserted database record
Despite its capability to work with data generated completely within an application, ADO.NET’s
main purpose is to access and manipulate data in external data stores. To enable this query-
and-update functionality on the source data platform, ADO.NET includes a “command” ob-
ject, a wrapper around a platform-specific query that updates, inserts, or deletes target data;
or returns single or multiple values from the data source.
This chapter introduces this command wrapper, and demonstrates how to process records
returned from a data query. ADO.NET does not impose any limits on the content of the que-
ry statements because they are simply passed on to the data platform. However, the results
that come back might require special handling depending on the structure of the returned
data.
Note
This chapter focuses on the SQL Server provider and its implementation of command-
related processing features. The OLE DB and ODBC providers include conceptually identical
features, although some of the class names and processing details might differ. For complete
information on these providers, refer to the Visual Studio online help.
Processing SQL Queries
SQL is the lingua franca of relational database processing. Although most database systems
include specialized tools that let you organize data values and the table constructs that con-
tain them, you can manage most essential features by crafting queries in SQL. From table
creation to multitable data queries, SQL includes data definition and manipulation com-
mands that give those with sufficient security rights complete control over the database and
its content.


Dwonloaded from: iDATA.ws
136
In SQL Server databases, the SQL language includes different types of statements, including
the following:

SQL query statements Selection queries that return data results

Data manipulation statements Statements that modify or change data content

Data definition statements Commands that modify tables and other structures that
support the data content

Stored procedures Named blocks of processing logic
ADO.NET lets you process any of these statement types through instances of the System.
Data.SqlClient.SqlCommand class. This class encapsulates one or more SQL statements and
includes methods that request processing of the statement(s) on a SQL Server connection,
optionally returning query results.
Note
In the OLE DB provider, the equivalent command class is located at System.Data.
OleDb.OleDbCommand, whereas the ODBC provider version is found at System.Data.Odbc.
OdbcCommand. These two classes and the SqlCommand class in the SQL Server provider all
derive from System.Data.Common.DbCommand.
Creating Command Objects
Using the SqlCommand class is a straightforward procedure:
1. Create an instance of SqlCommand.
2. Assign a valid SQL statement to the object’s CommandText property.
3. Set the object’s Connection property to an open SqlConnection instance.
4. Assign other optional properties as needed.
5. Call one of the object’s many synchronous or asynchronous “execute” methods.
The SqlCommand object’s constructor has various overloaded versions that let you specify

the SQL statement text and the ADO.NET connection as arguments.
Dwonloaded from: iDATA.ws
Chapter 9 Querying Databases
137
C#
SqlConnection linkToDB = new SqlConnection(connectionString);
linkToDB.Open();
string sqlText = @"UPDATE WorkTable SET ProcessedOn = GETDATE()
WHERE ProcessedOn IS NULL";
SqlCommand dataAction = new SqlCommand(sqlText, linkToDB);
Visual Basic
Dim linkToDB As New SqlConnection(connectionString)
linkToDB.Open()
Dim sqlText As String = "UPDATE WorkTable SET ProcessedOn = GETDATE() " &
"WHERE ProcessedOn IS NULL"
Dim dataAction As New SqlCommand(sqlText, linkToDB)
The SqlCommand.CommandText field accepts two types of string data:

Standard SQL statements This is the default type. Normally, only a single SQL state-
ment appears in this field. However, you can include multiple semicolon-delimited
statements within a single command instance. Information on retrieving the results of
multiple SELECT statements from a single command appears later in this chapter.

Stored procedures The command text field contains the stored procedure name. Set
the SqlCommand.CommandType property to CommandType.StoredProcedure. You add
any “in” or “out” arguments to the command through distinct parameters. See Chapter
10, “Adding Parameters to Queries,” for details on using parameters. If you want to in-
clude the arguments within the command text itself (as is commonly done through SQL
Server’s Management Studio tool), treat the text as a standard SQL statement, setting
the CommandType property to CommandType.Text.

Note
The SqlCommand.CommandType property also accepts a value of CommandType.
TableDirect, which indicates that the CommandText field contains nothing more than a table
name to be used for row retrieval and management. The SQL Server provider does not support
this command variation.
Processing Queries
The command object works for queries that return data values from the data source, and
also for statements that take some action on the database but that return no stored data.
These “nonquery” actions are typical when adding, updating, or removing records from the
database; or when processing Data Definition Language commands, such as SQL Server’s
CREATE TABLE statement.
Dwonloaded from: iDATA.ws
138
Microsoft ADO.NET 4 Step by Step
To run a nonquery, create a new SqlCommand object and set its command text to the server-
side SQL statement. Then call the object’s ExecuteNonQuery method.
C#
string sqlText = "DELETE FROM WorkTable WHERE Obsolete = 1";
SqlCommand dataAction = new SqlCommand(sqlText, linkToDB);
try
{
dataAction.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show("Failure: " + ex.Message);
}
Visual Basic
Dim sqlText As String = "DELETE FROM WorkTable WHERE Obsolete = 1"
Dim dataAction As New SqlCommand(sqlText, linkToDB)

Try
dataAction.ExecuteNonQuery()
Catch ex As Exception
MessageBox.Show("Failure: " & ex.Message)
End Try
ExecuteNonQuery sends the command text to the data source through the previously
opened connection. Any processing errors, including those generated by the data source,
throw an exception.
Calls to stored procedures work the same way.
C#
string sqlText = "dbo.CancelOrder " + orderID;
SqlCommand dataAction = new SqlCommand(sqlText, linkToDB);
dataAction.ExecuteNonQuery();
Visual Basic
Dim sqlText As String = "dbo.CancelOrder " & orderID
Dim dataAction As New SqlCommand(sqlText, linkToDB)
dataAction.ExecuteNonQuery()
Dwonloaded from: iDATA.ws
Chapter 9 Querying Databases
139
Note
Building SQL statements through string concatenation, especially with user-supplied com-
ponents, can be risky. Chapter 10, “Adding Standards to Queries,” introduces command param-
eters, which can reduce or eliminate these risks. Parameters also let your code retrieve data from
stored procedure “out” parameters.
Processing Asynchronously
The ExecuteNonQuery method is synchronous; your application will block until the database
operation completes successfully or aborts with an error or connection timeout. If your ap-
plication is single threaded, it will cease to function (or at least appear that way) until the
method returns.

The command object also supports asynchronous processing of nonqueries. It includes a pair
of methods—BeginExecuteNonQuery and EndExecuteNonQuery—that bracket the operation.
The BeginExecuteNonQuery method returns an object with the interface System.IAsyncResult
that sets its IsCompleted property to True when processing ends. At that point, your code
must call the EndExecuteNonQuery method to complete the process.
C#
SqlCommand dataAction = new SqlCommand(sqlText, linkToDB);
IAsyncResult pending = dataAction.BeginExecuteNonQuery();
while (pending.IsCompleted == false)
{
// ----- Do work as needed, or...
Threading.Thread.Sleep(100);
}
dataAction.EndExecuteNonQuery(pending);
Visual Basic
Dim dataAction As New SqlCommand(sqlText, linkToDB);
Dim pending As IAsyncResult = dataAction.BeginExecuteNonQuery()
Do While (pending.IsCompleted = False)
' ----- Do work as needed, or...
Threading.Thread.Sleep(100)
Loop
dataAction.EndExecuteNonQuery(pending)
A variation of the BeginExecuteNonQuery method lets you specify a callback method and an
optional object that will be passed to the callback method when the operation completes.
You must still call EndExecuteNonQuery, although you can call it from within the callback
code. Passing the SqlCommand object as the optional argument simplifies this process.
Dwonloaded from: iDATA.ws
140
Microsoft ADO.NET 4 Step by Step
C#

SqlCommand dataAction = new SqlCommand(sqlText, linkToDB);
AsyncCallback callback = new AsyncCallback(WhenFinished);
dataAction.BeginExecuteNonQuery(callback, dataAction);
// ----- Elsewhere...
private void WhenFinished(IAsyncResult e)
{
// ----- The IAsyncResult.AsyncState property contains the
// optional object sent in by BeginExecuteNonQuery.
SqlCommand dataAction = (SqlCommand)e.AsyncState;
// ----- Finish processing.
dataAction.EndExecuteNonQuery(e);
}
Visual Basic
Dim dataAction As New SqlCommand(sqlText, linkToDB)
Dim callback As New AsyncCallback(AddressOf WhenFinished)
dataAction.BeginExecuteNonQuery(callback, dataAction)
' ----- Elsewhere...
Private Sub WhenFinished(ByVal e As IAsyncResult)
' ----- The IAsyncResult.AsyncState property contains the
' optional object sent in by BeginExecuteNonQuery.
Dim dataAction As SqlCommand = CType(e.AsyncState, SqlCommand)
' ----- Finish processing.
dataAction.EndExecuteNonQuery(e)
End Sub
The connection used by the command must remain open during processing. If you want to
halt execution of the command before it completes, call the SqlCommand object’s Cancel
method. Be aware that—depending on the state of processing—the Cancel method might or
might not cancel the execution in time.
Returning Query Results
Sending commands to a database is useful; getting data back is also essential for data-centric

applications. The command object includes several methods that return both single values
and multiple rows of tabular data.
Dwonloaded from: iDATA.ws
Chapter 9 Querying Databases
141
Returning a Single Value
The SqlCommand object’s ExecuteScalar method sends a SQL command or stored procedure
request to the database, just like the ExecuteNonQuery method, but it also returns a single value
produced by the query. This method is useful with SELECT queries that return a simple result.
C#
string sqlText = "SELECT COUNT(*) FROM WorkTable";
SqlCommand dataAction = new SqlCommand(sqlText, linkToDB);
int totalItems = (int)dataAction.ExecuteScalar();
Visual Basic
Dim sqlText As String = "SELECT COUNT(*) FROM WorkTable"
Dim dataAction As New SqlCommand(sqlText, linkToDB)
Dim totalItems As Integer = CInt(dataAction.ExecuteScalar())
Because ExecuteScalar returns data of type System.Object, you must coerce it into the ex-
pected data type. The method can return System.DBNull for nondata results.
SQL Server 2005 introduced a new OUTPUT keyword on INSERT statements that returns
a specified field (typically the primary key) from the newly inserted data row. Before this
change, programmers often had to issue two statements to obtain this new key value: the
first to insert the record and the second to retrieve the primary key through a new SELECT
statement. By combining the OUTPUT keyword with the ExecuteScalar method, it’s easy to
obtain the primary key in a single command.
C#
// ----- Pretend the ...'s represent actual fields, and that
// WorkTable.ID is the name of the primary key.
string sqlText = @"INSERT INTO WorkTable (...)
OUTPUT INSERTED.ID VALUES (...)";

SqlCommand dataAction = new SqlCommand(sqlText, linkToDB);
int newID = (int)dataAction.ExecuteScalar();
Visual Basic
' ----- Pretend the ...'s represent actual fields, and that
' WorkTable.ID is the name of the primary key.
Dim sqlText As String = "INSERT INTO WorkTable (...) " &
"OUTPUT INSERTED.ID VALUES (...)"
Dim dataAction As New SqlCommand(sqlText, linkToDB)
Dim newID As Integer = CInt(dataAction.ExecuteScalar())
Stored procedures that return a single value are identical in concept.
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
×