简体   繁体   English

从ASP页运行插入查询时出现“过程或函数指定了太多参数”错误

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

I am trying to use an ASP detailsview to pass variables to an MSSQL stored procedure that then inserts values into multiple tables. 我试图使用ASP detailsview将变量传递给MSSQL存储过程,然后将值插入到多个表中。 The stored procedure works perfectly when I run it in SQL Management Studio. 当我在SQL Management Studio中运行它时,存储过程非常有效。 I have all of the stored procedure's variables set as parameters, yet I am still getting an error (below) when my ASP page runs. 我将所有存储过程的变量设置为参数,但是当我的ASP页面运行时,我仍然收到错误(下面)。 My ASP code and stored procedure are also included below the error message. 我的ASP代码和存储过程也包含在错误消息下面。

Any help would be greatly appreciated. 任何帮助将不胜感激。 This problem is starting to get extremely frustrating. 这个问题开始变得非常令人沮丧。

Error Message: 错误信息:

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 code: 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 Stored Procedure: 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" />

This being a bound field, it will be added as a parameter to the stored procedure and does not belong to the parameters list. 这是一个绑定字段,它将作为参数添加到存储过程中,并且不属于参数列表。 Try, if possible, transform it into a TemplateField and use Eval instead Bind . 如果可能,尝试将其转换为TemplateField并使用Eval代替Bind

I think I'm shooting in the dark here, but is this field causing the problems? 我想我在黑暗中拍摄,但这个领域是否会引发问题?

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

The DataSource has count as a parameter, and so does the stored procedure. DataSource已count为参数,存储过程也是如此。 The countYtD field doesn't exist, so I think that would be added automatically because it's a Bound Field. countYtD字段不存在,所以我认为会自动添加,因为它是一个Bound Field。

Yes, I experienced the same error while calling the Update Method of the data source for a gridview. 是的,我在为gridview调用数据源的更新方法时遇到了同样的错误。

The data source called a stored procedure to perform the update to the database. 数据源称为存储过程,用于对数据库执行更新。

I corrected the problem this way: 我用这种方式纠正了这个问题:

First, make sure you declare all of your SP parameters in the for the data source, include the DataKeys in the SP. 首先,确保在数据源中声明所有SP参数,在SP中包含DataKeys。

Second, all of the fields that you want to edit are bound using <%# Bind("some Field") %> . 其次,使用<%# Bind("some Field") %>要编辑的所有字段。 DO NOT bind any other fields from the SELECT command. 请勿绑定SELECT命令中的任何其他字段。 Use EVAL() instead. 请改用EVAL()

Third, the names of UPDATE Parameters MUST MATCH the names of any BIND() values. 第三, UPDATE参数的名称必须匹配任何BIND()值的名称。 AND ALL update parameters must be BOUND to a input control (textbox, etc). AND ALL更新参数必须绑定到输入控件(文本框等)。

When the Data Source Update() method is called, it will parse the postback data and look for all BIND() values. 调用Data Source Update()方法时,它将解析回发数据并查找所有BIND()值。 These values MUST match the NAMES defined in the Update Parameters definitions. 这些值必须与更新参数定义中定义的NAMES匹配。

For example, I have an Column. 例如,我有一个专栏。 It has both an <ItemTemplate> and <EditItemTemplate> definition. 它具有<ItemTemplate><EditItemTemplate>定义。 In the <ItemTemplate> , I Eval() the SELECTED column Name, <ItemTemplate> ,我Eval() SELECTED列Name,

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

In the <EditTemplate> , I have declared a <asp:textbox> control to receive the value of the "FirstName" value from the SELECT Command. <EditTemplate> ,我声明了一个<asp:textbox>控件,以从SELECT命令接收“FirstName”值的值。

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

In the data source UPDATE paramaters, I defined this parameter 在数据源UPDATE参数中,我定义了这个参数

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

Now, when the page posts back, the page will be parsed and the values for all of the UPDATE paramaters will be supplied from the controls whose values were BIND() with the same name of the UPDATE parameter. 现在,当页面回发时,将解析页面,并且将从控件中提供所有UPDATE参数的值,这些控件的值为BIND() ,其名称与UPDATE参数相同。

Any mismatch in either spelling of parameter names, or any EXTRA BIND() 's for values NOT included in the UPDATE parameters will throw the "Too Many Parameters" error. 参数名称拼写中的任何不匹配,或任何EXTRA BIND()UPDATE参数中未包含的值都将引发“Too Many Parameters”错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM