2012-03-13 51 views
1

我想要使用ASP detailsview將變量傳遞給MSSQL存儲過程,然後將值插入到多個表。當我在SQL Management Studio中運行存儲過程時,存儲過程可以正常工作。我將所有存儲過程的變量設置爲參數,但當我的ASP頁面運行時,我仍然收到錯誤(下面)。我的ASP代碼和存儲過程也包含在錯誤消息的下面。「過程或函數具有太多的參數指定」錯誤時,從ASP頁運行插入查詢

任何幫助將不勝感激。這個問題開始變得非常令人沮喪。

錯誤消息:

Server Error in '/PrinterUsage' Application. 

Procedure or function Add_Count_By_Name has too many arguments specified. 

Description: An unhandled exception occurred during the execution of the current web     request. Please review the stack trace for more information about the error and where it   originated in the code. 

Exception Details: System.Data.SqlClient.SqlException: Procedure or function  Add_Count_By_Name has too many arguments specified. 

Source Error: 

An unhandled exception was generated during the execution of the current web request.  Information regarding the origin and location of the exception can be identified using the exception stack trace below. 

Stack Trace: 

[SqlException (0x80131904): Procedure or function Add_Count_By_Name has too many arguments specified.] 
System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +1950522 
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +4856715 
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) +194 
System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler,  SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1121 
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +200 
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +954 
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +162 
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +175 
System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +137 
System.Web.UI.WebControls.SqlDataSourceView.ExecuteDbCommand(DbCommand command, DataSourceOperation operation) +386 
System.Web.UI.WebControls.SqlDataSourceView.ExecuteInsert(IDictionary values) +227 
System.Web.UI.DataSourceView.Insert(IDictionary values, DataSourceViewOperationCallback callback) +86 
System.Web.UI.WebControls.DetailsView.HandleInsert(String commandArg, Boolean causesValidation) +274 
System.Web.UI.WebControls.DetailsView.HandleEvent(EventArgs e, Boolean causesValidation, String validationGroup) +676 
System.Web.UI.WebControls.DetailsView.OnBubbleEvent(Object source, EventArgs e) +95 
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37 
System.Web.UI.WebControls.DetailsViewRow.OnBubbleEvent(Object source, EventArgs e) +113 
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs args) +37 
System.Web.UI.WebControls.LinkButton.OnCommand(CommandEventArgs e) +118 
System.Web.UI.WebControls.LinkButton.RaisePostBackEvent(String eventArgument) +135 
System.Web.UI.WebControls.LinkButton.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +10 
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +13 
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +175 
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1565 

Version Information: Microsoft .NET Framework Version:2.0.50727.5448; ASP.NET Version:2.0.50727.5456 

ASP代碼:

<%@ Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="AddCount.aspx.cs" Inherits="AddCountClass" Theme="ThemeMain" %> 

<asp:SqlDataSource ID="NewCount_DS" Runat="server" ProviderName="System.Data.SqlClient" 
    ConnectionString="<%$ ConnectionStrings:PrinterUsageConnectionString %>" 
    DataSourceMode="DataReader" 
    InsertCommandType="StoredProcedure" InsertCommand="Add_Count_By_Name" 
    DeleteCommand="Add_Count_By_ID" DeleteCommandType="StoredProcedure" 
    SelectCommand="Get_Count_By_PrinterID" SelectCommandType="StoredProcedure" 
    UpdateCommand="Edit_Count_By_ID" UpdateCommandType="StoredProcedure" > 
    <InsertParameters> 
     <asp:Parameter Name="pName" Type="String" /> 
     <asp:Parameter Name="dMonth" Type="Int32" /> 
     <asp:Parameter Name="dYear" Type="Int32" /> 
     <asp:parameter Name="count" Type="Int32" /> 
     <asp:parameter Name="dID" Type="Int32" DefaultValue="0" /> 
     <asp:parameter Name="prevMonth_dID" Type="Int32" DefaultValue="0" /> 
     <asp:parameter Name="pID" Type="Int32" DefaultValue="0" /> 
     <asp:Parameter Name="monthUsage" Type="Int32" DefaultValue="0" /> 
    </InsertParameters> 
</asp:SqlDataSource> 

<asp:SqlDataSource ID="pName_DS" runat="server" ProviderName="System.Data.SqlClient" 
ConnectionString="<%$ ConnectionStrings:PrinterUsageConnectionString %>" 
DataSourceMode="DataReader" SelectCommandType="StoredProcedure" SelectCommand="Get_pNames" /> 

    <asp:DetailsView ID="AddPrinter_DV" runat="server" AutoGenerateInsertButton="True" 
     AutoGenerateRows="False" DataSourceID="NewCount_DS" 
     EnableModelValidation="True" DefaultMode="Insert" SkinID="detailsviewSkin" > 

     <Fields> 
      <asp:TemplateField HeaderText="Printer Name:" SortExpression="pName" > 
       <InsertItemTemplate> 
        <asp:DropDownList ID="pNameDropdown" runat="server" DataSourceID="pName_DS" 
         DataValueField="pName" DataTextField="pName" /> 
       </InsertItemTemplate> 
      </asp:TemplateField> 
      <asp:BoundField DataField="dMonth" HeaderText="Month" 
       SortExpression="dMonth" /> 
      <asp:BoundField DataField="dYear" HeaderText="Year" SortExpression="dYear" /> 
      <asp:BoundField DataField="countYtD" HeaderText="Count" 
       SortExpression="countYtD" /> 
     </Fields> 

    </asp:DetailsView> 

</asp:Content> 

SQL存儲過程:

ALTER PROCEDURE [dbo].[Add_Count_By_Name] 
--Declare variables 
@pName NVARCHAR(100), @dMonth INT, @dYear INT, @count INT, 
@dID INT, @prevMonth_dID INT, @pID INT, @monthUsage INT 
AS 
BEGIN 
--set variables 
SET @dID = NULL 
SET @prevMonth_dID = NULL 
SET @pID = NULL 
SET @monthUsage = NULL 
--check if the printer has been added to the system 
--if the printer is in the system, then save the pID to @pID 
--if the printer is not in the system, display error msg and stop stored procedure 
IF EXISTS (SELECT pID FROM PrinterTbl WHERE [email protected]) 
    BEGIN 
     SELECT @pID = pID FROM PrinterTbl WHERE [email protected]; 
    END 
ELSE 
    BEGIN 
     PRINT 'Printer name not found. Please verify that the printer has been added to the system'; 
     RETURN 1; 
    END 

--Check if the date has been added to the system 
--if date is in the system, save dID to @dID 
--if date is not in the system, add it to the system 
IF EXISTS (SELECT dId FROM DatesTbl WHERE [email protected] AND dYear[email protected]) 
    BEGIN 
     SELECT @dID = dId FROM DatesTbl WHERE [email protected] AND [email protected]; 
    END 
ELSE 
    BEGIN 
     INSERT INTO DatesTbl (dMonth, dYear) 
     VALUES (@dMonth, @dYear); 
     SELECT @dID = dId FROM DatesTbl WHERE [email protected] AND [email protected]; 
    END 

--Verify that neither @pID or @dID contain a null value, 
--then calculate the monthly usage and add the new count to CountTbl 
IF @pID IS NOT NULL AND @dID IS NOT NULL 
    BEGIN 
     --if the count is being added for January, manually set the month to December 
     --and subtract 1 from the year to obtain dID of December of the previous year. 
     --if adding a count for any month other than January, subtract 1 from @dMonth 
     --to obtain @prevMonth_dID 
     IF @dMonth = 1 
      BEGIN 
       SELECT @prevMonth_dID = dID FROM DatesTbl WHERE dMonth=12 AND dYear=(@dYear-1); 
      END 
     ELSE 
      BEGIN 
       SELECT @prevMonth_dID = (@dID-1); 
      END 
     --subtract the countYtd value from the previous month from the newly entered YtD count 
     --to obtain the monthly usage for the printer. 
     SELECT @monthUsage = @count - (SELECT countYtD FROM CountTbl WHERE dID = @prevMonth_dID); 

     --insert the new count record into CountTbl 
     INSERT INTO CountTbl (pID, dID, monthUsage, countYtD) 
     VALUES (@pID, @dID, @monthUsage, @count); 
    END 
END 
+0

您可以在跟蹤SQL Server事件探查器時運行查詢,以便可以確定實際傳遞給SQL Server的內容嗎? – 2012-03-13 17:22:29

+0

你能夠使用SQL Server Profiler嗎?您可能會看到將哪些代碼發送到服務器本身;這可能會使你指向正確的方向。 – 2012-03-13 17:24:14

回答

5

我想我是在黑暗中拍攝的,但是這個領域是否會造成問題?

<asp:BoundField DataField="countYtD" HeaderText="Count" 
     SortExpression="countYtD" /> 

數據源有count作爲參數,存儲過程也是這樣。 countYtD字段不存在,所以我認爲這將被自動添加,因爲它是一個綁定字段。

+0

@AdrianIftode擊敗了我! – TLS 2012-03-13 17:44:49

+0

我很欣賞你的答案,看起來是正確的,所以+1 :) – 2012-03-13 18:01:00

+0

請確保接受一個正確答案。 @AdrianIftode首先提交了答案,所以我建議接受他,所以他得到了信用。 – TLS 2012-03-13 18:03:06

6
<asp:BoundField DataField="countYtD" HeaderText="Count" 
       SortExpression="countYtD" /> 

這被綁定的字段,它會被添加作爲參數傳遞給存儲過程,不屬於參數列表。如果可能,請嘗試將其轉換爲TemplateField,並使用Eval代替Bind

2

是的,我在調用GridView的數據源更新方法時遇到同樣的錯誤。

數據源調用存儲過程來執行數據庫更新。

我糾正這個問題是這樣的:

首先,確保你聲明所有的SP參數中的數據源,包括在SP的DataKeys。

其次,要編輯的所有字段都使用<%# Bind("some Field") %>進行綁定。 不要綁定來自SELECT命令的任何其他字段。改爲使用EVAL()

三,名稱UPDATE參數必須匹配任何BIND()值的名稱。 AND所有更新參數必須綁定到輸入控件(文本框等)。

當數據源Update()方法被調用時,它將解析回發數據並查找所有BIND()值。這些值必須與更新參數定義中定義的NAMES匹配。

例如,我有一個Column。它有一個<ItemTemplate><EditItemTemplate>的定義。在<ItemTemplate>,我​​所選列名稱,

<ItemTemplate> <%# Eval("LastName") %> </ItemTemplate> 

<EditTemplate>,我宣佈一個<asp:textbox>控制接收來自SELECT命令中的「名字」值的值。

<EditItemTemplate> 
    <asp:TextBox ID="tbFirstName" runat="server" text='<%# Bind("FirstName") %>'></asp:textbox> 
</EditItemTemplate> 

在數據源更新PARAMATERS,我定義這個參數現在

<UpdateParameters> 
    <asp:parameter Name="FirstName" DbType="String" DefaultValue="" /> 
</UpdateParameters> 

,當頁面回,頁面會被解析併爲所有UPDATE PARAMATERS的值將提供來自其值爲BIND()且具有相同名稱UPDATE參數的控件。

任何參數名稱拼寫不匹配或任何額外的BIND()對於不包含在UPDATE參數中的值都會引發「太多參數」錯誤。

相關問題