Cách sử dụng Data Readers Author :
Xcross87
Ở bài trước mình đã giới thiệu về cách viết SQL statement và thực thi (execute) câu lệnh. Ở bài này mình
sẽ tóm tắt về các sử dụng Data Readers.
Data Readers được dùng để :
• Thu nhận kết quả từ các query
• Lấy thông tin về các cột các hàng trong bảng dữ liệu
• Lấy thông tin result set
• Lấy thông tin về schema
• Xử lý các result sets
Tổng quát về Data Readers (Data Readers in General)
Thành phần thứ ba của nhà cung cấp dữ liệu là ‘data reader’, 2 thành phần trước là ‘connection’ và
‘command’. Một khi đã tạo được kết nối tới cơ sở dữ liệu và thi hành các lệnh query thì chúng ta cần một
phương thức nào đó để hỗ trợ cách xử lý dữ liệu thu nhận được. Nếu bạn đã biết về ADO thì một
ADO.NET data reader giống như là ADO recordset một chiều phía client, chứ không phải là một đối
tượng COM.
Data readers là các đối tượng được cung cấp trong lớp interface ‘System.Data.IdataReader’. Một ‘data
reader’ có thể gọi là một stream đã kết nối tới cơ sở dữ liệu đọc dữ liệu hiệu quả, theo một chiều và thu
nhận dữ liệu theo từng dòng (row).Vì vậy không thể trực tiếp xử lý data reader mà phải xử lý thông qua
phương thức ‘ExecuteReader’ của một đối tượng command. Ví dụ
[code]
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(new string(“query command”), conn);
SqlDataReader reader = cmd.ExecuteReader();
[/code]
Đoạn code ở trên là minh họa cách tạo một đối tượng trong lớp SqlDataReader.
Chú ý: Quy tắc chung khi sử dụng data reader dơn giản là chỉ thu nhận và trình bày kết quả thu được.Phân
biệt data reader với dataset, cả 2 đều được tạo ra với mục đích khác nhau mặc dù cách nhìn nhận chung
thì đều thu nhận kết quả.
Thử một vài ví dụ làm việc với Data Reader
[code]
catch (SqlException sqle)
{
// Thông báo lỗi
Console.WriteLine(sqle.ToString());
}
finally
{
// Đóng kết nối
conn.Close();
Console.WriteLine("Close connection !");
}
}
}
[/code]
Trong vòng lặp thu kết quả của ‘data reader’ (reader) phương thức ‘Read()’ trỏ đến giá trị hàng tiếp theo
(nếu có) . Bản chất khi reader đã có kết quả sau khi thực thi query thì reader nắm giữ toàn bộ record thu
được. vì vậy có thể dùng index để gọi đến một giá trị bất kì trong kết quả thu được nằm trong giới hạn của
bound.
Cuối cùng thì phải đóng lại reader. Tại sao đóng ? Vì khi đã kết nối và reader được gắn vào kết nối thì
reader sẽ nằm ở đó để lấy dữ liệu khi xử lý. Cứ tưởng tượng một ngôi nhà mà chỉ có người vào không có
người ra thì đến một lúc nào đó sẽ không vào được nữa mà muốn ra cũng không được. Tương tự như vậy,
phải đóng lại reader sau mỗi lần đọc.
Ví dụ dưới đây minh họa cách sử dụng index gọi giá trị column khi Read()
[code]
using System;
Page 2 of 9
Cách sử dụng Data Readers Author :
Xcross87
using System.Data;
using System.Data.SqlClient;
}
catch (SqlException sqle)
{
// Thông báo lỗi
Console.WriteLine(sqle.ToString());
}
finally
{
// Đóng kết nối
conn.Close();
Console.WriteLine("Close connection !");
}
}
}
[/code]
Kết quả thu được trong reader thu về là kiểu object . Vì vậy ở trên mình convert các object sang kiểu
string (ToString()) sau đó căn lề. Cuối cùng đóng kết nối để giải phóng khỏi kết nối.
Nhiều lúc cũng chẳng biết là cột số mấy vị trí nào hơi phức tạp. Lớp SqlDataReader cung cấp cho đối
tượng cách chỉ định index bằng tên cột.
Page 3 of 9
Cách sử dụng Data Readers Author :
Xcross87
[code]
reader[“companyname”].ToString().PadLeft(25);
reader[“contactname”].ToString().PadLeft(20);
[/code]
Tuy nhiên 2 cách trên đều không tối ưu. Vì khi truy cập vào bảng dữ liệu kết quả thu được giữ tạm thời
theo kiểu của .NET chứ không phải kiểu ban đầu trong tài nguyên. Hai cách ở trên mỗi lần lấy một kết
quả đều kiểm tra xem dữ liệu kiểu gì và convert kiểu nên không tối ưu.
Do đó phương thức lấy dữ liệu theo kiểu được cung cấp , tất cả bắt đầu với ‘Get’
Cách sử dụng Data Readers Author :
Xcross87
OLE DB .NET Phương thức truy cập
DBTYPE_I8 Int64 GetInt64
DBTYPE_BYTES Byte[] GetBytes
DBTYPE_BOOL Boolean GetBoolean
DBTYPE_BSTR String GetString
DBTYPE_STR String GetString
DBTYPE_CY Decimal GetDecimal
DBTYPE_DATE DateTime GetDateTime
DBTYPE_DBDATE DateTime GetDateTime
DBTYPE_DBTIME DateTime GetDateTime
DBTYPE_DBTIMESTAMP DateTime GetDateTime
DBTYPE_DECIMAL Decimal GetDecimal
DBTYPE_R8 Double GetDouble
DBTYPE_ERROR ExternalException GetValue
DBTYPE_FILETIME DateTime GetDateTime
DBTYPE_GUID Guid GetGuid
DBTYPE_I4 Int32 GetInt32
DBTYPE_LONGVARCHAR String GetString
DBTYPE_NUMERIC Decimal GetDecimal
DBTYPE_R4 Single GetFloat
DBTYPE_I2 Int16 GetInt16
DBTYPE_I1 Byte GetByte
DBTYPE_UI8 Uint64 GetValue
DBTYPE_UI4 Uint32 GetValue
DBTYPE_UI2 Uint16 GetValue
DBTYPE_VARCHAR String GetString
DBTYPE_VARIANT Object GetValue
DBTYPE_NVARCHAR String GetString
string sql = @"SELECT productname, unitprice, unitsinstock,
discontinued FROM products";
try
{
// Mở kết nối
conn.Open();
// Tạo command
SqlCommand cmd = new SqlCommand(sql, conn);
// Tạo Data Reader
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
Console.WriteLine("{0}\t{1}\t\t{2}\t{3}",
reader.GetString(0).PadRight(30),
reader.GetDecimal(1).ToString().PadLeft(8),
reader.GetInt16(2),
reader.GetBoolean(3));
}
reader.Close();
}
catch (SqlException sqle)
{
// Thông báo lỗi
Console.WriteLine(sqle.ToString());
}
finally
{
// Đóng kết nối
conn.Close();
// Tạo command
SqlCommand cmd = new SqlCommand(sql, conn);
// Tạo Data Reader
SqlDataReader reader = cmd.ExecuteReader();
DataTable table = reader.GetSchemaTable();
foreach (DataRow row in table.Rows)
{
foreach (DataColumn col in table.Columns)
{
Console.WriteLine("{0} = {1}", col.ColumnName, row[col]);
}
Console.WriteLine("===========================");
}
reader.Close();
}
catch (SqlException sqle)
{
// Thông báo lỗi
Console.WriteLine(sqle.ToString());
}
finally
{
// Đóng kết nối
conn.Close();
Console.WriteLine("Close connection !");
Page 7 of 9
Cách sử dụng Data Readers Author :
Xcross87
}
SqlConnection conn = new SqlConnection(@"Server = .\SQLEXPRESS;
Integrated Security = True;
Database = Northwind");
// Tạo query
string sql1 = @"SELECT productname, unitprice FROM products ";
string sql2 = @"SELECT firstname, lastname FROm employees ";
string sql = sql1 + sql2;
try
{
Page 8 of 9
Cách sử dụng Data Readers Author :
Xcross87
// Mở kết nối
conn.Open();
// Tạo command
SqlCommand cmd = new SqlCommand(sql, conn);
// Tạo Data Reader
SqlDataReader reader = cmd.ExecuteReader();
do
{
while (reader.Read())
{
Console.WriteLine("\t{0} - {1}", reader[0], reader[1]);
}
Console.WriteLine("".PadLeft(60,'='));
} while (reader.NextResult());
reader.Close();
}
catch (SqlException sqle)
{