使用 SqlDataSource 插入、更新和刪除資料 (VB)
在先前的教學課程中,我們已瞭解 ObjectDataSource 控件如何允許插入、更新和刪除數據。 SqlDataSource 控件支援相同的作業,但方法不同,本教學課程示範如何設定 SqlDataSource 來插入、更新和刪除數據。
簡介
如 插入、更新和刪除的概觀所述,GridView 控件提供內建的更新和刪除功能,而 DetailsView 和 FormView 控件包含插入支援以及編輯和刪除功能。 這些數據修改功能可以直接插入數據源控件,而不需要撰寫一行程序代碼。 使用 ObjectDataSource 檢查的插入、更新和刪除概觀,有助於使用 GridView、DetailsView 和 FormView 控件插入、更新和刪除。 或者,可以使用 SqlDataSource 取代 ObjectDataSource。
回想一下,使用 ObjectDataSource 支援插入、更新和刪除,我們需要指定要叫用的物件層方法來執行插入、更新或刪除動作。 使用 SqlDataSource,我們需要提供 INSERT
、 UPDATE
和 DELETE
SQL 語句, (或預存程式) 執行。 如本教學課程所示,這些語句可以手動建立,或可由 SqlDataSource 的設定數據源精靈自動產生。
注意
由於我們已討論 GridView、DetailsView 和 FormView 控件的插入、編輯和刪除功能,本教學課程將著重於設定 SqlDataSource 控件以支持這些作業。 如果您需要在 GridView、DetailsView 和 FormView 內實作這些功能,請返回編輯、插入和刪除數據教學課程,從 插入、更新和刪除的概觀開始。
步驟 1:指定 INSERT、UPDATE 和 DELETE 語句
如過去兩個教學課程中所見,若要從 SqlDataSource 控件擷取數據,我們需要設定兩個屬性:
ConnectionString
,指定要傳送查詢的資料庫,以及SelectCommand
,指定要執行的臨機操作 SQL 語句或預存程式名稱,以傳回結果。
對於 SelectCommand
具有參數的值,參數值是透過 SqlDataSource 的 SelectParameters
集合指定,而且可以包含硬式編碼的值、常見的參數來源值 (查詢字串字段、會話變數、Web 控件值等等) ,或可以程序設計方式指派。 當 SqlDataSource 控制項的 Select()
方法以程式設計方式或自動從資料 Web 控制項叫用資料庫時,就會將參數值指派給查詢,而命令會從資料庫開始。 然後,結果會傳回為 DataSet 或 DataReader,視控件 s DataSourceMode
屬性的值而定。
除了選取數據之外,SqlDataSource 控制件也可以用來以非常相同的方式提供 INSERT
、 UPDATE
和 SQL 語句來插入、更新和 DELETE
刪除數據。 只要指派 InsertCommand
、 UpdateCommand
、 和 DeleteCommand
屬性 INSERT
,即可執行、 UPDATE
和 DELETE
SQL 語句。 如果語句具有參數 (,因為其一律會) ,請在 、 UpdateParameters
和 DeleteParameters
集合中包含InsertParameters
參數。
指定 InsertCommand
、 UpdateCommand
或 DeleteCommand
值之後,對應資料 Web 控制項智慧標記中的 [啟用插入]、[啟用編輯] 或 [啟用刪除] 選項將會變成可用。 為了說明這點,讓我們從 Querying.aspx
我們在 使用 SqlDataSource 控件查詢數據 教學課程中建立的頁面取得範例,並加以增強以包含刪除功能。
首先,InsertUpdateDelete.aspx
從 SqlDataSource
資料夾開啟 和 Querying.aspx
頁面。 從頁面上的 DesignerQuerying.aspx
,從第一個範例中選取 SqlDataSource 和 GridView (ProductsDataSource
和 GridView1
控件) 。 選取兩個控件之後,請移至 [編輯] 功能表,然後選擇 [複製 (或只按 Ctrl+C) 。 接下來,移至 的 InsertUpdateDelete.aspx
Designer 並貼上控件。 將兩個控件 InsertUpdateDelete.aspx
移至 之後,請在瀏覽器中測試頁面。 您應該會看到資料庫資料表中Products
所有記錄的ProductID
、 ProductName
和 UnitPrice
資料行的值。
圖 1:列出所有產品,依 ProductID
(按兩下以檢視完整大小的影像)
新增 SqlDataSource 的 DeleteCommand 和 DeleteParameters 屬性
此時,我們有一個 SqlDataSource,只要從 Products
數據表傳回所有記錄,以及轉譯此數據的 GridView 即可。 我們的目標是擴充此範例,以允許使用者透過 GridView 刪除產品。 若要達成此目的,我們需要指定 SqlDataSource 控件的值 DeleteCommand
和 DeleteParameters
屬性,然後設定 GridView 以支持刪除。
DeleteCommand
與 DeleteParameters
屬性可以透過數種方式來指定:
- 透過宣告式語法
- 從 Designer中的 屬性視窗
- 從 [設定數據源精靈] 中的 [指定自定義 SQL 語句或預存程式] 畫面
- 透過 [設定數據源精靈] 中 [從檢視表指定數據行] 畫面中的 [進階] 按鈕,這實際上會自動產生
DELETE
和DeleteParameters
屬性中使用的DeleteCommand
SQL 語句和參數集合
我們將檢查如何在步驟 2 中自動 DELETE
建立 語句。 現在,讓我們在 Designer 中使用 屬性視窗,雖然 [設定數據源精靈] 或宣告式語法選項也可以運作。
從中的 InsertUpdateDelete.aspx
Designer 中,單擊 ProductsDataSource
[SqlDataSource],然後從 [檢視] 功能表顯示 屬性視窗 (、選擇 [屬性視窗],或直接點擊 F4) 。 選取DeleteQuery屬性,其會顯示一組省略號。
圖 2:從 [屬性] 視窗中選取 DeleteQuery 屬性
注意
SqlDataSource 沒有 DeleteQuery 屬性。 相反地,DeleteQuery 是 和 DeleteParameters
屬性的組合DeleteCommand
,只有在透過 Designer 檢視視窗時,才會列在 屬性視窗 中。 如果您要在 [來源] 檢視中查看 屬性視窗,則會改為找到 DeleteCommand
屬性。
按兩下DeleteQuery屬性中的省略號,以顯示 [命令和參數 編輯器] 對話框, (請參閱圖 3) 。 從這個對話框,您可以指定 DELETE
SQL 語句並指定參數。 如果您要) ,請在命令文字框中輸入下列查詢 DELETE
, (手動或使用查詢產生器:
DELETE FROM Products
WHERE ProductID = @ProductID
接下來,按兩下 [重新整理參數] 按鈕,將 @ProductID
參數新增至下列參數清單。
@ProductID 參數新增至 DELETE 命令參數列表。」 />
圖 3:從 [屬性] 視窗中選取 DeleteQuery 屬性 (按兩下即可檢視大小完整的影像)
請勿提供此參數的值, (將其參數來源保留為 None ) 。 當我們將刪除支援新增至 GridView 之後,GridView 會自動提供此參數值,並使用其 DataKeys
集合的值,做為按兩下 [刪除] 按鈕的數據列。
注意
查詢中使用的 DELETE
參數名稱 必須與 GridView、DetailsView 或 FormView 中的值名稱 DataKeyNames
相同。 也就是說,語句中的 參數會以目的方式命名 @ProductID
(,而不是例如 @ID
,) ,因為 Products 數據表中的DELETE
主鍵數據行名稱 (,因此 GridView) 中的 DataKeyNames 值是 ProductID
。
如果參數名稱和 DataKeyNames
值不相符,GridView 就無法自動將集合中的 DataKeys
值指派給參數。
在 [命令和參數 編輯器] 對話框中輸入刪除相關信息之後,按兩下 [確定] 並移至 [來源] 檢視,以檢查產生的宣告式標記:
<asp:SqlDataSource ID="ProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
SelectCommand=
"SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]"
DeleteCommand="DELETE FROM Products WHERE ProductID = @ProductID">
<DeleteParameters>
<asp:Parameter Name="ProductID" />
</DeleteParameters>
</asp:SqlDataSource>
請注意新增 DeleteCommand
屬性以及 <DeleteParameters>
區段和名為 productID
的 Parameter 物件。
設定 GridView 以刪除
新增 屬性后 DeleteCommand
,GridView 的智慧標記現在包含 [啟用刪除] 選項。 請繼續並核取此複選框。 如 插入、更新和刪除的概觀中所述,這會導致 GridView 新增 CommandField,其 ShowDeleteButton
屬性設定為 True
。 如圖 4 所示,當頁面透過瀏覽器瀏覽時,會包含 [刪除] 按鈕。 藉由刪除某些產品來測試此頁面。
圖 4:每個 GridView 數據列現在都包含 [刪除] 按鈕 (按鍵即可檢視大小完整的影像)
按兩下 [刪除] 按鈕時,發生回傳時,GridView 會 ProductID
為單擊 [刪除] 按鈕的數據列指派集合值的參數 DataKeys
,並叫用 SqlDataSource s Delete()
方法。 然後,SqlDataSource 控制項會連接到資料庫並執行 DELETE
語句。 GridView 接著會重新系結至 SqlDataSource,並返回並顯示目前的產品集, (不再包含剛刪除的記錄) 。
注意
由於 GridView 使用其 DataKeys
集合來填入 SqlDataSource 參數,因此 GridView DataKeyNames
的 屬性必須設定為構成主鍵的數據行 () ,而且 SqlDataSource 會 SelectCommand
傳回這些數據行。 此外,請務必將 SqlDataSource s DeleteCommand
中的參數名稱設定為 @ProductID
。 DataKeyNames
如果未設定屬性,或未命名 @ProductsID
參數,請按兩下 [刪除] 按鈕會導致回傳,但實際上不會刪除任何記錄。
圖 5 以圖形方式描述此互動。 請參閱 檢查與插入、更新和刪除相關聯的事件 教學課程,以取得與插入、更新及刪除數據 Web 控件相關聯之事件鏈結的更詳細討論。
圖 5:按兩下 GridView 中的 [刪除] 按鈕會叫用 SqlDataSource s Delete()
方法
步驟 2:自動產生 INSERT
、 UPDATE
和 DELETE
語句
如步驟 1 所檢查,INSERT
可以透過 屬性視窗 或控件的宣告式語法來指定 、 UPDATE
和 DELETE
SQL 語句。 不過,這種方法需要手動寫出 SQL 語句,這可以是單調且容易出錯的。 幸運的是,[設定數據源精靈] 提供一個選項,可讓您 INSERT
在使用檢視表畫面中的 [指定數據行] 時自動產生 、 UPDATE
和 DELETE
語句。
讓我們來探索這個自動產生選項。 將 DetailsView 新增至 中的 InsertUpdateDelete.aspx
Designer,並將其 ID
屬性設定為 ManageProducts
。 接下來,從 DetailsView 的智慧標記中,選擇建立新的數據源,並建立名為 的 ManageProductsDataSource
SqlDataSource。
圖 6:建立名為 ManageProductsDataSource
的新 SqlDataSource (按兩下即可檢視大小完整的映像)
從 [設定數據源精靈] 中,選擇使用 NORTHWINDConnectionString
連接字串,然後按 [下一步]。 從 [設定選取語句] 畫面,將 [從數據表或檢視] 單選按鈕保留 [指定數據行],然後從下拉式清單中挑選 Products
數據表。 ProductID
從複選框清單中選取、 ProductName
UnitPrice
和 Discontinued
資料行。
圖 7:使用 Products
數據表,傳回 ProductID
、 ProductName
、 UnitPrice
和 Discontinued
資料行 (按鍵即可檢視大小完整的影像)
若要根據選取的數據表和數據行自動產生 INSERT
、 UPDATE
和 DELETE
語句,請按兩下 [進階] 按鈕並核取 [產生 INSERT
、 UPDATE
和 DELETE
語句] 複選框。
圖 8:核取 [產生 INSERT
、 UPDATE
和 DELETE
語句] 複選框
只有在選取的數據表具有主鍵,且主鍵數據行 (或數據行) 包含在傳回的數據行清單中時,才會核取 [產生 INSERT
、 UPDATE
和 DELETE
語句] 複選框。 選取 [產生 INSERT
、 UPDATE
和 語句] 複選框后,[使用開放式並行存取] 複選框會變成可選取的複選框,將會增強WHERE
產生的 UPDATE
和 DELETE
DELETE
語句中的 子句,以提供開放式並行控制。 現在,將此複選框保持未核取;我們將在下一個教學課程中使用 SqlDataSource 控件來檢查開放式並行存取。
核取 [產生 INSERT
、 UPDATE
和 DELETE
語句] 複選框之後,按兩下 [確定] 傳回 [設定選取語句] 畫面,然後按 [下一步],然後按下 [完成],以完成 [設定數據源精靈]。 完成精靈時,Visual Studio 會將 BoundFields 新增至 、 ProductName
和 UnitPrice
數據行的 ProductID
DetailsView,以及數據行的 Discontinued
CheckBoxField。 從 DetailsView 的智慧標記中,核取 [啟用分頁] 選項,讓使用者瀏覽此頁面可以逐步執行產品。 同時清除DetailsView的 Width
和 Height
屬性。
請注意,智慧標記具有 [啟用插入]、[啟用編輯] 和 [啟用刪除] 選項可用。 這是因為 SqlDataSource 包含其 InsertCommand
、 UpdateCommand
和 DeleteCommand
的值,如下列宣告式語法所示:
<asp:DetailsView ID="ManageProducts" runat="server" AllowPaging="True"
AutoGenerateRows="False" DataKeyNames="ProductID"
DataSourceID="ManageProductsDataSource" EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="ManageProductsDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
DeleteCommand=
"DELETE FROM [Products] WHERE [ProductID] = @ProductID"
InsertCommand=
"INSERT INTO [Products] ([ProductName], [UnitPrice], [Discontinued])
VALUES (@ProductName, @UnitPrice, @Discontinued)"
SelectCommand=
"SELECT [ProductID], [ProductName], [UnitPrice], [Discontinued]
FROM [Products]"
UpdateCommand=
"UPDATE [Products] SET [ProductName] = @ProductName,
[UnitPrice] = @UnitPrice, [Discontinued] = @Discontinued
WHERE [ProductID] = @ProductID">
<DeleteParameters>
<asp:Parameter Name="ProductID" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="ProductName" Type="String" />
<asp:Parameter Name="UnitPrice" Type="Decimal" />
<asp:Parameter Name="Discontinued" Type="Boolean" />
<asp:Parameter Name="ProductID" Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="ProductName" Type="String" />
<asp:Parameter Name="UnitPrice" Type="Decimal" />
<asp:Parameter Name="Discontinued" Type="Boolean" />
</InsertParameters>
</asp:SqlDataSource>
請注意 SqlDataSource 控制項如何針對其 InsertCommand
、 UpdateCommand
和 DeleteCommand
屬性自動設定值。 和 UpdateCommand
屬性中所InsertCommand
參考的數據行集合是以 語句中的數據SELECT
行為基礎。 也就是說,除了 和UpdateCommand
中的每個 InsertCommand
Products 數據行之外,也只會省略 (ProductID
中指定的SelectCommand
數據行,因為它是一個IDENTITY
數據行,其值無法在編輯時變更,而且在插入) 時會自動指派。 此外,針對、 UpdateCommand
和屬性中的每個InsertCommand
參數,、 和 DeleteParameters
集合中有InsertParameters
UpdateParameters
對應的DeleteCommand
參數。
若要開啟 DetailsView 的數據修改功能,請檢查智慧標記中的 [啟用插入]、[啟用編輯] 和 [啟用刪除] 選項。 這會新增 CommandField,其ShowInsertButton
ShowEditButton
、 和 ShowDeleteButton
屬性設定為 True
。
瀏覽瀏覽器中的頁面,並記下 DetailsView 中包含的 [編輯]、[刪除] 和 [新增] 按鈕。 按兩下 [編輯] 按鈕會將DetailsView轉換成編輯模式,其中顯示每個 BoundField ReadOnly
屬性設定 False
為 (預設) 為 TextBox,以及 CheckBoxField 做為複選框。
圖 9:D etailsView 的預設編輯介面 (按兩下即可檢視大小完整的影像)
同樣地,您可以刪除目前選取的產品,或將新產品新增至系統。 InsertCommand
由於語句只適用於ProductName
、 UnitPrice
和 Discontinued
數據行,因此其他數據行在插入時,資料庫會指派NULL
其預設值。 就像 ObjectDataSource 一樣,如果 InsertCommand
遺漏任何不允許 NULL
且沒有預設值的資料庫數據表數據行,則嘗試執行 INSERT
語句時會發生 SQL 錯誤。
注意
DetailsView 的插入和編輯介面缺少任何類型的自定義或驗證。 若要新增驗證控件或自定義介面,您必須將 BoundFields 轉換為 TemplateFields。 如需詳細資訊 ,請參閱將驗證控件新增至編輯和插入介面 和 自定義數據修改介面 教學課程。
此外,請記住,若要更新和刪除,DetailsView 會使用目前的產品 DataKey
值,只有在設定屬性時 DataKeyNames
才會存在。 如果編輯或刪除似乎沒有任何作用,請確定 DataKeyNames
已設定 屬性。
自動產生 SQL 語句的限制
由於只有在從數據表挑選數據行時,才能使用 [產生 INSERT
、 UPDATE
和 DELETE
語句] 選項,因此針對更複雜的查詢,您必須撰寫自己的 INSERT
、 UPDATE
和 DELETE
語句,就像我們在步驟 1 中所做的一樣。 通常,SQL SELECT
語句會使用 JOIN
來從一或多個查閱數據表傳回數據,以供顯示 (,例如在顯示產品資訊時將數據表CategoryName
字段帶回 Categories
) 。 同時,我們可能會想要允許使用者編輯、更新或將數據插入核心數據表 (Products
,在此情況下) 。
INSERT
雖然 可以手動輸入 、 UPDATE
和 DELETE
語句,但請考慮下列省時提示。 一開始設定 SqlDataSource,讓它只從 Products
數據表提取數據。 使用 [設定數據源精靈] 的 [從數據表或檢視畫面指定數據行],以便自動產生 INSERT
、 UPDATE
和 DELETE
語句。 然後,完成精靈之後,選擇從 屬性視窗 (設定 SelectQuery,或者返回 [設定數據源精靈],但使用 [指定自定義 SQL 語句或預存程式] 選項) 。 然後更新 SELECT
語句以包含 JOIN
語法。 這項技術提供自動產生之 SQL 語句的省時優點,並允許更自定義 SELECT
的語句。
自動產生INSERT
、 UPDATE
和語句的另一個限制是 和 DELETE
UPDATE
語句中的數據INSERT
行是以語句所傳回的數據SELECT
行為基礎。 不過,您可能需要更新或插入更多或較少的欄位。 例如,在步驟 2 的範例中,或許我們想要讓 UnitPrice
BoundField 成為只讀的。 在此情況下,它不應該出現在 中 UpdateCommand
。 或者,我們可能會想要設定未出現在 GridView 中的數據表欄位值。 例如,新增記錄時,我們可能會想要將 QuantityPerUnit
值設定為 TODO 。
如果需要這類自定義,您必須透過 屬性視窗、在精靈中指定自定義 SQL 語句或預存程式選項,或透過宣告式語法手動進行自定義。
注意
在數據 Web 控制件中新增沒有對應欄位的參數時,請記住,這些參數值必須以某種方式指派值。 這些值可以是:直接在 或 UpdateCommand
中InsertCommand
編碼;可以來自某些預先定義的來源, (查詢字串、會話狀態、頁面上的 Web 控件等等) ;或者可以程式設計方式指派,如上一個教學課程中所見。
摘要
為了讓數據 Web 控制項利用其內建的插入、編輯和刪除功能,他們系結的數據源控件必須提供這類功能。 針對 SqlDataSource,這表示 INSERT
必須將、 UPDATE
和 DELETE
SQL 語句指派給 InsertCommand
、 UpdateCommand
和 DeleteCommand
屬性。 這些屬性和對應的參數集合可以透過 [設定數據源精靈] 手動新增或自動產生。 在本教學課程中,我們已檢查這兩種技術。
我們已在 實作開放式並行 存取教學課程中,使用開放式並行存取搭配 ObjectDataSource 來檢查。 SqlDataSource 控制件也提供開放式並行支援。 如步驟 2 所述,當自動產生 INSERT
、 UPDATE
和 DELETE
語句時,精靈會提供 [使用開放式並行存取] 選項。 如下一個教學課程所示,搭配 SqlDataSource 使用開放式並行存取會修改 WHERE
和 DELETE
語句中的 UPDATE
子句,以確保自從上次顯示數據之後,其他數據行的值尚未變更。
快樂的程序設計!
關於作者
Scott Mitchell 是七份 ASP/ASP.NET 書籍的作者,以及 自 1998 年以來與 Microsoft Web 技術合作的 4GuysFromRolla.com 作者。 Scott 是獨立顧問、訓練員和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 2.0。 您可以透過mitchell@4GuysFromRolla.com部落格來連線到 ,您可以在 找到http://ScottOnWriting.NET。
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應