查询中的 SQL 无效列名检测

Posted

技术标签:

【中文标题】查询中的 SQL 无效列名检测【英文标题】:SQL Invalid Column name detection from Query 【发布时间】:2017-01-05 19:27:00 【问题描述】:

我已尝试运行代码,但不知道查询出了什么问题。因为它一直说无效的列名,所以当我尝试从该列中检索数据时。列名与数据库中的列名匹配。它连接良好,因为它连接到一个登录表单,在该表单中它检测到另一个给定的密码和名称。我正在使用基于搜索文本框。

private void btnSearch_Click(object sender, EventArgs e)
   
    SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDetailConnectionString"].ToString());

    try
    
        cnn.Open();
        SqlCommand command = new SqlCommand();
        command.Connection = cnn;
        string query = "SELECT *FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";
        command.CommandText = query;
        SqlDataReader reader = command.ExecuteReader();
        while (reader.Read())
        
          ---[Converting String from db /Insert to textboxes]---
        
        cnn.Close();
    
    catch (Exception ex)
    
        MessageBox.Show("Error" + ex);
    

【问题讨论】:

您应该使用参数化查询。但是在您当前的 sql-injectable 查询中,您需要在字符串值周围使用'"SELECT * FROM AffiliatedRegister WHERE Username='" + txtUser.Text + "'" *FROM 之间不需要空格吗? 检查您的数据库架构并确保您没有任何拼写错误,列名可以是UserName vs Username 【参考方案1】:

您的语句出错了,因为您没有将字符串括在引号中,因此 Sql 将其插入为对象而不是字符串。话虽如此,您应该使用参数而不是字符串连接。

    使用参数 将 SqlConnection 包装在 using 块中 您应该在 SELECT 语句中指定列顺序,不要使用 *。 除非您知道如何从中恢复,否则不要吞下异常

更新代码

private void btnSearch_Click(object sender, EventArgs e)

    // use ConnectionString property
    // wrap in using block
    using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDetailConnectionString"].ConnectionString))
    
        try
        
            SqlCommand command = new SqlCommand();
            command.Connection = cnn;
            // use parameters
            // avoid *, specify columns instead
            string query = "SELECT * FROM AffiliatedRegister WHERE Username= @userName";
            command.CommandText = query;
            // use parameters, I assumed the parameter type and length - it should be updated to the type and length specified in your table schema
            command.Parameters.Add(new SqlParameter("@userName", SqlDbType.VarChar, 200) Value = txtUser.Text );

            // open as late as possible
            cnn.Open();
            SqlDataReader reader = command.ExecuteReader();
            while (reader.Read())
            
                // ---[Converting String from db / Insert to textboxes]-- -
            
        
        catch (Exception ex)
        
            MessageBox.Show("Error" + ex); 

            // do not swallow the exception unless you know how to recover from it
            throw;
        
    

【讨论】:

谢谢,我会尝试更多地练习参数。它解决了我的问题。【参考方案2】:

您需要将用户名文本用引号括起来。

您发出的 sql 脚本将如下所示:

SELECT *FROM AffiliatedRegister WHERE Username=InputUserName

所以 SQL 正在尝试将列 Username 与列 InputUsername 进行比较。

将用户名用引号括起来后,它将是:

SELECT *FROM AffiliatedRegister WHERE Username='InputUserName'

【讨论】:

我还建议让 OP 学习如何构造参数化查询.. 感谢您的建议。将尝试更多地关注该领域。【参考方案3】:

首先,您的查询非常危险,因此请不要将其用于生产目的。 现在你需要做什么:- 在您的查询中,您需要在 txtUser.Text 周围加上单引号。 像这样:-

"SELECT *FROM AffiliatedRegister WHERE Username='" + txtUser.Text + "'";

查询结果:SELECT *FROM AffiliatedRegister WHERE Username = 'txtUser.Text';

您也可以使用双引号,例如:-

...用户名=\"" + txtUser.Text + "\"";

它很复杂 ;-) 较早的版本更适合阅读。

为什么它没有运行? 因为除整数之外的所有值都必须在查询中的单引号或双引号内传递。喜欢:-

SELECT * FROM TABLE_NAME WHERE TABLE_NAME.COLUMN_NAME = "VALUE";

现在有一件非常重要的事情,请不要将这些类型的查询用于生产目的。我猜你正处于开发阶段,所以回答这个问题不会毁了你的生活......!!!

【讨论】:

【参考方案4】:

您可以尝试替换您的字符串:string query = "SELECT *FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";

收件人:string query = "SELECT <yourcolumn> FROM AffiliatedRegister WHERE Username=" + txtUser.Text + "";

我认为有必要指定列名。

最好的问候

【讨论】:

以上是关于查询中的 SQL 无效列名检测的主要内容,如果未能解决你的问题,请参考以下文章

列名无效是啥意思?

sql 查询 - 无效的列名

Hibernate 本机查询:无效的列名错误 SQL-17006

我有这个错误:java.sql.SQLException:Java 应用程序中的列名无效

SQL - 在 DAO 中执行时列名无效

hibernate创建本地查询后进行查询的时候报错: could not execute query;列名无效