【问题标题】:Procedure or function expects parameter which was not supplied - Parameter is in stored procedure(I think)过程或函数需要未提供的参数 - 参数在存储过程中(我认为)
【发布时间】:2016-06-08 13:20:20
【问题描述】:

我遇到了一个绝对让我发疯的错误。原谅我,我是新手,所以我可能会错过一些愚蠢或愚蠢的东西,所以提前抱歉。

我不断收到错误

“程序或函数‘prcPersonalSelectedByPatientIdAppointmentSelect’需要参数‘@PatientNumber’,但未提供。”

这让我感到莫名其妙,因为“@PatientNumber”在存储过程中,但我对 SQL 的了解并不是最丰富的。

ASPX 代码

<asp:UpdatePanel ID="pnlUpdate" runat="server">
        <ContentTemplate>
            <asp:Panel ID="pnlResults" runat="server" ScrollBars="Auto" >
                <asp:GridView ID="gvAppointmentSearch" runat="server" Font-Names = "Arial" 
                    Font-Size = "11pt" ForeColor = "#000000"
                    onselectedindexchanged="gvAppointmentSearch_SelectedIndexChanged" 
                    AutoGenerateColumns = "false" DataKeyNames="PatientNumber" AllowPaging = "true"
                    OnPageIndexChanging = "OnPaging" PageSize = "10" Width = "100%" 
                    HeaderStyle-BackColor = "#465c71" HeaderStyle-ForeColor = "#ffffff" 
                    style="margin-bottom: 26px"> 

                    <Columns>
                        <%--Creates a select button that appear at the start of the grid view--%>
                       <asp:TemplateField>
                            <ItemTemplate>
                                <asp:LinkButton Text="Select" ID="lnkSelect" runat="server" CommandName="Select" />
                            </ItemTemplate>
                        </asp:TemplateField>

                        <asp:TemplateField HeaderText="Appointment Number" ItemStyle-Wrap="False">
                            <ItemTemplate>
                                <%--This will be the first field to appear beside the select button--%>
                                <asp:Label ID="lblAppointmentNumber" Text='<%# Eval("AppointmentNumber") %>' runat="server" />
                            </ItemTemplate>
                        </asp:TemplateField>
                            <%--Bound fields will place them in a specific order--%>
                            <asp:BoundField DataField = "AppointmentDate" HeaderText = "Appointment Date" DataFormatString="{0:d}" />
                            <asp:BoundField DataField = "AppointmentTime" HeaderText = "Appointment Time" DataFormatString="{0:d}" />
                            <asp:BoundField DataField = "Consultant" HeaderText="Referred By" ItemStyle-Wrap="False" />
                            <asp:BoundField DataField = "ByAttendance" HeaderText="Attendance"/>
                    </Columns> 
                </asp:GridView>
            </asp:Panel>
        </ContentTemplate>
    <Triggers>
    <asp:AsyncPostBackTrigger ControlID="gvAppointmentSearch" />
    </Triggers>
    </asp:UpdatePanel>

C# 代码

protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            //Populate dropdown if no record has been selected
            String strConString = ConfigurationManager.ConnectionStrings["OepdSQLConnectionString"].ConnectionString;
            SqlConnection conn = new SqlConnection(strConString);
            conn.ConnectionString = strConString;
            SqlCommand cmdInit = new SqlCommand();
            cmdInit.CommandText = "Select * from DropdownCounty";
            cmdInit.Connection = conn;
            conn.Open();
            DataTable dtInit = new DataTable();
            dtInit.Load(cmdInit.ExecuteReader());
            conn.Close();
            dpdCounty.DataSource = dtInit;
            dpdCounty.DataTextField = "County";
            dpdCounty.DataValueField = "CountyID";
            dpdCounty.DataBind();
            DataSet ds = new DataSet();
            ds = (DataSet)Session["DS"];
            this.DataBindSearch();

            try
            {
                //Fields that are required to be filled in if the information is avaliable
                patientNumber.Text = ds.Tables[0].Rows[0]["PatientNumber"].ToString();
                txtHCNumber.Text = ds.Tables[0].Rows[0]["HC_Number"].ToString();
                //if (ds.Tables[0].Rows[0]["ConsentToDatabase"].ToString() != null)
                //chkDBConsent.Checked = (bool)ds.Tables[0].Rows[0]["ConsentToDatabase"];

                if (ds.Tables[0].Rows[0]["ConsentGivenDate"].ToString() != "dd/mm/yyyy")
                {
                    if (ds.Tables[0].Rows[0]["ConsentGivenDate"].ToString() != null && ds.Tables[0].Rows[0]["ConsentGivenDate"].ToString() != "")
                    {
                        ConsentGivenDate.Text = Convert.ToDateTime(ds.Tables[0].Rows[0]["ConsentGivenDate"].ToString()).ToShortDateString();
                    }
                }
                IDnumberLegacy.Text = ds.Tables[0].Rows[0]["ID_Number_LegacyID"].ToString();
                if (ds.Tables[0].Rows[0]["Sex"] != DBNull.Value)
                {
                    //Datasource is added only when values are being added to allow for alterations to be made 
                    //Allows for records with older dropdown values no longer selectable to be visible
                    String strConnString = ConfigurationManager.ConnectionStrings["OepdSQLConnectionString"].ConnectionString;
                    SqlConnection con = new SqlConnection(strConnString);
                    con.ConnectionString = strConnString;
                    SqlCommand cmd = new SqlCommand();
                    SqlCommand cmdPop = new SqlCommand();

                    cmd.CommandText = "Select Sex from DropdownSex";

                    cmd.Connection = con;
                    con.Open();
                    DataTable dt = new DataTable();

                    dt.Load(cmd.ExecuteReader());
                    con.Close();

                    //String builder to gather records that are currently active
                    StringBuilder currentid = new StringBuilder();

                    for (int i = dt.Rows.Count - 1; i >= 0; i--)
                    {
                        DataRow dr = dt.Rows[i];

                        currentid.AppendLine(string.Join(",", dr.ItemArray));
                    }

                    //convert stringbuilder to string
                    var output = currentid.ToString();

                    // Creates new StringReader instance from System.IO
                    using (StringReader reader = new StringReader(output))
                    {
                        // Loop over the lines in the string.
                        int count = 0;
                        string line;
                        while ((line = reader.ReadLine()) != null)
                        {
                            count++;

                            if (line == (ds.Tables[0].Rows[0]["Sex"].ToString()))
                                cmdPop.CommandText = " Select * From DropdownSex";
                        }
                    }

                    if (cmdPop.CommandText == "")
                        cmdPop.CommandText = " Select * From DropdownSex";

                    cmdPop.Connection = con;
                    con.Open();
                    DataTable dtValues = new DataTable();
                    dtValues.Load(cmdPop.ExecuteReader());
                    con.Close();
                    dpdSex.DataSource = dtValues;
                    dpdSex.DataTextField = "Sex";
                    dpdSex.DataValueField = "SexID";
                    dpdSex.DataBind();
                    dpdSex.SelectedValue = ds.Tables[0].Rows[0]["SexID"].ToString();
                }
                txtPatientFirstName.Text = ds.Tables[0].Rows[0]["Forename"].ToString();
                txtPatientSurname.Text = ds.Tables[0].Rows[0]["Surname"].ToString();
                PatientMaiden.Text = ds.Tables[0].Rows[0]["MaidenName"].ToString();
                if (ds.Tables[0].Rows[0]["DateOfBirth"].ToString() != "dd/mm/yyyy")
                {
                    if (ds.Tables[0].Rows[0]["DateOfBirth"].ToString() != null && ds.Tables[0].Rows[0]["DateOfBirth"].ToString() != "")
                    {
                        txtDateOfBirth.Text = Convert.ToDateTime(ds.Tables[0].Rows[0]["DateOfBirth"].ToString()).ToShortDateString();
                    }
                }
                AddressLine1.Text = ds.Tables[0].Rows[0]["AddressLine1"].ToString();
                AddressLine2.Text = ds.Tables[0].Rows[0]["AddressLine2"].ToString();
                AddressLine3.Text = ds.Tables[0].Rows[0]["AddressLine3_TownCity"].ToString();
                AddressLine4.Text = ds.Tables[0].Rows[0]["AddressLine4_Region"].ToString();
                if (ds.Tables[0].Rows[0]["County"] != DBNull.Value)
                {
                    //Datasource is added only when values are being added to allow for alterations to be made 
                    //Allows for records with older dropdown values no longer selectable to be visible
                    String strConnString = ConfigurationManager.ConnectionStrings["OepdSQLConnectionString"].ConnectionString;
                    SqlConnection con = new SqlConnection(strConnString);
                    con.ConnectionString = strConnString;
                    SqlCommand cmd = new SqlCommand();
                    SqlCommand cmdPop = new SqlCommand();
                    cmd.CommandText = "Select County from DropdownCounty";

                    cmd.Connection = con;
                    con.Open();
                    DataTable dt = new DataTable();

                    dt.Load(cmd.ExecuteReader());
                    con.Close();

                    //String builder to gather records that are currently active
                    StringBuilder currentid = new StringBuilder();

                    for (int i = dt.Rows.Count - 1; i >= 0; i--)
                    {
                        DataRow dr = dt.Rows[i];

                        currentid.AppendLine(string.Join(",", dr.ItemArray));
                    }

                    //convert stringbuilder to string
                    var output = currentid.ToString();

                    // Creates new StringReader instance from System.IO
                    using (StringReader reader = new StringReader(output))
                    {
                        // Loop over the lines in the string.
                        int count = 0;
                        string line;
                        while ((line = reader.ReadLine()) != null)
                        {
                            count++;

                            if (line == (ds.Tables[0].Rows[0]["County"].ToString()))
                                cmdPop.CommandText = " Select * From DropdownCounty";
                        }
                    }

                    if (cmdPop.CommandText == "")
                        cmdPop.CommandText = " Select * From DropdownCounty";

                    cmdPop.Connection = con;
                    con.Open();
                    DataTable dtValues = new DataTable();

                    dtValues.Load(cmdPop.ExecuteReader());
                    con.Close();
                    dpdCounty.DataSource = dtValues;
                    dpdCounty.DataTextField = "County";
                    dpdCounty.DataValueField = "CountyID";
                    dpdCounty.DataBind();
                    dpdCounty.SelectedValue = ds.Tables[0].Rows[0]["CountyID"].ToString();
                }
                PostCode.Text = ds.Tables[0].Rows[0]["PostCode"].ToString();
                HomeTelNumber.Text = ds.Tables[0].Rows[0]["HomeTelNumber"].ToString();
                MobileTelNumber.Text = ds.Tables[0].Rows[0]["MobileTelNumber"].ToString();
                WorkTelNumber.Text = ds.Tables[0].Rows[0]["WorkTelNumber"].ToString();
                PatientEmail.Text = ds.Tables[0].Rows[0]["Email"].ToString();
                PatientNotes.Text = ds.Tables[0].Rows[0]["Notes"].ToString();
                //Sets the color of the text box depedning if a value has been entered
                string hex = "#F0F8FF";
                if (txtDateOfBirth.Text != "dd/mm/yyyy")
                    txtDateOfBirth.ForeColor = System.Drawing.Color.Black;
                else
                    txtDateOfBirth.BackColor = System.Drawing.ColorTranslator.FromHtml(hex);

                if (ConsentGivenDate.Text != "dd/mm/yyyy")
                    ConsentGivenDate.ForeColor = System.Drawing.Color.Black;
                else
                    ConsentGivenDate.BackColor = System.Drawing.ColorTranslator.FromHtml(hex);
            }

            //If the dataset is empty this is executed instead
            catch (Exception fe)
            {
                lblErrors.Text = "New Record Successfully Started!";

                //calls the poup to display a notification
                dvMsg.Visible = true;
                lblMsg.Text = "" + lblErrors.Text;
            }
        }
        //Not required as this label has been replaced with a popup, still used to store message that will be displayed
        lblErrors.Visible = true;
        //Load the initial data from the session once
        //***Custom error messages below***//
        //Used to pull error message if someone else has already updated the data first
        if (Session["ex"] != null)
        {
            var msg = Session["ex"].ToString();
            //Message to be displayed
            if (msg == "Error")
                lblErrors.Text = "Update Failed! Someone has already made changes!";
            else
                lblErrors.Text = "Unable to update HC Number!";

            //calls the popup to display a notification
            dvMsg.Visible = true;
            lblMsg.Text = "" + lblErrors.Text;

            //required to prevent error message appearing everytime the page loads
            Session["ex"] = null;
        }

        //As the page refreshes when a new record is added to allow the master page to display the new records details this is required to pull
        //forward the success message to inform the user that the record has been added and the page has not just refreshed
        if (Session["NewRecordAdded"] != null)
        {
            //Message to be displayed
            lblErrors.Text = "Record Succesfully Added!";

            //calls the popup to display a notification
            dvMsg.Visible = true;
            lblMsg.Text = "" + lblErrors.Text;

            //required to prevent error message appearing everytime the page loads
            Session["NewRecordAdded"] = null;
        }

        //Error when trying to find record that does not exist
        if (Session["FindRecordError"] != null)
        {
            string a = Session["FindRecordError"].ToString();
            //Message to be displayed
            if (a == "Unable to locate")
                lblErrors.Text = "Unable to find record!";
            else
                lblErrors.Text = "Full HC Number required!";

            //calls the popup to display a notification
            dvMsg.Visible = true;
            lblMsg.Text = "" + lblErrors.Text;

            //required to prevent error message appearing everytime the page loads
            Session["FindRecordError"] = null;
        }

        if (Session["PersonalDeatilsSave"] != null)
        {
            //only if an update has occured
            lblErrors.Text = "Save Successful!";

            //calls the popup to display a notification
            dvMsg.Visible = true;
            lblMsg.Text = "" + lblErrors.Text;

            //required to prevent error message appearing everytime the page loads
            Session["PersonalDeatilsSave"] = null;
        }
    }

    protected void gvAppointmentSearch_SelectedIndexChanged(object sender, EventArgs e)
    {

        DataSet ds = new DataSet();
        int index = gvAppointmentSearch.SelectedIndex;

        string strConString = ConfigurationManager.ConnectionStrings["OepdSQLConnectionString"].ConnectionString;
        SqlConnection myConnect = new SqlConnection(strConString);
        myConnect.ConnectionString = strConString;

        string strCommandText = "prcPersonalSelectedByPatientIdAppointmentRetrieve";

        try
        {
            SqlCommand sqlCmd = new SqlCommand(strCommandText, myConnect);
            sqlCmd.CommandType = CommandType.StoredProcedure;

            sqlCmd.Parameters.Add(new SqlParameter("@PatientNumber", gvAppointmentSearch.DataKeys[index].Value.ToString()));

            SqlDataAdapter da = new SqlDataAdapter();
            da.SelectCommand = sqlCmd;
            da.Fill(ds, "personal");

            //Needed to reset the clinical eval page for newly selected patient
            Session["NDS"] = null;
        }

        catch (Exception fe)
        {
            lblMoreErrors.Text = "Error: " + fe.Message;
        }

        try
        {
            //Assigns the selected patients details to the dataset and redirects the user to the personal page
            Session["DS"] = ds;
            Response.Redirect("~/UserPages/PatientAppointment.aspx");
        }

        catch (Exception er)
        {
            lblErrors.Text = "Error: " + er.Message;
        }
    }

    //Tells the gridview what to do when the page change is selected
    protected void OnPaging(object sender, GridViewPageEventArgs e)
    {
        this.DataBindSearch();
        gvAppointmentSearch.PageIndex = e.NewPageIndex;
        gvAppointmentSearch.DataBind();
    }

    protected void DataBindSearch()
    {

        DataSet ds = new DataSet();
        string strConString = ConfigurationManager.ConnectionStrings["OepdSQLConnectionString"].ConnectionString;
        SqlConnection myConnect = new SqlConnection(strConString);
        myConnect.ConnectionString = strConString;
        string strCommandText = "prcPersonalSelectedByPatientIdAppointmentSelect";

        try
        {
            SqlCommand sqlCmd = new SqlCommand(strCommandText, myConnect);
            sqlCmd.CommandType = CommandType.StoredProcedure;
            SqlDataAdapter da = new SqlDataAdapter();
            da.SelectCommand = sqlCmd;
            da.Fill(ds, "personal");

            gvAppointmentSearch.DataSource = ds;
            //Finally, all results matching the criteria will be placed into the gridview
            gvAppointmentSearch.DataBind();
            DataTable dt = new DataTable();
            da.Fill(dt);
            Session["CurrentData"] = dt;
            //Counts the number of results found
            lblResults.Text = "Results Found: " + ds.Tables.Cast<DataTable>().Sum(x => x.Rows.Count).ToString();
        }

        catch (Exception fe)
        {
            lblErrors.Text = "Error: " + fe.Message;
        }
    }

    }

SQL 存储过程

ALTER PROCEDURE [dbo].[prcPersonalSelectedByPatientIdAppointmentSelect]
@PatientNumber int
AS
SELECT 
[dbo].[Appointments].[AppointmentDate] as AppointmentDate
,dbo.Appointments.AppointmentTime as AppointmentTime
,[dbo].[DropdownReferredBy].[ReferredBy] as Consultant
,[dbo].[DropdownAttended].[ByAttendance] as ByAttendance
,dbo.Appointments.AppointmentNumber as AppointmentNumber
  FROM [dbo].[PATIENTS] 
  LEFT JOIN dbo.Appointments on dbo.PATIENTS.PatientNumber = dbo.Appointments.PatientNumber
  LEFT JOIN [dbo].[DropdownReferredBy] on dbo.Appointments.ReferredBy = [dbo].[DropdownReferredBy].ReferredBy
  LEFT JOIN [dbo].[DropdownAttended] on dbo.Appointments.ByAttendance = dbo.DropdownAttended.ByAttendance

  WHERE dbo.PATIENTS.PatientNumber LIKE @PatientNumber

  ORDER BY AppointmentNumber ASC;

为了增加这一切,这个页面从另一个带有连接存储过程的 gridview 中获取数据。

提前感谢,如果我做了一些非常愚蠢的事情,请见谅!!!

【问题讨论】:

    标签: c# sql asp.net sql-server web


    【解决方案1】:

    在您的 DataBindSearch() 方法中,您没有为 @PatientNumber 参数提供值。您需要指定该参数并为其指定一个值,就像您在代码中所做的那样。

    另外,虽然我引起了您的注意,但您确实应该将 SqlConnection 和 SqlCommand 对象放在 using 语句中。

    protected void DataBindSearch()
    {
        DataSet ds = new DataSet();
        string strConString = ConfigurationManager.ConnectionStrings["OepdSQLConnectionString"].ConnectionString;
        string strCommandText = "prcPersonalSelectedByPatientIdAppointmentSelect";
    
        using (SqlConnection myConnect = new SqlConnection(strConString))
        using (SqlCommand sqlCmd = new SqlCommand(strCommandText, connect))
        {
            try
            {
                SqlCommand sqlCmd = new SqlCommand(strCommandText, myConnect);
                sqlCmd.CommandType = CommandType.StoredProcedure;
    
                //You need to add the parameter before you call da.Fill()
                sqlCmd.Parameters.Add(new SqlParameter("@PatientNumber", /*Parameter Value*/));
    
                SqlDataAdapter da = new SqlDataAdapter();
                da.SelectCommand = sqlCmd;
                da.Fill(ds, "personal");
    
                gvAppointmentSearch.DataSource = ds;
                //Finally, all results matching the criteria will be placed into the gridview
                gvAppointmentSearch.DataBind();
                DataTable dt = new DataTable();
                da.Fill(dt);
                Session["CurrentData"] = dt;
                //Counts the number of results found
                lblResults.Text = "Results Found: " + ds.Tables.Cast<DataTable>().Sum(x => x.Rows.Count).ToString();
            }
    
            catch (Exception fe)
            {
                lblErrors.Text = "Error: " + fe.Message;
            }
        }
    }
    

    【讨论】:

    • 嗨@Hill 感谢您的回答 - 但是 - 我在 sqlCmd.Parameters.Add(new SqlParameter("@PatientNumber", gvAppointmentSearch.DataKeys[index].Value.ToString( )));正如它所说的“当前上下文中不存在名称'index'”
    • @karlb123 我的错,我已经编辑了我的答案。你需要用你想要的 PatientNumber 替换那部分行
    • 我认为您的原始答案是正确的,因为它从 SQL 调用数据以在页面加载时创建网格视图。然而,不幸的是它无法正常工作
    • 您没有为该参数提供值这一事实绝对是问题所在。这个值是什么或者你从哪里得到是你需要弄清楚的,抱歉。
    • 感谢您的帮助 - 我的大脑终于弄清楚了为什么它不起作用。我正在尝试搜索尚未调用的索引
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 2013-01-24
    • 1970-01-01
    相关资源
    最近更新 更多