【问题标题】:Concatenation in C# with SQL Query for Access DatabaseC# 中的连接与 Access 数据库的 SQL 查询
【发布时间】:2012-01-31 01:56:23
【问题描述】:

我有一个带有 C# 的 Access Db,我在 where 子句之后的 sql 查询中进行连接,但出现以下错误

“查询表达式中的语法错误(缺少运算符)”

我的代码在下面

cmd.CommandText = "Select * from TEMP1 WHERE EMAIL=" + GlobalData.Email; 

请告诉我是什么导致了错误以及连接的正确语法是什么。

【问题讨论】:

    标签: c# sql ms-access


    【解决方案1】:

    你最好使用SqlParameter(更安全):

    SqlCommand cmd = new SqlCommand("SELECT * FROM Temp1 WHERE Email LIKE @email")
    cmd.Parameters.Add(new SqlParameter("email", GlobalData.Email));
    

    回答原来的问题:

    使用直接连接,没有字符串分隔符,你的查询变成:

    SELECT * FROM Temp1 WHERE Email LIKE email@email.com
    

    而不是

    SELECT * FROM Temp1 WHERE Email LIKE 'email@email.com'
    

    【讨论】:

    • 可以删除第一个吗?第二个更安全。
    【解决方案2】:

    我认为您的问题是缺少引号。试试这个:

    cmd.CommandText = "Select * from TEMP1 WHERE EMAIL='" + GlobalData.Email + "'"; 
    

    但如果您不验证电子邮件,该方法可能会导致 SQL 注入。虽然上面的代码并没有什么问题,但是如果验证了数据,我还是更喜欢使用 SQL 参数:

    SqlCommand cmd = new SqlCommand( "SELECT * FROM Temp1 WHERE Email = @Email" )
    cmd.Parameters.Add( new SqlParameter( "Email" , GlobalData.Email ) );
    

    【讨论】:

    • 是的,查询中的字符串必须放在引号中。
    • 如果数据来自用户输入(很有可能),则查询对 SQL 注入开放。
    • @Guffa 一个验证有效电子邮件的正则表达式解决了这个问题。我会假设询问者在保存到数据库之前验证响应,因为在验证后不可能进行非常结构化的字符串,例如电子邮件注入。
    • @AndrewJackman:你不能仅仅假设验证就在那里并且是安全的。很高兴您添加了有关它的注释。 :)
    【解决方案3】:

    尝试改用Parameterised queries。出于安全原因和可读性考虑,这通常是处理 SQL 查询时的常态。

    【讨论】:

      【解决方案4】:

      字符串文字周围没有任何撇号,因此您的查询最终会像:

      Select * from TEMP1 WHERE EMAIL=someone@somesite.com
      

      这当然会导致语法错误。您需要字符串周围的撇号:

      cmd.CommandText = "Select * from TEMP1 WHERE EMAIL='" + Replace(GlobalData.Email, "'", "''") + "'";
      

      但是,正确编码字符串并非易事。 (上述方法适用于 Access 和 Microsoft SQL Server,但其他数据库需要其他方法。)您应该使用参数化查询:

      cmd.CommandText = "Select * from TEMP1 WHERE EMAIL=@email";
      

      然后你给命令对象添加一个参数,例如:

      cmp.Parameters.Add("@email", DbType.VarChar, 300).Value = GlobalData.Email;
      

      【讨论】:

        【解决方案5】:

        试试下面的方法

        cmd.CommandText = "Select * from TEMP1 WHERE EMAIL='" + GlobalData.Email + "'"; 
        

        【讨论】:

        • 这对 SQL 注入开放。你至少应该提到这一点。
        【解决方案6】:

        我不确定这个错误,但你应该这样尝试

        cmd.CommandText = string.Format("SELECT * FROM TEMP1 WHERE EMAIL='{0}'", GlobalData.Email);
        

        这样你就不需要弄乱丑陋的连接,顺便说一句,占用大量内存。

        【讨论】:

        • 如果数据来自用户输入(很有可能),则查询对 SQL 注入开放。
        • 内存使用曾经是真实的(在 .Net 2.0 和更早版本中),但现在,由于编译器优化,这种丑陋的混乱是最有效的连接方法 (codeproject.com/Articles/303158/…)
        • 其实Francois B.给你的例子比我用SqlParameters好很多。
        • 验证在许多用途中非常有用,但如果同时使用 SqlParam 和验证,它会更安全。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-31
        • 1970-01-01
        相关资源
        最近更新 更多