我对C#非常陌生,当我尝试使用字符串生成器执行sql查询时,我遇到了一些问题。
下面是名为:
| ID | Name | InternalID |
|:----:|:---------:| :---------:|
| 1 | Emory Lu | 84765 |
| ... | ... | ... |
| 8 | John Smith| 52455 |
| 9 | John smith| 49 |
| ... | ... | ... |注意,John在这个表中被分配了两个不同的InternalID (字符串类型)。在第二张唱片中,他的姓氏以小写字母"s“开头。
在输入员工姓名时,我执行了一个简单的sql查询,以选择员工的InternalID (字符串类型):
public DataTable findInternalID(string name)
{
RecordConnection.Open();
DataTable output = new DataTable();
OleDbCommand bdCommand = RecordConnection.CreateCommand() as OleDbCommand;
StringBuilder x = new StringBuilder();
// SELECT InternalID FROM EmployeeList WHERE Name = "(name)"
x.AppendLine("SELECT InternalID ");
x.AppendLine("FROM EmployeeList ");
x.AppendLine($"WHERE Name LIKE '%{name}%'");
bdCommand.CommandText = x.ToString();
_dataAdapter = new OleDbDataAdapter(bdCommand);
_dataAdapter.Fill(output);
RecordConnection.Close();
return output;
}对于只有一条记录的员工来说,这段代码可以正常工作,但是对于拥有多条记录的员工,它将同时填充所有InternalID记录和输出,因为这行代码如下:
x.AppendLine($"WHERE Name LIKE '%{name}%'");因此,我尝试将LIKE关键字更改为"=“:
x.AppendLine($"WHERE Name = '%{name}%'");但这给了我一个错误。
我如何编辑我的代码,所以当输入"John“时只输出"52455”,而输入"John“则只输出"49”。
在主函数下,我编写了一段代码来测试这个函数:
string name = "John Smith"; // or John smith
DataTable output = _accessManager.findInternalID(name);
String message = result.Rows[0][0].ToString(); // Or ROWS[1][0]
MessageBox.Show(message);顺便说一句,我使用了MS Access :)
=================Problem解决了!====================
我非常感谢大家的帮助。我考虑了每个人的建议,这是我的最后代码。我使用了StrComp()特性,它非常适合在MS Access中执行区分大小写的sql查询:
public DataTable findInternalID(string name)
{
RecordConnection.Open();
DataTable output = new DataTable();
OleDbCommand bdCommand = RecordConnection.CreateCommand() as OleDbCommand;
StringBuilder x = new StringBuilder();
x.AppendLine("SELECT InternalID ");
x.AppendLine("FROM EmployeeList ");
x.AppendLine($"WHERE StrComp(Name, @name, 0) = 0;");
bdCommand.CommandText = x.ToString();
bdCommand.Parameters.AddWithValue("name", $"{name}");
_dataAdapter = new OleDbDataAdapter(bdCommand);
_dataAdapter.Fill(output);
RecordConnection.Close();
return output;
}如果您使用的是MS Access,那么COLLATE和varbinary(MAX)并不是适合您的特性。
发布于 2022-02-15 17:05:26
首先,您不应该通过将用户提供的数据连接到查询字符串中来构建SQL查询。这样做会使您容易受到SQL注入的攻击。相反,应该使用查询参数将用户提供的数据传递给查询。
重写原始函数以使用参数可能如下所示:
public DataTable findInternalID(string name)
{
RecordConnection.Open();
var output = new DataTable();
var bdCommand = RecordConnection.CreateCommand() as OleDbCommand;
var x = new StringBuilder();
// SELECT InternalID FROM EmployeeList WHERE Name = "(name)"
x.AppendLine("SELECT InternalID ");
x.AppendLine("FROM EmployeeList ");
x.AppendLine("WHERE Name LIKE @name");
bdCommand.CommandText = x.ToString();
bdCommand.Parameters.AddWithValue("name", $"%{name}%");
_dataAdapter = new OleDbDataAdapter(bdCommand);
_dataAdapter.Fill(output);
RecordConnection.Close();
return output;
}至于获得区分大小写的查询,我不能说我已经这样做了。假设您的数据库是Server,它看起来应该可以工作。
x.AppendLine("SELECT InternalID ");
x.AppendLine("FROM EmployeeList ");
x.AppendLine("WHERE Name = @name COLLATE Latin1_General_CP1_CS_AS");或者,可能转换到varbinary(MAX)来比较字节?
x.AppendLine("SELECT InternalID ");
x.AppendLine("FROM EmployeeList ");
x.AppendLine("WHERE CAST(Name as varbinary(MAX)) = CAST(@name AS varbinary(MAX))");另外,作为最后一个注意事项,您根本不需要使用StringBuilder。如果要跨多行格式化语句,只需使用逐字string和@标识符。
string commandText = @"SELECT InternalId
FROM EmployeeList
WHERE Name = @name COLLATE Latin1_General_CP1_CS_AS";发布于 2022-02-15 16:28:24
在Server中,您只需要区分大小写的搜索,试试这个!
x.AppendLine($"WHERE Name = '{name}' COLLATE Latin1_General_CS_AS ");
在中,试试这个!
x.AppendLine($"WHERE StrComp(Name, '{name}', 0) = 0");
https://stackoverflow.com/questions/71129780
复制相似问题