[ Team LiB ] |
21.3 Methods Reference
Closes the DataReader, but leaves the connection open. You must call Close( ) before you can use the connection for another command. However, if you want to close the DataReader and the connection, simply call the Connection.Close( ) method instead. ExampleThe following code shows how to close a DataReader and reuse the connection for another task: con.Open(); SqlDataReader r = cmdA.ExecuteReader(); // (Process rows here.) r.Close(); // Reuse the open connection for another query. r = cmdB.ExecuteReader(); con.Close();
Every DataReader has a set of strongly typed accessors that allow you to retrieve column values without performing any sort of conversion, potentially improving performance. For example, you can use the GetInt32( ) method to retrieve a column value that holds a 32-bit integer. This call succeeds only if the column contains a 32-bit integer; otherwise, an exception occurs. Many providers define additional accessor methods that are customized to use database-specific data types. You can recognize these because they will include the provider abbreviation. For example, the SQL Server uses the abbreviation Sql and provides strongly typed accessors such as GetSqlGuid( ), GetSqlMoney( ), and GetSqlDateTime( ). These methods return values using the native SQL data types defined in the System.Data.SqlTypes namespace. For a complete example on how to use these types with a DataReader, refer to Chapter 5. When using the strongly typed accessors, you must specify the column index. You can't look up a value by column name. However, you can use the GetOrdinal( ) method to retrieve the column ordinal for a column with a specific name. ExampleThe following code retrieves the second column as a string: string value = r.GetString(1); NotesIt isn't necessary to use strongly typed accessors. You can use the indexer, unless you have reason to be concerned that the conversion to a .NET type could introduce a rounding error. Before calling a strongly typed accessor on a field that can contain null values, you should use the IsDBNull( ) method.
Retrieves the name of the native data type used for a specified column. In C#, you can also use the typeof( ) operator to retrieve type information. ExampleThe following code displays the data type of the second column: Console.WriteLine(r.GetDataTypeName(1));
Returns the name of a column at a specified index. One reason to use this method is to display column headings when iterating through a result set by index number. ExampleThe following code statement generically prints every column retrieved from a query and its column name: con.Open(); r = cmd.ExecuteReader(); while (r.Read()) { for (int i = 1; i <= r.FieldCount - 1; i++) { Console.Write(r.GetName(i).ToString() + ": "); Console.WriteLine(r[i].ToString()); } Console.WriteLine(); } con.Close();
Retrieves the zero-based ordinal for the column with the specific name. This is useful for two reasons. First of all, many DataReader methods require the use of column ordinals, not field names. Second, access via a column ordinal is likely to perform faster. In fact, when you use a column name, ADO.NET performs a hashtable lookup behind the scenes to determine the correct column ordinal. Using GetOrdinal( ), you can perform this lookup once, rather than every time you need to access a field. ExampleThe following code shows a simple example of how you might access a column using the column ordinal, even if you only know its column name: // Perform the ordinal lookups. int colID = r.GetOrdinal("CustomerID"); int colFirstName = r.GetOrdinal("FirstName"); int colSecondName = r.GetOrdinal("SecondName"); while (r.Read()) { // Use the ordinals far faster column value access. Console.WriteLine(r[colID].ToString()); Console.WriteLine(r[colFirstName].ToString() + " " + r[colSecondName].ToString()); Console.WriteLine(); } NoteColumns are returned in the same order they appear in a SELECT statement.
Returns a DataTable that contains metadata for the current query. This table contains one row for each column in the result set and several fields that describe details such as column names and data types. Table 21-2 lists all columns returned in the schema DataTable, in order.
ExampleThe following example retrieves a schema table and displays the returned information. The schema information describes the columns from the Customers table. SqlCommand cmd = new SqlCommand("SELECT * FROM CUSTOMERS", con); // Get the schema table. con.Open(); SqlDataReader r = cmd.ExecuteReader(); DataTable schema = r.GetSchemaTable(); con.Close(); // Display schema table information. foreach (DataRow row in schema.Rows) { foreach (DataColumn col in schema.Columns) { Console.WriteLine(col.ColumnName + " = " + row[col].ToString()); } Console.WriteLine(); }
Retrieves a single value from a column as a .NET framework type. This method is rarely needed because the indexer provides more convenient access. NoteSome providers also provide strongly typed versions of the GetValue( ) method, which you can recognize based on the provider prefix. For example, SQL Server provides a GetSqlValue( ) method that retrieves a column values as a SQL Server-specific type.
This method provides an efficient way to retrieve all the values in a row at once rather than access each column value separately. The values are retrieved into an array of objects, which you must supply as an argument. The GetValues( ) method returns the number of values used to fill the array. Before you use the GetValues( ) method, you should make sure the array length is the correct size. If the array length is less than the number of required columns, all the values will not be retrieved. Instead, the available slots in the array are filled with the corresponding column values, and all additional column values are ignored. No exception is thrown. You can also pass an object array that has a length greater than the number of columns contained in the resulting row without generating an error. ExampleThe following example retrieves all the column values for a row into an object array, and then adds this array to an ArrayList collection. The information for each row is added to the ArrayList in this fashion. string SQL = "SELECT * FROM Customers"; SqlCommand cmd = new SqlCommand(SQL, con); ArrayList rows = new ArrayList(); con.Open(); SqlDataReader r = cmd.ExecuteReader(); while (r.Read()) { object[] values = new object[r.FieldCount]; r.GetValues(values); rows.Add(values); } con.Close(); Console.WriteLine("Data retrieved for " + rows.Count.ToString() + " rows"); NotesSome providers also provide strongly typed versions of the GetValue( ) method, which you can recognize based on the provider prefix. For example, SQL Server provides a GetSqlValue( ) method. There is no DataReader method that allows you to retrieve multiple rows into an array.
Returns a Boolean value that indicates whether the indicated column contains a null value. You can call this method to check for a null value before you call a typed accessor method such as GetByte( ) or GetChar( ) and thereby avoid raising an error. ExampleThe following code tests for a null value before attempting to retrieve an integer value: int rowVal; if (r.IsDbNull(i)) { // Use default value. Row is null. rowVal = 0; } else { // Use database value. rowVal = (int)r[i]; }
Moves the reader to the next result set. A DataReader returns multiple result sets only if you use a batch query or if you invoke a stored procedure that includes more than one SELECT query. By default, the DataReader begins on the first result set. NextResult( ) returns true if there are more result sets. ExampleHere's an example that retrieves multiple result sets using a batch query: // Define a batch query. string SQL = "SELECT * FROM Categories; SELECT * FROM Products"; SqlConnection con = new SqlConnection(connectionString); SqlCommand cmd = new SqlCommand(SQL, con); con.Open(); // Execute the batch query. SqlDataReader reader = cmd.ExecuteReader(); while (reader.Read()) { // (Process the category rows here.) } reader.NextResult(); while (reader.Read()) { // (Process the product rows here.) }
Moves to the next record. If no record can be found, it returns false. Otherwise, it returns true. When the DataReader is first created, it is positioned just before the first row. You must call Read( ) before you can retrieve information from the first row. (The first Read( ) call advances the DataReader to the first record, if any.) ExampleThe following code shows the basic pattern of access for reading rows with the DataReader. The Read( ) method is invoked as part of a while loop, ensuring that the loop ends immediately when the Read( ) method returns false. string SQL = "SELECT ContactName FROM Customers"; SqlCommand cmd = new SqlCommand(SQL, con); SqlDataReader r; try { con.Open(); r = cmd.ExecuteReader(); // Iterate over the results. while (r.Read()) { Console.WriteLine(r["ContactName"].ToString()); } } finally { con.Close(); } Because the DataReader encapsulates a live connection, you should read all the information as quickly as possible and close the connection immediately after. NoteThe DataReader provides only a single record at a time. Once the DataReader has been moved forward, you can't retrieve a value from a previous row. |
[ Team LiB ] |