我有一些C#代码被调用来通过查询db来生成字符串。最初我使用字符串插值创建SQL,如下所示:
string queryString = $"SELECT * FROM SECTION Where " +
$"Product_Code = (SELECT Product_Code FROM PRODUCT WHERE SHORT_NAME = '{productName}') " +
$"AND UPPER(description) like '{sectionName}%'";
此代码无问题; sectionName和productName是字符串。在阅读了SQL注入的工作原理后,我决定将其更改为使用参数(即使这个特定的应用程序不需要担心注入)。以下是我的设置方法:
string queryString = "SELECT filename, description FROM SECTION Where " +
"Product_Code = (SELECT Product_Code FROM PRODUCT WHERE SHORT_NAME = '@ProductCode') " +
"AND UPPER(description) like '@SectionName%'";
var command = new SqlCommand(queryString, connection);
command.Parameters.Add("@ProductCode", SqlDbType.VarChar).Value = productName;
command.Parameters.Add("@SectionName", SqlDbType.VarChar).Value = sectionName;
这无法获得任何回报。起初我认为SQL必须不同,所以我使用以下代码查看了参数方法生成的SQL:
string query = command.CommandText;
foreach (SqlParameter p in command.Parameters)
{
query = query.Replace(p.ParameterName, p.Value.ToString());
}
根据上面的代码,任一方法生成的SQL都是相同的。如果我执行在SSMS中使用参数方法创建的查询,我会得到正确的返回值,因此它看起来格式正确。我想使用参数方法只是因为它似乎是最佳实践,但我无法弄清楚为什么它在硬编码版本获得回报时没有得到回报。我有什么可以忽视或不理解?
答案 0 :(得分:2)
这是正确的方法:
string queryString =
@"SELECT filename, description
FROM SECTION
Where Product_Code = (
SELECT Product_Code
FROM PRODUCT
WHERE SHORT_NAME = @ProductCode
)
AND UPPER(description) like @SectionName";
var command = new SqlCommand(queryString, connection);
command.Parameters.Add("@ProductCode", SqlDbType.VarChar).Value = productName;
command.Parameters.Add("@SectionName", SqlDbType.VarChar).Value = "%" + sectionName + "%";
答案 1 :(得分:1)
生成的SQL将您的变量名称用引号括起来。它应该是:
string queryString = "SELECT filename, description FROM SECTION Where " +
"Product_Code = (SELECT Product_Code FROM PRODUCT WHERE SHORT_NAME = @ProductCode) " +
"AND UPPER(description) like '%' + @SectionName + '%'";