我在VS2015中使用C#和MySQl来查询我的数据库,并在名为"方法"的VARCHAR类型列中返回信息。但是,查询返回字符串"方法",而不是方法列的值。
下面是代码:
string queryOne = "SELECT " + "@columnName" + " FROM log.transactions";
MySqlCommand cmdOne = new MySqlCommand(queryOne, connectionString);
cmdOne.Parameters.AddWithValue("@columnName", "method");
MySqlDataReader dataReaderOne = cmdOne.ExecuteReader();
while (dataReaderOne.Read())
{
Console.WriteLine(dataReaderOne.GetString(0));
}
dataReaderOne.Close();
虽然这是输出:
method
method
method
.
.
.
..表示方法列中的行数。这是格式化问题吗?我的数据库配置是否可能阻止VarChar正确返回?当我更改查询以查询INT类型的列时,它返回INT类型列的正确值。
答案 0 :(得分:2)
您无法在选择参数中参数化列名。你正在做的事情就像说select 'foo' from log.transactions
一样。它为每一行选择一次字符串'foo'。你只是在那里坚持一个字符串值;它没有将字符串值解析为SQL。
你能做什么(如果你负担得起)是select * from log.transactions
,那么你的C#代码可以在调用者传给你名字的任何列中获取数据。有很多行,你可能会从数据库中拖回大量无用的垃圾。
您在所显示的代码中想要的只是这样:
string queryOne = "SELECT method FROM log.transactions";
如果你真的想参数化“方法”,那是因为SQL注入漏洞而粗略的。
string queryOne = "SELECT " + fieldname + " FROM log.transactions";
在使用您的应用程序的某个喜剧演员在文本框中为您提供值"0; drop table log.transactions;--"
之前,这看起来很不错。那你就麻烦了。如果你曾经将一个字符串变量连接到一个你将要执行的SQL字符串中,那么你必须对它进行消毒会很狂热,即使这样你也想以任何方式避免它。这是俄罗斯轮盘赌。
答案 1 :(得分:1)
如果要保持列动态,则必须形成查询。现在相应地传递列名。
string queryOne = "SELECT " + column_name + " FROM log.transactions";
MySqlCommand cmdOne = new MySqlCommand(queryOne, connectionString);
MySqlDataReader dataReaderOne = cmdOne.ExecuteReader();
while (dataReaderOne.Read())
{
Console.WriteLine(dataReaderOne[column_name]);
}
dataReaderOne.Close();