2013-02-05 23 views
5

このタイプの質問は少なくとも十数回は要請されていますが、私はこれまでのすべての質問と回答を見てきました。私は適用を見つけた。私は自分のページでいくつかのFormViewオブジェクトを使用していますが、そのうちの1つを編集するオプションを追加します。 FormViewコントロールは、ストアドプロシージャにリンクSqlDataSourceコントロールによって移入ので、私はレコードを更新するストアドプロシージャを作り、次のようになりますSqlDataSourceコントロール、それを追加されます。プロシージャまたは関数 'xyz'に指定された引数が多すぎます

<asp:SqlDataSource ID="TestSqlDataSource" runat="server" 
        SelectCommandType="StoredProcedure" 
        ConnectionString="<%$ ConnectionStrings:development %>" 
        SelectCommand="usp_GetNewTestDetails" 
        UpdateCommand="usp_UpdateTest" 
        UpdateCommandType="StoredProcedure" 
        onupdating="TestSqlDataSource_Updating"> 
    <SelectParameters> 
     <asp:SessionParameter SessionField="TestID" Name="TestID"/> 
    </SelectParameters> 
    <UpdateParameters> 
     <asp:Parameter Name="testId" Type="Int32"/> 
     <asp:Parameter Name="testerLicense" Type="Int32" /> 
     <asp:Parameter Name="premiseOwner" Type="String" /> 
     <asp:Parameter Name="premiseAddress" Type="String" /> 
     <asp:Parameter Name="premiseCity" Type="String" /> 
     <asp:Parameter Name="premiseState" Type="String" /> 
     <asp:Parameter Name="premiseZip" Type="String" /> 
     <asp:Parameter Name="protectionType" Type="String" /> 
     <asp:Parameter Name="testType" Type="String" /> 
     <asp:Parameter Name="repairs" Type="String" /> 
     <asp:Parameter Name="notes" Type="String" /> 
     <asp:Parameter Name="testDate" Type="DateTime" /> 
     <asp:Parameter Name="employerName" Type="String" /> 
     <asp:Parameter Name="employerAddress" Type="String" /> 
     <asp:Parameter Name="phoneNumber" Type="String" /> 
     <asp:Parameter Name="emailAddress" Type="String" /> 
     <asp:Parameter Name="dataEntryName" Type="String" /> 
     <asp:Parameter Name="dataEntryPhone" Type="String" /> 
     <asp:Parameter Name="signature" Type="String" /> 
     <asp:Parameter Name="entryDate" Type="DateTime" /> 
    </UpdateParameters> 
</asp:SqlDataSource> 

私はレコードを更新しようとすると、クエリにパラメータが多すぎるというエラーが表示されます。私は、私のコード内のパラメータが、私のストアドプロシージャのものと正確に(名前、番号、さらには順序)一致することを三重チェックしました。

答えを見つけようとすると、this siteと表示されていたthis post(オリジナルがダウンしているように見えるため、archive.orgに移動しなければならなかった)が見つかりました。 trace関数にパラメータを追加するために提案した内容を適用しました。私が見つけたのは、私のストアドプロシージャには、selectプロシージャからのいくつかの "ルックアップ"値があり、それらは更新プロシージャにはないということでした。私が更新しようとしているテーブルはテスターのIDしか持っていませんが、ユーザーはそのテーブルも参照していますので、FormViewではこれらのフィールドは編集モードでは読み取り専用です。それを変更しようとしないでください。他のすべてのパラメータは整列しています...これらのルックアップ値だけがオフです。

私は、パラメータの特定のリストを含めることによって、それらのパラメータのみを使用するが、それは間違っているように見えると考えました。私は既にパラメータを指定しているので、私は困惑しています。選択されたストアドプロシージャのもので上書きされている場所はどこにも見えません。読み込み専用の値を使用しないように、どこで教えてください。

ユーザーが必要とするので、元のストアドプロシージャから削除したくありません。私がこれまでに思いついた解決策の1つは、ストアドプロシージャにそれらを追加してから、それらを使用しないことです。私はこれがうまくいくと確信していますが、それを修正するのではなく、問題を隠すだけです。


EDIT:追加コード、要求

あたりこれはtrace関数にパラメータを出力する方法である:

protected void TestSqlDataSource_Updating(object sender, SqlDataSourceCommandEventArgs e) 
{ 
    for (int i = 0; i < e.Command.Parameters.Count; i++) 
    { 
     Trace.Write(e.Command.Parameters[i].ParameterName); 
     if (e.Command.Parameters[i].Value != null) 
     { 
      Trace.Write(e.Command.Parameters[i].Value.ToString()); 
     } 
    } 
} 

これがために使用されるストアドプロシージャであります更新:

ALTER PROCEDURE [dbo].[usp_UpdateTest] 
    @testId INT , 
    @testerLicense INT , 
    @premiseOwner VARCHAR(50) , 
    @premiseAddress VARCHAR(150) , 
    @premiseCity VARCHAR(50) , 
    @premiseState VARCHAR(2) , 
    @premiseZip VARCHAR(10) , 
    @protectionType VARCHAR(11) , 
    @testType VARCHAR(2) , 
    @repairs VARCHAR(200) , 
    @notes VARCHAR(300) , 
    @testDate DATETIME , 
    @employerName VARCHAR(50) , 
    @employerAddress VARCHAR(150) , 
    @phoneNumber VARCHAR(25) , 
    @emailAddress VARCHAR(60) , 
    @dataEntryName VARCHAR(50) , 
    @dataEntryPhone VARCHAR(25) , 
    @signature VARCHAR(50) , 
    @entryDate DATETIME 
AS 
    BEGIN 
     SET NOCOUNT ON; 

     UPDATE dbo.Tests 
     SET  TesterLicense = @testerLicense , 
       PremiseOwner = @premiseOwner , 
       PremiseAddress = @premiseAddress , 
       PremiseCity = @premiseCity , 
       PremiseState = @premiseState , 
       PremiseZip = @premiseZip , 
       ProtectionType = @protectionType , 
       TestType = @testType , 
       Repairs = @repairs , 
       Notes = @notes , 
       TestDate = @testDate , 
       EmployerName = @employerName , 
       EmployerAddress = @employerAddress , 
       PhoneNumber = @phoneNumber , 
       EmailAddress = @emailAddress , 
       DataEntryName = @dataEntryName , 
       DataEntryPhone = @dataEntryPhone , 
       Signature = @signature , 
       EntryDate = @entryDate 
     WHERE TestID = @testId 
    END 
+0

スペルミスやデータ型の変換エラーがないか確認しましたか? –

+0

@RuchiRahulDoshiはい。私は両方のパラメータのセットをExcelにコピーし、行ごとに比較しました。それはここではあまりにも一般的な質問で最も一般的な問題だったので、私は彼らが正確であることを確認するために非常に慎重だった。渡しているすべてのパラメータを表示するために 'trace'を使いましたが、実際にはあまりにも多くの引数を渡していることを確かめることができますが、それを止める方法はわかりません。 – techturtle

+0

"usp_UpdateTest"と "TestSqlDataSource_Updating"を貼り付けてください。 –

答えて

6

これは私自身で解決しました。 Visual Studioがストアドプロシージャのスキーマに基づいて私用のテンプレートを作成したという事実に関連していました。テンプレートが自動生成された場合、<EditItemTemplate>セクション内のすべてのテキストボックスは、次のように生成されます:

<asp:TextBox ID="TestIDTextBox" runat="server" Text='<%# Bind("TestID") %>'/> 

はそれがこれを引き起こしたBind声明であることが判明しました。 VSは、Bindを使用して入力されたフィールドのパラメータを自動的に作成します。私は<UpdateParameters>セクションがこれを無効にするべきであると信じられていましたが、実際には逆でした。完全に今

<asp:TextBox ID="TestIDTextBox" runat="server" Text='<%# Eval("TestID") %>'/> 

作品:私はEvalBindからこれらのフィールド上のコードを変更することにより、それらのパラメータを渡すバックからこれらのいくつかの読み取り専用フィールドを防ぐことができました。


補遺:

が、これは、他の方向に同じ問題が発生することがわかりました。フィールドに印を付けて編集したくない場合は、このフィールドには更新が含まれていなければなりません(行IDなど)。そこには何も従っていないようですので、私はe.Command.Parameters.RemoveAt(あなたが例えばOnDeletingイベント中に不要なパラメータを削除することができます...、偶数の<UpdateParameters>セクションのどのような目的になりまし

+0

あなたのソリューションを試して、BindをEvalに置き換えました。 'プロシージャまたは関数' xyz '引数が多すぎますが、データが更新されていません。 –

+0

@ThandoTee 'すべての* Bind'ステートメントを' Eval'に置き換えたくない場合は、データを更新する予定の少数だけです。 'Eval'は読み取り専用コマンドなので、これらのフィールドは更新されません。 – techturtle

+0

あなたが思いついたソリューションを投稿してくれてありがとう。私はASPプログラマではありませんが、SQL Serverがエラーを起こしたときに他の人を助けることができます。 –

関連する問題