2013-02-05 35 views
5

我知道這種類型的問題至少在SO上被問過十次,但我已經瀏覽了所有以前的問題和答案,我發現適用。我在頁面上使用了幾個FormView對象,現在想添加編輯其中一個的選項。 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 post,其中引用了this site(必須轉到archive.org,因爲原件似乎已關閉)。我應用了他們建議的將參數添加到trace函數的內容。我發現,在我的存儲過程中,select過程中有一些不在更新過程中的「查找」值。我試圖更新的表只有測試者的ID,但用戶也希望看到他們的名字,所以它引用該表,但在FormView中這些字段在編輯模式下是隻讀的,因此他們可以試圖改變它。所有其他參數排隊......只有那些查找值已關閉。

我認爲通過包含特定的參數列表來傳遞它只會使用這些參數,但這似乎是不正確的。現在我很難過,因爲我已經指定了參數,而且我看不到它們被選擇存儲過程中的參數覆蓋的地方。我在哪裏告訴它不要使用這些只讀值?

我不想從原始存儲過程中刪除它們,因爲它們將被用戶所需。到目前爲止,我提出的一個解決方法是將它們添加到存儲過程中,然後永遠不要使用它們。雖然我相當肯定這會起作用,但它只是掩蓋了問題而不是解決問題。


編輯:附加代碼,每個請求

這是該參數輸出至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>部分應該覆蓋這一點,但實際上卻是相反的。我能夠阻止這幾個只讀域從通過改變這些字段代碼傳回它們的參數從BindEval

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

完美的作品了。


附錄:

發現,這將導致在其他方向上的相同問題,以及。如果您將不希望編輯的字段標記爲Eval,但需要將其包含在更新中(例如行ID),則該字段將不起作用,此時參數太少。我現在想知道<UpdateParameters>這一節的用途是什麼,因爲它似乎沒有遵循任何內容......

+0

我試過你的解決方案,用Eval替換綁定。它不會給我錯誤「過程或函數」xyz'指定了太多參數',但數據不會更新 –

+0

@ThandoTee您不想用'Eval'替換所有* Bind'語句,只有少數不應該更新數據。 'Eval'是一個只讀命令,所以它不會更新這些字段。 – techturtle

+0

感謝您發佈您提出的解決方案。我不是一個ASP程序員,但是它會讓我在SQL Server咳嗽時幫助其他人。 –

1

您可以在例如OnDeleting事件(e.Command.Parameters.RemoveAt)期間刪除不需要的參數(一世))。

相關問題