查询中的 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 无效列名检测的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate 本机查询:无效的列名错误 SQL-17006