【问题标题】:How can I use a Session string in a SQL command?如何在 SQL 命令中使用会话字符串?
【发布时间】:2018-07-14 21:17:16
【问题描述】:

我正在尝试使用会话字符串变量作为 SQL 命令中的 WHERE 子句条件,下面是 C# 中的代码

static string strConn = ConfigurationManager.ConnectionStrings["pEAnUtWoRM"].ToString();
SqlConnection conn = new SqlConnection(strConn);

protected void Page_Load(object sender, EventArgs e)
{
        if (!Page.IsPostBack)
        {
            displayProfiles();
        }
}

private void displayProfiles()
{
       if (Session["email"] != null )
       {
            string email = Convert.ToString(Session["email"]);

            SqlCommand cmd = new SqlCommand("SELECT Student.Name FROM Student " +
            "LEFT JOIN Mentor ON Student.MentorID = Mentor.MentorID " +
            "WHERE Mentor.EmailAddr = " + email.ToString(), conn);

            SqlDataAdapter da = new SqlDataAdapter(cmd);

            DataSet result = new DataSet();

            conn.Open();
            da.Fill(result, "StudentProfile");
            conn.Close();

            gvProfileList.DataSource = result.Tables["StudentProfile"];
            gvProfileList.DataBind();
        }
}

连接字符串和SqlConnection 工作正常(它不在方法中),因为我已经在其他aspx 页面上对其进行了测试。错误说:

System.Data.SqlClient.SqlException:无法在da.Fill(result, "StudentProfile");上绑定多部分标识符

【问题讨论】:

  • 请不要对我们大喊大叫(粗体字是喊)。我们知道您是新人,因为您的个人资料。我们知道您需要帮助,因为您提出了一个问题。 :o)
  • SQL Injection alert - 您应该将您的 SQL 语句连接在一起 - 使用 参数化查询 来避免 SQL 注入 - 查看 Little Bobby Tables
  • 感谢大家对我提出问题的方式的反馈以及对我的建议。就像我说的那样,我是新来的,因此我真的不知道提出问题的正确方法,而且我不是一个强大的程序员。

标签: c# sql-server visual-studio session


【解决方案1】:

抛出异常是因为查询语法不正确,因为email.ToString()的值没有被适当地转义,导致如下查询:

SELECT
    Student.Name
FROM
    Student
LEFT JOIN
    Mentor ON Student.MentorID = Mentor.MentorID
WHERE
    Mentor.EmailAddr = email@outlook.com

我的假设是您的意图是生成以下查询,其中email.ToString() 的值(例如email@outlook.com在单引号之间

SELECT
    Student.Name
FROM
    Student
LEFT JOIN
    Mentor ON Student.MentorID = Mentor.MentorID
WHERE
    Mentor.EmailAddr = 'email@outlook.com'

一种可能的解决方法是在 SQL 命令中添加一个参数(例如@EmailAddress)并将电子邮件值分配给它,如下所示:

const string EMAIL_ADDRESS_PARAMETER_NAME = "@EmailAddress";

SqlCommand cmd = new SqlCommand("SELECT Student.Name FROM Student " +
    "LEFT JOIN Mentor ON Student.MentorID = Mentor.MentorID " +
    $"WHERE Mentor.EmailAddr={EMAIL_ADDRESS_PARAMETER_NAME}", conn);

cmd.Parameters.Add(EMAIL_ADDRESS_PARAMETER_NAME, SqlDbType.VarChar).Value = email;

【讨论】:

  • @EmailAddressconstant 变量 EMAIL_ADDRESS_PARAMETER_NAME 定义,建议不要使用多个相同的字符串值在代码的不同部分,这可能很容易导致错误(例如,拼写错误,在一个地方更改字符串而不在另一个地方更改字符串)。 $ 用于字符串插值。最后一行cmd.Parameters.Add...中添加了参数值。查询中没有连接输入。我在问题代码中留下了 +,我认为它是为了防止行太长。
  • 除了更好的安全性之外,参数化查询消除了根据类型将文字包含(或不包含)的需要,消除了在字符串中转义引号的需要,避免了将日期字符串文字格式化为特定方式,不需要小数分隔符(因文化而异),通过促进执行计划缓存重用来提高性能,并产生更易于维护的更简洁的代码。
猜你喜欢
  • 2014-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-27
  • 1970-01-01
  • 2012-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多