使用參數配合 DataAdapter
DataAdapter 具有四個屬性,可用來擷取資料來源的資料,以及將資料更新至資料來源:SelectCommand 屬性可傳回資料來源的資料;InsertCommand、UpdateCommand 與 DeleteCommand 屬性可用來管理資料來源上的變更。SelectCommand 屬性必須先經過設定,才能呼叫 DataAdapter 的 Fill 方法。呼叫 DataAdapter 的 Update 方法之前,必須先設定 InsertCommand、UpdateCommand 或 DeleteCommand 屬性,視針對 DataSet 中之的資料所進行的變更而定。例如,如果已經加入資料列,則必須先設定 InsertCommand,才能呼叫 Update。Update 正在處理已插入、已更新或已刪除的資料列時,DataAdapter 會使用個別的 Command 屬性來處理這項動作。已修改資料列的目前資訊會透過 Parameters 集合傳遞給 Command 物件。
更新資料來源的資料列時,您呼叫的 UPDATE 陳述式會使用唯一的識別項來識別資料表中需要更新的資料列。唯一的識別項一般是主索引鍵欄位的值。UPDATE 陳述式所使用的參數包含唯一的識別項,以及需要更新的資料行和值,如下列 Transact-SQL 陳述式所示。
UPDATE Customers SET CompanyName = @CompanyName
WHERE CustomerID = @CustomerID
注意事項 |
---|
參數語法的保留字元會隨資料來源而有所不同。此範例將說明 SQL Server 資料來源的保留字元。若為 System.Data.OleDb 和 System.Data.Odbc 參數,請使用問號 (?) 保留字元。 |
在此 Visual Basic 範例中,會針對 CustomerID 等於 @CustomerID 參數值的資料列,以 @CompanyName 參數的值來更新 CompanyName 欄位。這些參數會使用 SqlParameter 物件的 SourceColumn 屬性,從已修改的資料列擷取資訊。下列是前面範例 UPDATE 陳述式的參數。程式碼會假設變數 adapter 表示有效的 SqlDataAdapter 物件。
adapter.Parameters.Add( _
"@CompanyName", SqlDbType.NChar, 15, "CompanyName")
Dim parameter As SqlParameter = _
adapter.UpdateCommand.Parameters.Add("@CustomerID", _
SqlDbType.NChar, 5, "CustomerID")
parameter.SourceVersion = DataRowVersion.Original
Parameters 集合的 Add 方法擷取參數的名稱、DataAdapter 特定型別、大小 (如果此型別有大小),以及來自 DataTable 的 SourceColumn 名稱。請注意,@CustomerID 參數的 SourceVersion 是設定為 Original。如此一來,如果已修改的 DataRow 內識別資料行的值已經變更,便可確保資料來源內的現有資料列也已經更新。這種情況下,Original 資料列值會和資料來源中的目前值相符,而 Current 資料列值會包含已更新的值。@CompanyName 參數的 SourceVersion 並未設定,將會使用預設的 Current 資料列值。
SqlClient 範例
下列範例所顯示的範例 SQL 陳述式,將用做 SqlDataAdapter 之 SelectCommand、InsertCommand、UpdateCommand 和 DeleteCommand 屬性的 CommandText。對於 SqlDataAdapter 物件,請使用指名參數。
Dim selectSQL As String = _
"SELECT CustomerID, CompanyName FROM Customers " & _
"WHERE CountryRegion = @CountryRegion 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"
string selectSQL =
"SELECT CustomerID, CompanyName FROM Customers WHERE CountryRegion = " +
"@CountryRegion 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 或 Odbc 範例
若為 OleDbDataAdapter 和 OdbcDataAdapter 物件,則必須使用問號 (?) 保留字元來識別參數。
Dim selectSQL As String = _
"SELECT CustomerID, CompanyName FROM Customers " & _
"WHERE CountryRegion = ? 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 = ?"
string selectSQL =
"SELECT CustomerID, CompanyName FROM Customers " +
"WHERE CountryRegion = ? 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
' Assumes that connection is a valid SqlConnection object.
Dim adapter As SqlDataAdapter = New SqlDataAdapter
Dim selectCMD AS SqlCommand = New SqlCommand(selectSQL, connection)
adapter.SelectCommand = selectCMD
' Add parameters and set values.
selectCMD.Parameters.Add( _
"@CountryRegion", SqlDbType.NVarChar, 15).Value = "UK"
selectCMD.Parameters.Add( _
"@City", SqlDbType.NVarChar, 15).Value = "London"
Dim customers As DataSet = New DataSet
adapter.Fill(customers, "Customers")
// Assumes that connection is a valid SqlConnection object.
SqlDataAdapter adapter = new SqlDataAdapter();
SqlCommand selectCMD = new SqlCommand(selectSQL, connection);
adapter.SelectCommand = selectCMD;
// Add parameters and set values.
selectCMD.Parameters.Add(
"@CountryRegion", SqlDbType.NVarChar, 15).Value = "UK";
selectCMD.Parameters.Add(
"@City", SqlDbType.NVarChar, 15).Value = "London";
DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
OleDb
' Assumes that connection is a valid OleDbConnection object.
Dim adapter As OleDbDataAdapter = New OleDbDataAdapter
Dim selectCMD AS OleDbCommand = New OleDbCommand(selectSQL, connection)
adapter.SelectCommand = selectCMD
' Add parameters and set values.
selectCMD.Parameters.Add( _
"@CountryRegion", OleDbType.VarChar, 15).Value = "UK"
selectCMD.Parameters.Add( _
"@City", OleDbType.VarChar, 15).Value = "London"
Dim customers As DataSet = New DataSet
adapter.Fill(customers, "Customers")
// Assumes that connection is a valid OleDbConnection object.
OleDbDataAdapter adapter = new OleDbDataAdapter();
OleDbCommand selectCMD = new OleDbCommand(selectSQL, connection);
adapter.SelectCommand = selectCMD;
// Add parameters and set values.
selectCMD.Parameters.Add(
"@CountryRegion", OleDbType.VarChar, 15).Value = "UK";
selectCMD.Parameters.Add(
"@City", OleDbType.VarChar, 15).Value = "London";
DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
Odbc
' Assumes that connection is a valid OdbcConnection object.
Dim adapter As OdbcDataAdapter = New OdbcDataAdapter
Dim selectCMD AS OdbcCommand = New OdbcCommand(selectSQL, connection)
adapter.SelectCommand = selectCMD
' Add Parameters and set values.
selectCMD.Parameters.Add("@CountryRegion", OdbcType.VarChar, 15).Value = "UK"
selectCMD.Parameters.Add("@City", OdbcType.VarChar, 15).Value = "London"
Dim customers As DataSet = New DataSet
adapter.Fill(customers, "Customers")
// Assumes that connection is a valid OdbcConnection object.
OdbcDataAdapter adapter = new OdbcDataAdapter();
OdbcCommand selectCMD = new OdbcCommand(selectSQL, connection);
adapter.SelectCommand = selectCMD;
//Add Parameters and set values.
selectCMD.Parameters.Add("@CountryRegion", OdbcType.VarChar, 15).Value = "UK";
selectCMD.Parameters.Add("@City", OdbcType.VarChar, 15).Value = "London";
DataSet customers = new DataSet();
adapter.Fill(customers, "Customers");
注意事項 |
---|
若未提供參數名稱給參數,則會為參數指定 Parameter N 的累加預設名稱,從 "Parameter1" 開始。當您提供參數名稱時,建議您避免使用 ParameterN 命名慣例,因為您所提供的名稱可能會與 ParameterCollection 中現有的預設參數名稱衝突。如果提供的名稱已經存在,便會發生例外狀況。 |
Parameter.DbType
Parameter 型別僅適用於 .NET Framework 資料提供者。指定型別會使 Parameter 的值在傳遞給資料來源前,先轉換成 .NET Framework 資料提供者型別。您也可以將 Parameter 物件的 DbType 屬性設為特定的 DbType,以透過一般方式指定 Parameter 的型別。
您可以從 Parameter 物件 Value 的 .NET Framework 型別,或從 Parameter 物件的 DbType 推斷出 Parameter 物件的 .NET Framework 資料提供者型別。下列表格顯示根據當作 Parameter 值或指定的 DbType 來傳遞的物件而推斷出的 Parameter 型別。
.NET Framework 型別 | System.Data.DbType | SqlDbType | OleDbType | OdbcType | OracleType |
---|---|---|---|---|---|
bool |
Boolean |
Bit |
Boolean |
Bit |
Byte |
byte |
Byte |
TinyInt |
UnsignedTinyInt |
TinyInt |
Byte |
byte[] |
Binary |
VarBinary. 如果位元組陣列超過 VarBinary 的最大大小 8000 位元組,則這項隱含轉換會失敗。若要使用超過 8000 個位元組的位元組陣列,請明確設定 SqlDbType。 |
VarBinary |
Binary |
Raw |
char |
|
不支援從 char 推斷 SqlDbType。 |
Char |
Char |
Byte |
DateTime |
DateTime |
DateTime |
DBTimeStamp |
DateTime |
DateTime |
Decimal |
Decimal |
Decimal |
Decimal |
Numeric |
Number |
double |
Double |
Float |
Double |
Double |
Double |
float |
Single |
Real |
Single |
Real |
Float |
Guid |
Guid |
UniqueIdentifier |
Guid |
UniqueIdentifier |
Raw |
Int16 |
Int16 |
SmallInt |
SmallInt |
SmallInt |
Int16 |
Int32 |
Int32 |
Int |
Int |
Int |
Int32 |
Int64 |
Int64 |
BitInt |
BigInt |
BigInt |
Number |
object |
Object |
Variant |
Variant |
不支援從 Object 推斷 OdbcType。 |
Blob |
string |
String |
NVarChar。如果字串超過 NVarChar 的最大大小 4000 個字元,則這項隱含轉換便會失敗。若要使用超過 4000 個字元的字串,請明確設定 SqlDbType。 |
VarWChar |
NVarChar |
NVarChar |
TimeSpan |
Time |
不支援從 TimeSpan 推斷 SqlDbType。 |
DBTime |
Time |
DateTime |
UInt16 |
UInt16 |
不支援從 UInt16 推斷 SqlDbType。 |
UnsignedSmallInt |
Int |
UInt16 |
UInt32 |
UInt32 |
不支援從 UInt32 推斷 SqlDbType。 |
UnsignedInt |
BigInt |
UInt32 |
UInt64 |
UInt64 |
不支援從 UInt64 推斷 SqlDbType。 |
UnsignedBigInt |
Numeric |
Number |
|
AnsiString |
VarChar |
VarChar |
VarChar |
VarChar |
|
AnsiStringFixedLength |
Char |
Char |
Char |
Char |
|
Currency |
Money |
Currency |
不支援從 Currency 推斷 OdbcType。 |
Number |
|
Date |
不支援從 Date 推斷 SqlType。 |
DBDate |
Date |
DateTime |
|
SByte |
不支援從 SByte 推斷 SqlType。 |
TinyInt |
不支援從 SByte 推斷 OdbcType。 |
SByte |
|
StringFixedLength |
NChar |
WChar |
NChar |
NChar |
|
Time |
不支援從 Time 推斷 SqlType。 |
DBTime |
Time |
DateTime |
|
VarNumeric |
不支援從 VarNumeric 推斷 SqlDbType。 |
VarNumeric |
不支援從 VarNumeric 推斷 OdbcType。 |
Number |
注意事項 |
---|
.NET Framework 1.0 版隨附的 .NET Framework 資料提供者不會驗證 Decimal 參數值的精確度和小數位數,這可能導致截斷的資料插入資料來源中。如果您使用 .NET Framework 1.0,請在設定參數值前,先驗證 Decimal 值的精確度與小數位數。對於 .NET Framework 1.1 與更新版本,若以無效的精確度設定 Decimal 參數值,則會發生例外狀況。超過 Decimal 參數小數位數的小數位數值仍會被截斷。 |
注意事項 |
---|
若為 .NET Framework 1.0 和更新版本,您可以在使用 System.Data.SqlClient 時搭配使用 System.Data.SqlTypes。如需詳細資訊,請參閱使用 SqlType。 |
Parameter.Direction
下列表格所顯示的值可與 ParameterDirection 列舉型別搭配使用,以設定 Parameter 的 Direction。
成員名稱 | 說明 |
---|---|
Input |
這是輸入參數。此為預設值。 |
InputOutput |
這個參數可用於輸入和輸出。 |
Output |
這是輸出參數。 |
ReturnValue |
這個參數表示傳回值。 |
下列程式碼範例顯示如何設定 Parameter 的 Direction。
parameter.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
adapter.UpdateCommand.Parameters.Add( _
"@CustomerID", SqlDbType.NChar, 5, "CustomerID")
adapter.UpdateCommand.Parameters.Add( _
"@CompanyName", SqlDbType.NVarChar, 40, "CompanyName")
Dim parameter As SqlParameter = _
adapter.UpdateCommand.Parameters.Add("@OldCustomerID", _
SqlDbType.NChar, 5, "CustomerID")
parameter.SourceVersion = DataRowVersion.Original
adapter.UpdateCommand.Parameters.Add(
"@CustomerID", SqlDbType.NChar, 5, "CustomerID");
adapter.UpdateCommand.Parameters.Add(
"@CompanyName", SqlDbType.NVarChar, 40, "CompanyName");
SqlParameter parameter =
adapter.UpdateCommand.Parameters.Add(
"@OldCustomerID", SqlDbType.NChar, 5, "CustomerID");
parameter.SourceVersion = DataRowVersion.Original;
UpdatedRowSource
您可以使用 Command 物件的 UpdatedRowSource 屬性,控制從資料來源傳回的值對應回 DataSet 的方式。將 UpdatedRowSource 屬性設為其中一個 UpdateRowSource 列舉型別值,即可控制是要忽略 DataAdapter 命令所傳回的參數,還是將其套用至 DataSet 的已變更資料列中。您還能指定是否要將第一個傳回的資料列 (如果存在) 套用至 DataSet 內已變更的資料列。
下列表格說明 UpdateRowSource 列舉型別的各種值,以及這些值與 DataAdapter 合用後會如何影響命令的行為。
UpdateRowSource | 說明 |
---|---|
Both |
輸出參數和傳回結果集的第一個資料列會被對應至 DataSet 內已變更的資料列。 |
FirstReturnedRecord |
只有傳回結果集第一個資料列內的資料會被對應至 DataSet 內已變更的資料列。 |
None |
任何輸出參數參數或傳回結果集的資料列都會被忽略。 |
OutputParameters |
只有輸出參數會被對應至 DataSet 內已變更的資料列。 |
請參閱
概念
指定參數和傳回值
將資料提供者資料型別對應至 .NET Framework 資料型別