- PR -

「プロシージャまたは関数 〜 の引数が多すぎます。」エラーについて

1
投稿者投稿内容
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
(以下、省略)

1

スキルアップ/キャリアアップ(JOB@IT)