- toto
- 常連さん
- 会議室デビュー日: 2005/10/18
- 投稿数: 46
- お住まい・勤務地: 岡山
|
投稿日時: 2007-03-27 13:31
環境
Visual Studio 2005
.NET Framework 2.0
SQL server 2003
Windows XP
sqlDataSourceとGridViewを使用して、ショッピングカートの機能を作成しています。
cart.aspxの初期表示で、カートの内容を表示します。
カートに入っている商品を削除したい場合には、商品(行)の削除ボタンを押下すると、該当商品をカートテーブル(DB)より削除して、カートを再表示しようとしています。
カートの表示は問題なく行われますが、削除ボタンを押下したタイミングで、下記のエラーが表示されます。
エラーメッセージ「プロシージャまたは関数 DeleteItemOfCart の引数が多すぎます。 」
具体的に、どの様に修正すれば上記のエラー表示を回避できるのかをご教授ねがいます。
よろしくお願いします。
コード: |
|
-- cart.aspx --
<asp:GridView ID="GridViewCart" runat="server" AutoGenerateColumns="False" DataKeyNames="ItemCode"
DataSourceID="SqlDataSource1" ShowFooter="True" GridLines="None">
<Columns>
<asp:TemplateField HeaderText="削除" ShowHeader="False">
<ItemTemplate>
<asp:Button ID="Button1" runat="server" CausesValidation="False" CommandName="Delete"
OnClientClick="return confirm('本当に削除しても良いですか?')" Text="削除" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ItemCode" HeaderText="商品コード" ReadOnly="True" SortExpression="ItemCode" />
<asp:BoundField DataField="ItemName" HeaderText="商品名" SortExpression="ItemName" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:DatabaseConnectionString %>"
DeleteCommand="DeleteItemOfCart" DeleteCommandType="StoredProcedure" SelectCommand="GetItemOfCart"
SelectCommandType="StoredProcedure">
<DeleteParameters>
<asp:SessionParameter Name="i_UserId" SessionField="UserId" Type="String" />
<asp:ControlParameter ControlID="GridViewCart" Name="i_ItemCode" PropertyName="SelectedDataKey" Type="String" />
</DeleteParameters>
<SelectParameters>
<asp:SessionParameter Name="i_UserId" SessionField="UserId" Type="String" />
<asp:SessionParameter Name="i_ItemCode" SessionField="CustomerCode" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
-- GetItemOfCartプロシージャー --
ALTER PROCEDURE supplies.GetItemOfCart
(
@i_UserId char(20),
@i_CustomerCode int
)
AS
(以下、省略)
-- DeleteItemOfCartプロシージャー --
ALTER PROCEDURE supplies.DeleteItemOfCart
(
@i_UserId char(20),
@i_ItemCode char(15)
)
AS
(以下、省略)
|
|
- Jitta
- ぬし
- 会議室デビュー日: 2002/07/05
- 投稿数: 6267
- お住まい・勤務地: 兵庫県・海手
|
投稿日時: 2007-03-27 18:21
楽観的同時実行制御 じゃないかなぁ?
ストアドのほうの引数をひとつずつ増やして、エラーが出なくなったら、なにが送られているか確認するとか。
_________________
|
- toto
- 常連さん
- 会議室デビュー日: 2005/10/18
- 投稿数: 46
- お住まい・勤務地: 岡山
|
投稿日時: 2007-03-28 09:40
>Jittaさん
いつも返信ありがとうございます。
引用: |
|
Jittaさんの書き込み (2007-03-27 18:21) より:
楽観的同時実行制御 じゃないかなぁ?
ストアドのほうの引数をひとつずつ増やして、エラーが出なくなったら、なにが送られているか確認するとか。
|
考え方に間違いがあればご指摘ください。
GridViewのDataKeyNamesに設定されたKeyは、SqlDataSourceのDeleteのタイミングで自動的に、DeleteParametersとして追加される。
そこで、DeleteのストアドのInパラメーターにItemCodeのパラメーターを追記しました。
コード: |
|
ALTER PROCEDURE supplies.DeleteItemOfCart
(
@ItemCode char(15), -- 追加
@i_UserId char(20),
@i_ItemCode char(15)
)
AS
|
上記の様にすると、「〜引数が多すぎます。」エラーは発生しなくなりました。
しかし、今度はストアドでデータの削除ができません。
@ItemCodeをKeyにDeleteを行うと、下記のエラーが発生します。
「指定された引数は、有効な値の範囲内にありません。」
@i_ItemCodeをKeyにDeleteを行うと、エラーは発生しませんが、データは削除されずにストアドが終了します。
GridViewのDataKeyNamesに設定した、KeyをGridViewCart.SelectedDataKeyで取得できると思っているのですが。
ストアドに渡す前のパラメーターをブレイクなどで確認できるのでしょうか。
よろしくお願いします。
|
- べる
- ぬし
- 会議室デビュー日: 2003/09/20
- 投稿数: 1093
|
投稿日時: 2007-03-28 15:27
引用: |
| GridViewのDataKeyNamesに設定した、KeyをGridViewCart.SelectedDataKeyで取得できると思っているのですが。
| CommandName="Delete"であり「Select」してないのでSelectedDataKeyでは
取得できません。それに、PropertyName="SelectedDataKey"としても、
SelectedDataKeyはDataKey型なのでうまくいかないと思います。
引用: |
| ストアドに渡す前のパラメーターをブレイクなどで確認できるのでしょうか。
| Delete操作ならSqlDataSource1.OnDeletingのイベントハンドラを作れば確認できます。
(ハンドラの引数であるSqlDataSourceCommandEventArgsからCommandが取れます)
ご提示のGridViewでやってみましがた@ItemCodeには削除ボタンを押した行のItemCodeがわたってました。
ストアド側の引数を3つにしなくてもGridView側の@i_ItemCodeを消せばOKでしょうね。
引用: |
| @ItemCodeをKeyにDeleteを行うと、下記のエラーが発生します。
「指定された引数は、有効な値の範囲内にありません。」
| 当方ではうまく削除されました。(←テーブル定義とか適当ですから)別の問題かもしれませんね。
|
- toto
- 常連さん
- 会議室デビュー日: 2005/10/18
- 投稿数: 46
- お住まい・勤務地: 岡山
|
投稿日時: 2007-03-29 10:52
べるさん
返信ありがとうございます。
引用: |
| CommandName="Delete"であり「Select」してないのでSelectedDataKeyでは
取得できません。それに、PropertyName="SelectedDataKey"としても、
SelectedDataKeyはDataKey型なのでうまくいかないと思います。
|
そうだったんですね。
SelectedDataKeyはDeleteでも、「削除ボタン」で行を選択しているので取得できるものだと思い込んでいました。お恥ずかしい。。。
引用: |
| Delete操作ならSqlDataSource1.OnDeletingのイベントハンドラを作れば確認できます。(ハンドラの引数であるSqlDataSourceCommandEventArgsからCommandが取れます)
|
これは、よい方法を聞きました。
この方法で試してみると、確かにItemCodeとUserIdが渡っていました。
引用: |
| ご提示のGridViewでやってみましがた@ItemCodeには削除ボタンを押した行のItemCodeがわたってました。
ストアド側の引数を3つにしなくてもGridView側の@i_ItemCodeを消せばOKでしょうね。
@ItemCodeをKeyにDeleteを行うと、下記のエラーが発生します。
「指定された引数は、有効な値の範囲内にありません。」
|
わざわざ、試していただいて、恐縮です。
これは、引数にSelectedDataKeyを渡していた関係でエラーとなっていたようです。
SelectedDataKeyを渡さない様にすると上手くいきました。
■ポイント
・DataKeyNamesで設定された値は、Delete(多分Insertも)コマンドでは自動的にパラメータとして追加される。
・SelectedDataKeyの値は、Selectコマンドの時のみ取得可能。
■悩みどころ
・DataKeyNamesの値は自動的に追加されるが、その際にパラメーター名はSelectの列名に依存するので、自由に設定できない?ここは、Selectの際にDeleteで使用するパラメーター名に合わせるしか方法がないのでしょうか。i_ItemCodeみたいに。
皆さんありがとうございました。
最後に動作したコードを。
コード: |
|
-- cart.aspx --
<asp:GridView ID="GridViewCart" runat="server" AutoGenerateColumns="False" DataKeyNames="ItemCode"
DataSourceID="SqlDataSource1" ShowFooter="True" GridLines="None">
<Columns>
<asp:TemplateField HeaderText="削除" ShowHeader="False">
<ItemTemplate>
<asp:Button ID="Button1" runat="server" CausesValidation="False" CommandName="Delete"
OnClientClick="return confirm('本当に削除しても良いですか?')" Text="削除" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="ItemCode" HeaderText="商品コード" ReadOnly="True" SortExpression="ItemCode" />
<asp:BoundField DataField="ItemName" HeaderText="商品名" SortExpression="ItemName" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:DatabaseConnectionString %>"
DeleteCommand="DeleteItemOfCart" DeleteCommandType="StoredProcedure" SelectCommand="GetItemOfCart"
SelectCommandType="StoredProcedure">
<DeleteParameters>
<asp:SessionParameter Name="i_UserId" SessionField="UserId" Type="String" />
</DeleteParameters>
<SelectParameters>
<asp:SessionParameter Name="i_UserId" SessionField="UserId" Type="String" />
<asp:SessionParameter Name="i_ItemCode" SessionField="CustomerCode" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
-- GetItemOfCartプロシージャー --
ALTER PROCEDURE supplies.GetItemOfCart
(
@i_UserId char(20),
@i_CustomerCode int
)
AS
(以下、省略)
-- DeleteItemOfCartプロシージャー --
ALTER PROCEDURE supplies.DeleteItemOfCart
(
@i_UserId char(20),
@ItemCode char(15)
)
AS
(以下、省略)
|
|