【问题标题】:Error converting data type nvarchar to int using stored procedure使用存储过程将数据类型 nvarchar 转换为 int 时出错
【发布时间】:2016-04-30 17:53:39
【问题描述】:

我知道这是一个相当常见的错误,但我似乎无法找到问题的根源。由于必须将数据输入两个不同的表,我正在尝试使用存储过程添加学生的详细信息,但出现此错误:

System.Data.dll 中出现“System.Data.SqlClient.SqlException”类型的异常,但未在用户代码中处理

附加信息:将数据类型 nvarchar 转换为 int 时出错。

关于 `myCommand.ExecuteNonQuery();

ASP.NET

<asp:SqlDataSource ID="courselist" runat="server" 
     ConnectionString='<%$ ConnectionStrings:ConnectionString %>' 
     SelectCommand="SELECT [course_name], [course_id] FROM [courses]">
</asp:SqlDataSource>
<asp:SqlDataSource ID="yearlist" runat="server" 
     ConnectionString='<%$ ConnectionStrings:ConnectionString %>' 
     SelectCommand="SELECT [year_id], [year_title] FROM [year]">
</asp:SqlDataSource>
<asp:SqlDataSource ID="advisor_tutor_list" runat="server" 
     ConnectionString='<%$ ConnectionStrings:ConnectionString %>'  
     SelectCommand="SELECT DISTINCT staff_records.f_name + ' ' + staff_records.l_name AS Name, staff_records.user_id FROM courses INNER JOIN staff_records ON courses.school = staff_records.school_id WHERE (courses.course_id = @course_id)">
     <SelectParameters>
        <asp:Parameter Name="course_id"></asp:Parameter>
    </SelectParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="status_list" runat="server" 
     ConnectionString='<%$ ConnectionStrings:ConnectionString %>' 
     SelectCommand="SELECT [status_id], [status] FROM [status]">
</asp:SqlDataSource>
<asp:SqlDataSource ID="current_academic_year" runat="server"  
     ConnectionString='<%$ ConnectionStrings:ConnectionString %>' 
     SelectCommand="SELECT [academic_year] FROM [academic_year]">
</asp:SqlDataSource>
<div class="row">
    <div class="col-12">
        <h1>Add Student Record</h1>
        <h5 class="subheading">Please use the form below to add a student:</h5>
        <div class="feedback blue" id="feedback" runat="server" visible="false">
            <asp:Label ID="feedback_text" runat="server" Text=""></asp:Label>
        </div>
    </div>
</div>
<div class="row">
    <div class="col-3">
        <img id="img_preview" src="images/default_profile.jpg" />
    </div>
    <div class="col-9">
        <div class="panel">
            <h3>Fill out Student Details:</h3>
            <h5>Profile Image:</h5>
            <asp:FileUpload ID="newimage" runat="server" onpropertychange="changeImg(this.value)" />
            <h5>First Name:</h5>
            <asp:TextBox CssClass="full-width" ID="f_nametext" runat="server"></asp:TextBox>
            <h5>Last Name:</h5>
            <asp:TextBox CssClass="full-width" ID="l_nametext" runat="server"></asp:TextBox>
            <h5>Password:</h5>
            <asp:TextBox ID="p_wordtext" CssClass="inline-button" runat="server"></asp:TextBox>
            <div class="button blue" id="generate_password_button">Create Password</div>
            <h5>Course:</h5>
            <asp:DropDownList CssClass="full-width" ID="courseddl" runat="server" DataSourceID="courselist" DataTextField="course_name" DataValueField="course_id" OnSelectedIndexChanged="courseddl_SelectedIndexChanged" AutoPostBack="true" OnDataBound="courseddl_DataBound"></asp:DropDownList>
            <h5>Year:</h5>
            <asp:DropDownList CssClass="full-width" ID="yearddl" runat="server" DataSourceID="yearlist" DataTextField="year_title" DataValueField="year_id"></asp:DropDownList>
            <h5>Date of Birth:</h5>
            <asp:TextBox ID="dob_calendar" CssClass="datepicker full-width" runat="server"></asp:TextBox>
            <h5>Part Time / Full Time Status:</h5>
            <asp:DropDownList CssClass="full-width" ID="enrolmentddl" runat="server">
                <asp:ListItem>Full Time</asp:ListItem>
                <asp:ListItem>Part Time</asp:ListItem>
            </asp:DropDownList>
            <h5>Personal Tutor:</h5>
            <asp:DropDownList ID="tutorddl" CssClass="full-width" runat="server" DataSourceID="advisor_tutor_list" DataTextField="Name" DataValueField="user_id"></asp:DropDownList>
            <h5>Advisor of Studies:</h5>
            <asp:DropDownList ID="advisorddl" CssClass="full-width" runat="server" DataSourceID="advisor_tutor_list" DataTextField="Name" DataValueField="user_id"></asp:DropDownList>
            <h5>Enrollment Status:</h5>
            <asp:DropDownList ID="statusddl" CssClass="full-width" runat="server" DataSourceID="status_list" DataTextField="status" DataValueField="status_id"></asp:DropDownList>
            <asp:DropDownList ID="academic_year_ddl" CssClass="full-width" runat="server" DataSourceID="current_academic_year" DataTextField="academic_year" DataValueField="academic_year" Visible="false"></asp:DropDownList>
            <asp:Button ID="updatebutton1" runat="server" Text="Add Student" OnClick="updatebutton1_Click" />
        </div>
    </div>
</div>`

C# 代码隐藏:

protected void courseddl_SelectedIndexChanged(object sender, EventArgs e) {
    string course_id = courseddl.SelectedValue;
    advisor_tutor_list.SelectParameters["course_id"].DefaultValue = course_id;
    advisor_tutor_list.DataBind();
}

protected void courseddl_DataBound(object sender, EventArgs e) {
    courseddl.Items.Insert(0, new ListItem("- Select -", ""));
}

protected void updatebutton1_Click(object sender, EventArgs e) {
    Random rand = new Random();
    int newRand;
    newRand = rand.Next(1, 99);

    Random hashrand = new Random();
    int newhashrand;
    newhashrand = hashrand.Next(1000000000, int.MaxValue);

    string f_name_data = f_nametext.Text;
    string l_name_data = l_nametext.Text;
    string pword_data = p_wordtext.Text;

    string email_domain = "@uni.ac.uk";
    string role = "5";

    courseddl.DataBind();

    string course_data = courseddl.SelectedValue;
    string year_data = yearddl.SelectedValue;
    string enrolment_data = enrolmentddl.SelectedValue;
    string tutor_data = tutorddl.SelectedValue;
    string advisor_data = advisorddl.SelectedValue;
    string status_data = statusddl.SelectedValue;

    academic_year_ddl.DataBind();

    string academic_year = academic_year_ddl.SelectedValue;
    string dob_text = dob_calendar.Text;

    //check user has uploaded a file and filled in all fields
    if (!newimage.HasFile || f_name_data == "" || l_name_data == "" || dob_text == "" || pword_data == "") {
        feedback.Visible = true;
        feedback_text.Text = "Please ensure you've uploaded an image and filled out all fields. ";
        return;
    }

    DateTime dob_data = Convert.ToDateTime(dob_text);
    string f_name_initial = f_nametext.Text.Substring(0, 1);

    string UpPath = Server.MapPath("~/images");
    string new_name = "";

    Random r = new Random();
    int rInt = r.Next(0, 10000);

    if (!Directory.Exists(UpPath)) {
       Directory.CreateDirectory(UpPath);
    } else {
       int imgSize = newimage.PostedFile.ContentLength;
       string imgName = newimage.FileName;
       new_name = rInt + imgName;
       string imgPath = "images/" + new_name;

       if (newimage.PostedFile.ContentLength > 1000000) {
          Page.ClientScript.RegisterClientScriptBlock(typeof(Page), "Alert", "alert('File is too big.')", false);
       } else {
          newimage.SaveAs(Server.MapPath(imgPath));
       }
    }

    string ConnectionString = WebConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
    SqlConnection myConnection = new SqlConnection(ConnectionString);

    myConnection.Open();

    string query = "Execute AddStudent @password, @email, @role_id, @reset_hash, @student_id, @f_name, @l_name, @course_id, @year, @dob, @parttime_fulltime, @personal_tutor_id, @advisor, @status_id, @academic_year, @profile_image";

    SqlCommand myCommand = new SqlCommand(query, myConnection);

    myCommand.Parameters.AddWithValue("@password", EncryptPassword(pword_data));
    myCommand.Parameters.AddWithValue("@email", f_name_initial + l_name_data + newRand + email_domain);
    myCommand.Parameters.AddWithValue("@role_id", role);
    myCommand.Parameters.AddWithValue("@reset_hash", newhashrand);
    myCommand.Parameters.AddWithValue("@student_id", "");
    myCommand.Parameters.AddWithValue("@f_name", f_name_data);
    myCommand.Parameters.AddWithValue("@l_name", l_name_data);
    myCommand.Parameters.AddWithValue("@course_id", course_data);
    myCommand.Parameters.AddWithValue("@year", year_data);
    myCommand.Parameters.AddWithValue("@dob", dob_data);
    myCommand.Parameters.AddWithValue("@parttime_fulltime", enrolment_data);
    myCommand.Parameters.AddWithValue("@personal_tutor_id", tutor_data);
    myCommand.Parameters.AddWithValue("@advisor", advisor_data);
    myCommand.Parameters.AddWithValue("@status_id", status_data);
    myCommand.Parameters.AddWithValue("@academic_year", academic_year);
    myCommand.Parameters.AddWithValue("@profile_image", new_name);

    myCommand.ExecuteNonQuery();

    myConnection.Close();

    Response.Redirect("studentrecords.aspx");
  }

  private string EncryptPassword(string password) {
     System.Security.Cryptography.SHA1 sha = System.Security.Cryptography.SHA1.Create();
     string hashed = System.Convert.ToBase64String(sha.ComputeHash(System.Text.UnicodeEncoding.Unicode.GetBytes(password)));
     return hashed.Length > 49 ? hashed.Substring(0, 49) : hashed;
}

存储过程:

CREATE PROCEDURE AddStudent 
    @password nvarchar(50),
    @email nvarchar(50),
    @role_id int,
    @reset_hash nvarchar(50),
    @student_id int,
    @f_name nvarchar(50),
    @l_name nvarchar(50),
    @course_id int,
    @year int,
    @dob datetime,
    @parttime_fulltime nvarchar(50),
    @personal_tutor_id int,
    @advisor int,
    @status_id int,
    @academic_year int,
    @profile_image nvarchar(max)
AS
    INSERT INTO users (password, email, role_id, reset_hash)
    VALUES (@password, @email, @role_id, @reset_hash);

    SET @student_id = SCOPE_IDENTITY()

    INSERT INTO student_records (user_id, f_name, l_name, course_id, year, dob, parttime_fulltime, personal_tutor_id, advisor, status_id, academic_year, profile_image)
    VALUES (@student_id, @f_name, @l_name, @course_id, @year, @dob, @parttime_fulltime, @personal_tutor_id, @advisor, @status_id, @academic_year, @profile_image)

Users表结构:

user_id int
password    nvarchar(50)    
email   nvarchar(50)    
role_id int 
reset_hash  nvarchar(50)

student_records表结构:

user_id int
f_name  nvarchar(50)    
l_name  nvarchar(50)    
course_id   int 
year    int
dob datetime
parttime_fulltime   nvarchar(50)    
profile_image   nvarchar(MAX)   
personal_tutor_id   int 
status_id   int 
academic_year   int 
home_email  nvarchar(256)   
advisor int 

任何帮助将不胜感激。

【问题讨论】:

  • usersstudent_records 的表结构是什么?
  • @AdamV 我用表格结构更新了我的答案
  • 在调用 ExecuteNonQuery 之前,您是否检查过每个参数的值?您对所有这些都使用字符串,并且有几个正在读取 SelectedValue,它可能是一个空字符串或不会成为 int 的东西。单步执行您的代码。

标签: c# asp.net sql-server visual-studio stored-procedures


【解决方案1】:

请试试这个

myCommand.Parameters.AddWithValue("@student_id", 0);

仔细检查所有这些属性,您不应向它们传递任何整数值

@role_id int
@student_id int
@course_id int
@year int
@personal_tutor_id int
@advisor int
@status_id int
@academic_year int

【讨论】:

    【解决方案2】:

    您的数据库表中的以下某些列可能是 int,假设是 nvarchar

    @email nvarchar(50),
    @reset_hash nvarchar(50),
    @f_name nvarchar(50),
    @l_name nvarchar(50),
    @parttime_fulltime nvarchar(50),
    @profile_image nvarchar(max)
    

    【讨论】:

    • 它们都是我表中的 nvarchar 值
    【解决方案3】:

    你不能这样传递 Student_id

    myCommand.Parameters.AddWithValue("@student_id", "");
    

    您必须改为传递一个 int 值。

    【讨论】:

      猜你喜欢
      • 2014-03-14
      • 1970-01-01
      • 2016-03-14
      • 2014-07-25
      • 1970-01-01
      • 1970-01-01
      • 2018-04-06
      • 2015-02-15
      • 2015-03-14
      相关资源
      最近更新 更多