0

据我了解,以下代码应该创建一个参数化语句并向该参数添加一个值。参数为“@exp”以及添加到其中的值由用户输入确定。我将用户输入存储在String exp;(不是我的选择,其他人编写了这个函数的大部分内容)。

SQl_Command.CommandText = "SELECT COUNT(*) As MyCount FROM members WHERE ([Primary Exp] = '@exp') AND ([Approved] = 'True') OR ([Approved] = 'True') AND ([Secondary Exp] = '@exp')";
SQl_Command.Parameters.Add("@exp", SqlDbType.NVarChar, 255);
SQl_Command.Parameters["@exp"].Value = exp;

我的测试用例所需的结果是 16,但此查询返回 0。从 SQL Server 2008 运行时,查询有效,如下所示。

SELECT COUNT(*) As MyCount 
FROM members 
WHERE ([Primary Exp] = 'Risk Management') 
  AND ([Approved] = 'True') OR ([Approved] = 'True') 
  AND ([Secondary Exp] = 'Risk Management')

我应该能够Response.Write(SQl_Command.CommandText);在我选择“风险管理”的地方使用,并且参数化查询应该打印出来:

SELECT COUNT(*) As MyCount 
FROM members 
WHERE ([Primary Exp] = 'Risk Management') 
  AND ([Approved] = 'True') OR ([Approved] = 'True') 
  AND ([Secondary Exp] = 'Risk Management')`

然而事实并非如此。就@exp好像那是我想比较 [Primary Exp] 和 [Secondary Exp] 的值。那是对的吗?

我已经看到了多种这样做的方法,但我通常一直遵循这里的示例

我认为这不是问题,但这就是我使用查询的方式。

SQl_Reader = SQl_Command.ExecuteReader();
int numRows = 0;
while(SQl_Reader.Read()){
    numRows = Convert.ToInt32(SQl_Reader["MyCount"]);
}

我确定这是我想念的简单的东西,但我无法看到它。

4

2 回答 2

6

您在这里处理变量,SQL 对象不只是执行“更安全”的搜索和替换。将您的代码更改为:

SQl_Command.CommandText = "SELECT COUNT(*) As MyCount FROM members WHERE 
        ([Primary Exp] = @exp) AND ([Approved] = 'True') OR
        ([Approved] = 'True') AND ([Secondary Exp] = @exp)";

你应该会发现你现在得到了正确的值;使用您的原始版本,它实际上会搜索 string '@exp'

请注意,SQL 参数和命令本身仅在执行期间合并,作为对 SQL Server 的调用的一部分。因此,当您看到即使添加了参数后@exp仍然显示CommandText,这实际上是正确的。

于 2013-08-21T23:36:53.517 回答
1

当您通过 .NET SQL Server 提供程序之一运行参数化查询时,该查询将其参数化形式一直保持到服务器。如果您在执行查询时运行 SQL Profiler,您会看到执行查询的“RPC”事件发生,并在此过程中填写参数。

RPC 是 SQL 客户端直接按名称执行存储过程的一种方式,而不是作为文本执行 T-SQL 语句。不是将您的 SQL 命令作为 T-SQL 发送,而是以 RPC 调用的形式发送到“sp_executesql”,您的查询和后续参数本身作为参数发送到 sp_executesql。所以你的查询实际上会像这样运行:

sp_executesql "SELECT COUNT(*) As MyCount FROM members WHERE ([Primary Exp] = '@exp') AND ([Approved] = 'True') OR ([Approved] = 'True') AND ([Secondary Exp] = '@exp')", "@exp NVARCHAR(255)", "@exp = 'Risk Management'"

这篇关于SQL Server Connection Basics 的文章更详细地解释了不同之处。

于 2013-08-21T23:37:26.733 回答