DataAdapter 具有四项用于从数据源检索数据和向数据源更新数据的属性。SelectCommand 属性从数据源中返回数据。InsertCommand、UpdateCommand 和 DeleteCommand 属性用于管理数据源中的更改。在调用 DataAdapter 的 Fill 方法之前,必须设置 SelectCommand 属性。根据对 DataSet 中的数据作出的更改,在调用 DataAdapter 的 Update 方法之前,必须设置 InsertCommand、UpdateCommand 或 DeleteCommand 属性。例如,如果已添加行,在调用 Update 之前必须设置 InsertCommand。当 Update 处理已插入、更新或删除的行时,DataAdapter 将使用相应的 Command 属性来处理该操作。有关已修改行的当前信息将通过 Parameters 集合传递到 Command 对象。
例如,当更新数据源中的行时,将调用 UPDATE 语句,它使用唯一标识符来表示该表中要更新的行。该唯一标识符通常是主键字段的值。UPDATE 语句使用既包含唯一标识符又包含要更新的列和值的参数,如以下 SQL 语句所示。
UPDATE Customers SET CompanyName = @CompanyName WHERE CustomerID = @CustomerID
在该示例中,CompanyName 字段使用其中 CustomerID 等于 @CustomerID 参数值的行的 @CompanyName 参数的值来进行更新。这些参数使用 Parameter 对象的 SourceColumn 属性从已修改的行中检索相关信息。下面是上一示例 UPDATE 语句的参数。
custDA.Parameters.Add("@CompanyName", SqlDbType.NChar, 15, "CompanyName")
Dim myParm As SqlParameter = custDA.UpdateCommand.Parameters.Add("@CustomerID",
_
SqlDbType.NChar, 5, "CustomerID")
myParm.SourceVersion = DataRowVersion.Original
Parameters 集合的 Add 方法采用参数的名称、DataAdapter 特定类型、大小(如果可应用于该类型)以及 DataTable 中 SourceColumn 的名称。请注意,@CustomerID 参数的 SourceVersion 设置为 Original。这样,如果标识列的值已经在修改后的 DataRow 中被更改,就一定会更新数据源中的现有行。在这种情况下,Original 行值将匹配数据源中的当前值,而 Current 行值将包含更新的值。如果没有为 @CompanyName 参数设置 SourceVersion,而将使用默认的 Current 行值。
以下示例显示要用作 DataAdapter 的 SelectCommand、InsertCommand、UpdateCommand 和 DeleteCommand 属性的 CommandText 的示例 SQL 语句。对于 OleDbDataAdapter 对象,必须使用问号 (?) 占位符来标识参数。对于 SqlDataAdapter 对象,必须使用命名参数。
SqlClient
[Visual Basic]
Dim selectSQL As String = "SELECT CustomerID, CompanyName FROM
Customers WHERE Country = @Country AND City = @City"
Dim insertSQL As String = "INSERT INTO Customers (CustomerID, CompanyName)
VALUES (@CustomerID, @CompanyName)"
Dim updateSQL As String = "UPDATE Customers SET CustomerID = @CustomerID,
CompanyName = @CompanyName WHERE CustomerID = @OldCustomerID"
Dim deleteSQL As String = "DELETE FROM Customers WHERE CustomerID = @CustomerID"
[C#]
string selectSQL = "SELECT CustomerID, CompanyName FROM Customers
WHERE Country = @Country AND City = @City";
string insertSQL = "INSERT INTO Customers (CustomerID, CompanyName) VALUES
(@CustomerID, @CompanyName)";
string updateSQL = "UPDATE Customers SET CustomerID = @CustomerID,
CompanyName = @CompanyName WHERE CustomerID = @OldCustomerID";
string deleteSQL = "DELETE FROM Customers WHERE CustomerID = @CustomerID";
OleDb
[Visual Basic]
Dim selectSQL As String = "SELECT CustomerID, CompanyName FROM
Customers WHERE Country = ? AND City = ?"
Dim insertSQL AS String = "INSERT INTO Customers (CustomerID, CompanyName)
VALUES (?, ?)"
Dim updateSQL AS String = "UPDATE Customers SET CustomerID = ?, CompanyName
= ? WHERE CustomerID = ?"
Dim deleteSQL As String = "DELETE FROM Customers WHERE CustomerID = ?"
[C#]
string selectSQL = "SELECT CustomerID, CompanyName FROM Customers
WHERE Country = ? AND City = ?";
string insertSQL = "INSERT INTO Customers (CustomerID, CompanyName) VALUES
(?, ?)";
string updateSQL = "UPDATE Customers SET CustomerID = ?, CompanyName = ?
WHERE CustomerID = ? ";
string deleteSQL = "DELETE FROM Customers WHERE CustomerID = ?";
参数化查询语句定义将需要创建哪些输入和输出参数。若要创建参数,请使用 Parameters.Add 方法或 Parameter 构造函数来指定列名称、数据类型和大小。对于内部数据类型(如 Integer),无需包含大小或者可以指定默认大小。
以下代码示例为上一示例中的 SQL 语句创建参数并填充 DataSet。
SqlClient
[Visual Basic]
Dim nwindConn As SqlConnection = New SqlConnection("Data Source=localhost;Integrated
Security=SSPI;Initial Catalog=northwind")
Dim custDA As SqlDataAdapter = New SqlDataAdapter
Dim selectCMD AS SqlCommand = New SqlCommand(selectSQL, nwindConn)
custDA.SelectCommand = selectCMD
' Add parameters and set values.
selectCMD.Parameters.Add("@Country", SqlDbType.NVarChar, 15).Value =
"UK"
selectCMD.Parameters.Add("@City", SqlDbType.NVarChar, 15).Value =
"London"
Dim custDS As DataSet = New DataSet
custDA.Fill(custDS, "Customers")
[C#]
SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated
Security=SSPI;Initial Catalog=northwind");
SqlDataAdapter custDA = new SqlDataAdapter();
SqlCommand selectCMD = new SqlCommand(selectSQL, nwindConn);
custDA.SelectCommand = selectCMD;
// Add parameters and set values.
selectCMD.Parameters.Add("@Country", SqlDbType.NVarChar, 15).Value =
"UK";
selectCMD.Parameters.Add("@City", SqlDbType.NVarChar, 15).Value =
"London";
DataSet custDS = new DataSet();
custDA.Fill(custDS, "Customers");
OleDb
[Visual Basic]
Dim nwindConn As OleDbConnection = New OleDbConnection("Provider=SQLOLEDB;Data
Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind")
Dim custDA As OleDbDataAdapter = New OleDbDataAdapter
Dim selectCMD AS OleDbCommand = New OleDbCommand(selectSQL, nwindConn)
custDA.SelectCommand = selectCMD
' Add parameters and set values.
selectCMD.Parameters.Add("@Country", OleDbType.VarChar, 15).Value =
"UK"
selectCMD.Parameters.Add("@City", OleDbType.VarChar, 15).Value =
"London"
Dim custDS As DataSet = New DataSet
custDA.Fill(custDS, "Customers")
[C#]
OleDbConnection nwindConn = new OleDbConnection("Provider=SQLOLEDB;Data
Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind;");
OleDbDataAdapter custDA = new OleDbDataAdapter();
OleDbCommand selectCMD = new OleDbCommand(selectSQL, nwindConn);
custDA.SelectCommand = selectCMD;
// Add parameters and set values.
selectCMD.Parameters.Add("@Country", OleDbType.VarChar, 15).Value =
"UK";
selectCMD.Parameters.Add("@City", OleDbType.VarChar, 15).Value =
"London";
DataSet custDS = new DataSet();
custDA.Fill(custDS, "Customers");
注意 如果没有为参数提供参数名称,则将给该参数提供递增的默认名称 ParameterN,参数名称从“Parameter1”开始。建议在提供参数名称时避免使用“ParameterN”命名约定,因为所提供的名称可能会与 ParameterCollection 中现有的默认参数名称发生冲突。如果提供的名称已经存在,将引发异常。
Parameter.DbType
参数的类型针对于 .NET 数据提供程序。如果指定类型,则会在向数据源传递值之前将 Parameter 的值转换为 .NET 数据提供程序类型。如果未指定类型,ADO.NET 将从 Parameter 对象的 Value 的 .NET 框架类型推断 Parameter 的 .NET 数据提供程序类型。
也可以通过将 Parameter 对象的 DbType 属性指定为特定的 System.Data.DbType,以一般的方式来指定 Parameter 的类型。此外,ADO.NET 将从 Parameter 对象的 DbType 推断 Parameter 的 .NET 数据提供程序类型。
Parameter 对象的 .NET 数据提供程序类型是从 Parameter 对象的 Value 的 .NET 框架类型或从 Parameter 对象的 DbType 来进行推断的,如下表所示。
| .NET 框架类型 | System.Data.DbType | SqlDbType | OleDbType |
|---|---|---|---|
| bool | Boolean | Bit | Boolean |
| byte | Byte | TinyInt | UnsignedTinyInt |
| byte[] | Binary | VarBinary。如果字节数组大于 VarBinary 的最大大小(8000 字节),此隐式转换将失败。对于大于 8000 字节的字节数组,请显式设置 SqlDbType。 | VarBinary |
| char | 不支持从 char 推断 SqlDbType。 | Char | |
| DateTime | DateTime | DateTime | DBTimeStamp |
| Decimal | Decimal | Decimal | Decimal |
| double | Double | Float | Double |
| float | Single | Real | Single |
| Guid | Guid | UniqueIdentifier | Guid |
| int | Int | Integer | |
| Int16 | Int16 | SmallInt | SmallInt |
| Int32 | Int32 | Int | Int |
| Int64 | Int64 | BitInt | BigInt |
| long | BigInt | BigInt | |
| object | Object | Variant | Variant |
| short | SmallInt | SmallInt | |
| string | string | NVarChar。如果字符串大于 NVarChar 的最大大小(4000 字节),此隐式转换将失败。对于大于 4000 字符的字符串,请显式设置 SqlDbType。 | VarWChar |
| UInt16 | UInt16 | 不支持从 UInt16 推断 SqlDbType。 | UnsignedSmallInt |
| UInt32 | UInt32 | 不支持从 UInt32 推断 SqlDbType。 | UnsignedInt |
| UInt64 | UInt64 | 不支持从 UInt64 推断 SqlDbType。 | UnsignedBigInt |
| AnsiString | VarChar | VarChar | |
| Currency | Money | Currency | |
| Date | DateTime | DBDate | |
| SByte | TinyInt | TinyInt | |
| Time | DateTime | DBTime | |
| VarNumeric | 不支持从 VarNumeric 推断 SqlDbType。 | VarNumeric |
Parameter.Direction
下表显示可以与 ParameterDirection 枚举一起用来设置 Parameter 的 Direction 的值。
| 成员名称 | 说明 |
|---|---|
| Input | 该参数是输入参数。这是默认值。 |
| InputOutput | 该参数能够输入和输出。 |
| Output | 该参数是输出参数。 |
| ReturnValue | 该参数表示返回值。 |
以下代码示例显示如何设置 Parameter 的 Direction。
myParm.Direction = ParameterDirection.Output
Parameter.SourceColumn,Parameter.SourceVersion
SourceColumn 和 SourceVersion 可以作为参数传递到 Parameter 构造函数,或设置为现有 Parameter 的属性。SourceColumn 是来自将在其中检索 Parameter 值的 DataRow 的 DataColumn 的名称。SourceVersion 指定 DataAdapter 使用哪个 DataRow 版本来检索值。
下表显示可以与 SourceVersion 一起使用的 DataRowVersion 枚举值。
| 成员名称 | 说明 |
|---|---|
| Current | 该参数使用列的当前值。这是默认值。 |
| Default | 该参数使用列的 DefaultValue。 |
| Original | 该参数使用列的初始值。 |
| Proposed | 该参数使用建议值。 |
以下代码示例定义一个 UPDATE 语句,在该语句中,CustomerID
列用作以下两个参数的 SourceColumn:@CustomerID (SET
CustomerID = @CustomerID) 和 @OldCustomerID (WHERE
CustomerID = @OldCustomerID)。@CustomerID 参数用于将 CustomerID
列更新为 DataRow 中的当前值。因此,将使用 SourceVersion
为 Current 的 CustomerID SourceColumn。@OldCustomerID
参数用于标识数据源中的当前行。由于在该行的 Original
版本中找到了匹配列值,所以将使用 SourceVersion 为 Original
的相同 SourceColumn (CustomerID)。
SqlClient
[Visual Basic]
custDA.UpdateCommand.Parameters.Add("@CustomerID",
SqlDbType.NChar, 5, "CustomerID")
custDA.UpdateCommand.Parameters.Add("@CompanyName", SqlDbType.NVarChar,
40, "CompanyName")
Dim myParm As SqlParameter = custDA.UpdateCommand.Parameters.Add("@OldCustomerID",SqlDbType.NChar,
5, "CustomerID")
myParm.SourceVersion = DataRowVersion.Original
[C#]
custDA.UpdateCommand.Parameters.Add("@CustomerID",
SqlDbType.NChar, 5, "CustomerID");
custDA.UpdateCommand.Parameters.Add("@CompanyName", SqlDbType.NVarChar,
40, "CompanyName");
SqlParameter myParm = custDA.UpdateCommand.Parameters.Add("@OldCustomerID",
SqlDbType.NChar, 5, "CustomerID");
myParm.SourceVersion = DataRowVersion.Original;
OleDb
[Visual Basic]
custDA.UpdateCommand.Parameters.Add("@CustomerID",
OleDbType.Char, 5,"CustomerID")
custDA.UpdateCommand.Parameters.Add("@CompanyName", OleDbType.VarChar,
40, "CompanyName")
Dim myParm As OleDbParameter = custDA.UpdateCommand.Parameters.Add("@OldCustomerID",OleDbType.Char,
5, "CustomerID")
myParm.SourceVersion = DataRowVersion.Original
[C#]
custDA.UpdateCommand.Parameters.Add("@CustomerID",
OleDbType.Char, 5, "CustomerID");
custDA.UpdateCommand.Parameters.Add("@CompanyName", OleDbType.VarChar,
40, "CompanyName");
OleDbParameter myParm = custDA.UpdateCommand.Parameters.Add("@OldCustomerID",
OleDbType.Char, 5, "CustomerID");
myParm.SourceVersion = DataRowVersion.Original;
UpdatedRowSource
可以使用 Command 对象的 UpdatedRowSource 属性控制从数据源中返回的值如何映射回 DataSet。通过将 UpdatedRowSource 属性设置为 UpdateRowSource 枚举值之一,可以控制是忽略 DataAdapter 命令返回的参数还是将其应用于 DataSet 中已更改的行。还可以指定是否将返回的第一个行(如果存在)应用于 DataSet 中已更改的行。
下表描述 UpdateRowSource 枚举的不同值,并说明它们如何影响与 DataAdapter 一起使用的命令的行为。
| UpdateRowSource | 说明 |
|---|---|
| Both | 输出参数和返回的结果集的第一行都可以映射到 DataSet 中已更改的行。 |
| FirstReturnedRecord | 只有返回的结果集第一行中的数据才可以映射到 DataSet 中已更改的行。 |
| None | 将忽略任何输出参数或返回的结果集的行。 |
| OutputParameters | 只有输出参数才可以映射到 DataSet 中已更改的行。 |