Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当参数化查询执行时,它似乎没有参数值_C#_Parameterized Query - Fatal编程技术网

C# 当参数化查询执行时,它似乎没有参数值

C# 当参数化查询执行时,它似乎没有参数值,c#,parameterized-query,C#,Parameterized Query,据我所知,以下代码应该创建一个参数化语句,并向该参数添加一个值。参数为“@exp”,添加的值由用户输入决定。我将用户输入存储在stringexp(不是我的选择,此函数的大部分由其他人编写) 我的测试用例的期望结果是16,但此查询返回0。该查询在从SQLServer2008运行时工作,如下所示 SELECT COUNT(*) As MyCount FROM members WHERE ([Primary Exp] = 'Risk Management') AND ([Approved]

据我所知,以下代码应该创建一个参数化语句,并向该参数添加一个值。参数为“@exp”,添加的值由用户输入决定。我将用户输入存储在
stringexp(不是我的选择,此函数的大部分由其他人编写)

我的测试用例的期望结果是16,但此查询返回0。该查询在从SQLServer2008运行时工作,如下所示

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_命令.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"]);
}

我确信我遗漏了一些简单的东西,但我没有看到它。

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

SQl_Command.CommandText = "SELECT COUNT(*) As MyCount FROM members WHERE 
        ([Primary Exp] = @exp) AND ([Approved] = 'True') OR
        ([Approved] = 'True') AND ([Secondary Exp] = @exp)";
你应该发现你现在得到了正确的值;对于您的原始版本,它会逐字搜索字符串
'@exp'


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

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

RPC是SQL客户机按名称直接执行存储过程的一种方式,而不是以文本形式执行T-SQL语句。它不是以T-SQL的形式发送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代码将用实际值替换这些参数。这些参数将作为参数发送到SQL Server,包括它们在值列表中的值。这就是它的方式,也是它的设计方式——如果您希望在将查询发送到SQL Server之前将参数替换为其实际值,那么您就错了。
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'"