2013-02-05 9 views
5

Wiem, że tego typu pytanie było zadawane co najmniej kilkanaście razy na SO, ale przeszedłem przez wszystkie poprzednie pytania i odpowiedzi, które mogłem znaleźć tutaj i żadne Znalazłem zastosowanie. Korzystam z kilku obiektów FormView na mojej stronie, a teraz chcę dodać opcję edycji jednego z nich. FormView jest wypełniana przez SqlDataSource połączonego z procedury przechowywanej, więc zrobiłem procedurę przechowywaną, aby zaktualizować rekordy i dodaje go do SqlDataSource, który teraz wygląda tak:Procedura lub funkcja 'xyz' ma zbyt wiele argumentów określonych

<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> 

Przy próbie aktualizacji rekordu, Otrzymuję błąd, który mówi, że w moim zapytaniu jest zbyt wiele parametrów. Potrwałem trzykrotnie, czy parametry w moim kodzie pasują dokładnie (nazwa, numer, a nawet kolejność) do tych w mojej procedurze przechowywanej.

Próbując znaleźć odpowiedzi, natknąłem się na this post, które zawierało odniesienie do this site (musiałem przejść do archive.org, ponieważ oryginał wydaje się być wyłączony). Zastosowałem to, co zaproponowali, aby dodać parametry do funkcji trace. Odkryłem, że w mojej procedurze przechowywanej jest kilka wartości "wyszukiwania" z procedury wyboru, które nie są w procedurze aktualizacji. Tabela, którą próbuję aktualizować, ma tylko identyfikator testera, ale użytkownicy chcieliby również zobaczyć jej nazwę, więc odwołuje się do tej tabeli, ale w FormView te pola są tylko do odczytu w trybie edycji, więc mogą "Spróbuj to zmienić. Wszystkie pozostałe parametry są wyrównane ... tylko wartości wyszukiwania są wyłączone.

Pomyślałem, że poprzez uwzględnienie określonej listy parametrów do przekazania, które użyłoby tylko tych parametrów, ale wydaje się, że jest niepoprawna. Teraz jestem zakłopotany, ponieważ już określiłem parametry i nie widzę nigdzie, że są one nadpisywane tymi z wybranej zapisanej procedury. Gdzie mam powiedzieć, żeby nie używać tych wartości tylko do odczytu?

Nie chcę ich usuwać z oryginalnej procedury składowanej, ponieważ będą potrzebne użytkownikom. Jedynym sposobem obejścia tego problemu jest dodanie ich do procedury składowanej, a następnie po prostu nigdy ich nie używam. Chociaż jestem prawie pewien, że to zadziała, to tylko zasłania problem, zamiast go naprawiać.


Edycja: kod dodatkowy, na życzenie

To jest metoda, która generuje parametry w trace funkcję:

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()); 
     } 
    } 
} 

Jest to procedura przechowywane używany do aktualizacja:

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

Czy sprawdziłeś, czy są jakieś błędy ortograficzne lub błąd konwersji typu danych? –

+0

@RuchiRahulDoshi Tak. Skopiowałem oba zestawy parametrów do Excela i przeszedłem porównanie linii po linii. To był najczęstszy problem w tym zbyt powszechnym pytaniu tutaj, więc bardzo ostrożnie upewniłem się, że są dokładne. Używając funkcji 'trace' do wyświetlenia wszystkich parametrów, które przekazuje, mogę stwierdzić z całą pewnością, że przekazuje ona zbyt wiele argumentów, ale nie wiem, jak to wyłączyć. – techturtle

+0

Czy możesz wkleić "usp_UpdateTest" i "TestSqlDataSource_Updating" tutaj, jeśli nie masz nic przeciwko. –

Odpowiedz

6

Skończyłem wymyślać to na własną rękę. Było to związane z faktem, że Visual Studio utworzyło dla mnie szablony oparte na schemacie procedury składowanej. Gdy szablony są wygenerowany automatycznie, każde pole tekstowe w sekcji <EditItemTemplate> zostanie wygenerowany tak:

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

Okazuje się, że jest to stwierdzenie Bind który spowodował to. VS automatycznie tworzy parametr dla dowolnego pola wypełnionego przy użyciu Bind. Chociaż doprowadzono mnie do przekonania, że ​​sekcja <UpdateParameters> powinna to zmienić, była odwrotnie.Udało mi się uniknąć tych kilka pól tylko do odczytu z przechodząc z powrotem swoje parametry przez zmianę kodu w tych dziedzinach od Bind do Eval:

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

roboty doskonale teraz.


Uzupełnienie:

Stwierdzono, że powoduje to ten sam problem w drugim kierunku. Jeśli zaznaczysz pole, którego nie chcesz edytować jako Eval, ale musi ono zostać uwzględnione w aktualizacji (takiej jak identyfikator wiersza), nie będzie działać, tym razem dla zbyt małej liczby parametrów. Zastanawiam się teraz, jaki jest cel sekcji <UpdateParameters>, ponieważ nie wydaje się, aby coś tam było ...

+0

Próbowałem Twojego rozwiązania, zastępując Binda opcją Eval. Nie daje mi błędu "Procedura lub funkcja" xyz "zawiera zbyt wiele argumentów", ale dane nie są aktualizowane –

+0

@ThandoTee Nie chcesz zastępować * wszystkich * instrukcji 'Bind' za pomocą' Eval', tylko nieliczni, którzy nie powinni aktualizować danych. 'Eval' jest poleceniem tylko do odczytu, więc nie zaktualizuje tych pól. – techturtle

+0

Dzięki za opublikowanie rozwiązania, które wymyśliłeś. Nie jestem programistą ASP, ale pozwoli mi to pomagać innym, gdy SQL Server wykrztusza z sukcesem błąd. –

1

Możesz usunąć niepożądane parametry podczas np. Zdarzenia OnDeleting (e.Command.Parameters.RemoveAt (ja)).

Powiązane problemy