C#硬编码SQL可以工作,但使用SqlCommand参数则不行;t

本文关键字:参数 SqlCommand SQL 编码 工作 | 更新日期: 2023-09-27 18:28:29

我有一些C#代码被调用来通过查询数据库生成字符串。最初,我使用字符串插值创建了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中的parameters方法创建的查询,我会得到正确的返回,因此它看起来格式正确。我想使用parameters方法,因为这似乎是最佳实践,但我不明白为什么它没有得到回报,而硬编码版本却得到回报。我能忽略或不理解什么?

C#硬编码SQL可以工作,但使用SqlCommand参数则不行;t

以下是正确的方法:

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将您的变量名用引号括起来。应该是:

string queryString = "SELECT filename, description FROM SECTION Where " +
            "Product_Code = (SELECT Product_Code FROM PRODUCT WHERE SHORT_NAME = @ProductCode) " +
            "AND UPPER(description) like '%' + @SectionName + '%'";