簡體   English   中英

從ASP頁運行插入查詢時出現“過程或函數指定了太多參數”錯誤

[英]“Procedure or function has too many arguments specified” error when running insert query from ASP page

我試圖使用ASP detailsview將變量傳遞給MSSQL存儲過程,然后將值插入到多個表中。 當我在SQL Management Studio中運行它時,存儲過程非常有效。 我將所有存儲過程的變量設置為參數,但是當我的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 pName=@pName)
    BEGIN
        SELECT @pID = pID FROM PrinterTbl WHERE pName=@pName;
    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 dMonth=@dMonth AND dYear=@dYear)
    BEGIN
        SELECT @dID = dId FROM DatesTbl WHERE dMonth=@dMonth AND dYear=@dYear;
    END
ELSE
    BEGIN
        INSERT INTO DatesTbl (dMonth, dYear)
        VALUES (@dMonth, @dYear);
        SELECT @dID = dId FROM DatesTbl WHERE dMonth=@dMonth AND dYear=@dYear;
    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
 <asp:BoundField DataField="countYtD" HeaderText="Count" 
                SortExpression="countYtD" />

這是一個綁定字段,它將作為參數添加到存儲過程中,並且不屬於參數列表。 如果可能,嘗試將其轉換為TemplateField並使用Eval代替Bind

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

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

DataSource已count為參數,存儲過程也是如此。 countYtD字段不存在,所以我認為會自動添加,因為它是一個Bound Field。

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

數據源稱為存儲過程,用於對數據庫執行更新。

我用這種方式糾正了這個問題:

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

其次,使用<%# Bind("some Field") %>要編輯的所有字段。 請勿綁定SELECT命令中的任何其他字段。 請改用EVAL()

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

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

例如,我有一個專欄。 它具有<ItemTemplate><EditItemTemplate>定義。 <ItemTemplate> ,我Eval() SELECTED列Name,

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

<EditTemplate> ,我聲明了一個<asp:textbox>控件,以從SELECT命令接收“FirstName”值的值。

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

在數據源UPDATE參數中,我定義了這個參數

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

現在,當頁面回發時,將解析頁面,並且將從控件中提供所有UPDATE參數的值,這些控件的值為BIND() ,其名稱與UPDATE參數相同。

參數名稱拼寫中的任何不匹配,或任何EXTRA BIND()UPDATE參數中未包含的值都將引發“Too Many Parameters”錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM