3

SqlDataSource にバインドされた GridView があります。UpdateCommand の実行で問題が発生しています。2 回実行されているようです。gvChecklist_RowUpdating イベントのコードをステップ実行すると、すべてが適切に実行され、ストアド プロシージャが実行されていることがわかります。db テーブルに新しいレコードがあるため、ストアド プロシージャが正しく動作することを確認しました。ただし、このイベントが終了すると、次のエラーが発生します。

プロシージャまたは関数 usp_TestLogInsert に指定された引数が多すぎます。

データソースの Updating イベントが RowUpdating イベントの後に呼び出されていることがわかります。複数の更新試行を防ぐためにこのイベントをキャンセルしようとしましたが、何も起こらず、GridView は編集モードのままです。

ASPコード

<asp:UpdatePanel ID="upGridView" runat="server" UpdateMode="Conditional">
  <ContentTemplate>
    <asp:GridView ID="gvChecklist" runat="server" 
                  AutoGenerateColumns="false" DataSourceID="dsChecklist"
                  AutoGenerateEditButton="true" 
                  onrowupdating="gvChecklist_RowUpdating">
      <Columns>
        <asp:TemplateField HeaderText="Status">
          <ItemTemplate>
            <asp:Label ID="lblStatus" runat="server" 
                       Text='<%#Eval("Status") %>' />
          </ItemTemplate>
          <EditItemTemplate>
            <asp:DropDownList ID="ddStatus" runat="server" 
                              DataTextField="Status" 
                              DataValueField="ID" 
                              DataSourceID="dsStatus" />
          </EditItemTemplate>
        </asp:TemplateField>
        <asp:BoundField DataField="Division" 
                        HeaderText="Division"
                        readonly="true" />
        <asp:BoundField DataField="Application"
                        HeaderText="Application"
                        readonly="true" />
        <asp:BoundField DataField="Task"
                        HeaderText="Task"
                        readonly="true" />
        <asp:BoundField DataField="TestedBy" 
                        HeaderText="Tested By" 
                        readonly="true"/>
        <asp:BoundField DataField="Notes" 
                        HeaderText="Notes" 
                        ReadOnly="false"/>
        <asp:BoundField DataField="JiraTicket"
                        HeaderText="JIRA Ticket"
                        readonly="false" />
        <asp:BoundField DataField="ID" />
      </Columns>
    </asp:GridView>
  </ContentTemplate>
  <Triggers>
    <asp:PostBackTrigger ControlID="gvChecklist" />
  </Triggers>
</asp:UpdatePanel>
</td>
</tr>
</table>

<asp:SqlDataSource ID="dsChecklist" 
                   SelectCommand=" SELECT l.ID, d.division, c.Context AS Application, t.Task, l.TestedBy, l.Notes, l.JiraTicket, s.Status
                                   FROM Automation.manual.Tests t
                                   OUTER APPLY 
                                         (SELECT TOP 1 *
                                          FROM Automation.manual.TestLog l
                                          WHERE l.TestID = t.ID 
                                          ORDER BY l.Date DESC) l
                                   INNER JOIN Automation.dbo.Context c ON  c.ID = t.Context
                                   INNER JOIN Automation.dbo.Division d ON d.ID = t.Division
                                   LEFT OUTER JOIN Automation.manual.Status s ON s.ID = l.Status"
                   runat="server"                                
                   ConnectionString="<%$ ConnectionStrings:AutomationDBConnectionString %>" 
                   onupdating="dsChecklist_Updating" >
  <UpdateParameters>
    <asp:Parameter Name="Status" DbType="Int32" />
    <asp:Parameter Name="TestID" DbType="Int32" />
    <asp:Parameter Name="TestedBy" DbType="String" />
    <asp:Parameter Name="Notes" DbType="String" />
    <asp:Parameter Name="JiraTicket" DbType="String" />
    <asp:Parameter Name="Build" DbType="String" />
  </UpdateParameters>
</asp:SqlDataSource>

C#

protected void gvChecklist_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
    SQLConnections sql = new SQLConnections();
    SqlDataSource dsChecklist = (SqlDataSource)LoginView1.FindControl("dsChecklist");
    var dd = (DropDownList)gvChecklist.Rows[e.RowIndex].FindControl("ddStatus");
    var status = dd.SelectedValue;
    var testID = sql.SQLSelectSingle(String.Format("SELECT ID FROM Automation.manual.Tests WHERE Task = '{0}'", (String)e.OldValues["Task"]), "pwautosql01");
    string user = Page.User.Identity.Name;
    string notes = (String)e.NewValues["Notes"];
    string jira = (String)e.NewValues["JiraTicket"];
    var dbID = e.NewValues["ID"];
    string build = "TODO";

    if (dbID == null) //Record does not exist in TestLog, INSERT a new one
    {
        dsChecklist.UpdateCommand = "[Automation].[manual].[usp_TestLogInsert]";
        dsChecklist.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure;

        dsChecklist.UpdateParameters["Status"].DefaultValue = status;
        dsChecklist.UpdateParameters["TestID"].DefaultValue = testID;
        dsChecklist.UpdateParameters["TestedBy"].DefaultValue = user;
        dsChecklist.UpdateParameters["Notes"].DefaultValue = notes;
        dsChecklist.UpdateParameters["JiraTicket"].DefaultValue = jira;
        dsChecklist.UpdateParameters["Build"].DefaultValue = build;

        gvChecklist.DataBind();
    }
    //else //Record already exists in TestLog. UPDATE
    //{
    //TODO
    //}
}

編集: SQL プロファイラーを使用して、ストアド プロシージャで送信されているパラメーターを確認しました。INSERT が発生して新しいレコードが作成されても、ID という追加のパラメーターが送信されています。このパラメーターを明示的に送信することはありませんが、GridView に ID という BoundField があるため、作成されたようです。元の質問に基づいて構築するには、UpdateCommand がこの BoundField を無視して、パラメーターとして自動的に使用しないようにする方法はありますか?

4

1 に答える 1

1

SQL プロファイラーを使用した後、BoundField ID が UpdateCommand パラメーターとして暗黙的に追加されていることがわかりました。このフィールドを TemplateItem に変更すると、この問題が修正されます。

                       <asp:TemplateField>
                        <ItemTemplate>
                            <asp:TextBox ID="tbId" Text='<%#Eval("ID") %>' ReadOnly="true" runat="server"></asp:TextBox>
                        </ItemTemplate>
                       </asp:TemplateField>
于 2013-07-05T15:44:22.583 に答える