我正在尝试使用存储过程从SQL Server 2008 R2数据库查询数据。代码执行时没有错误,但查询没有返回任何结果。当通过SQL Server Management Studio使用完全相同的参数调用此相同的存储过程时,将正确返回数据。我不知道是什么导致这种情况,可能是SqlClient实现的具体内容?查询返回两个DateTime2
值之间的所有数据;如果我将这些DateTime2
值分开得足够远,则返回数据。显然这不是理想的行为。
C#代码(在这种情况下startTime.HasValue
和endTime.HasValue
为真):
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
SqlCommand comm = conn.CreateCommand();
comm.CommandType = CommandType.StoredProcedure;
comm.CommandText = "GetAllPropertyValues";
comm.Parameters.Add("@dataTypeName", SqlDbType.NVarChar).Value = dataTypeName;
comm.Parameters.Add("@propertyName", SqlDbType.NVarChar).Value = propertyName;
if (startTime.HasValue)
{
var startString = startTime.Value.ToUniversalTime().ToString("O");
if (endTime.HasValue)
{
var endString = endTime.Value.ToUniversalTime().ToString("O");
comm.CommandText += "Between";
comm.Parameters.Add("@startTime", SqlDbType.DateTime2).Value = startString;
comm.Parameters.Add("@endTime", SqlDbType.DateTime2).Value = endString;
}
else
{
comm.CommandText += "After";
comm.Parameters.Add("@dateTime", SqlDbType.DateTime2).Value = startString;
}
}
SqlDataReader reader = comm.ExecuteReader();
while (reader.Read())
{
// ...
}
SQL Server存储过程:
declare @str varchar(max) = 'select * from [dbo].[' + @tableName + '] where StartTime BETWEEN ''' +
CAST(@startTime as nvarchar(max)) + ''' AND ''' + CAST(@endTime as nvarchar(max)) + ''' order by StartTime asc'
exec(@str)
执行示例查询:
USE [Construct3]
GO
DECLARE @return_value int
EXEC @return_value = [dbo].[GetAllPropertyValuesBetween]
@datatypeName = N'HeadPose',
@propertyName = N'HeadRotationRadiansZ',
@startTime = '2014-12-31T19:00:00.0000000Z',
@endTime = '2014-12-31T20:00:00.0000000Z'
SELECT 'Return Value' = @return_value
GO
答案 0 :(得分:1)
更改CommandText
属性会清除Parameters
集合。完成文本后设置所有参数。
此外,你所拥有的将容易受到sql注入攻击。您应该使用sp_executesql
而不是exec()
,以便安全地处理您的时间参数。我会怀疑,@tableName
参数不是用户可以输入任意文本的东西,而是必须从服务器验证的表列表中选择。
答案 1 :(得分:1)
假设存储过程中的@startTime
和@endTime
参数类型为DATETIME
,那么您正在进行从datetime到string的双重转换,首先您要做的是它在你的c#代码:
var startString = startTime.Value.ToUniversalTime().ToString("O"); //This will create the datetime as a string using .NET format
您将其作为DateTime2
传递给存储过程:
comm.Parameters.Add("@startTime", SqlDbType.DateTime2).Value = startString;
然后你将它转换回SQL上的字符串格式:
CAST(@startTime as nvarchar(max))
这可能是问题,当你在.NET和SQL中从DATETIME
转换为字符串时,不要期望它们具有相同的结果,因此当您在数据库上执行存储过程时你得到了结果,但是当你从.NET调用它时,没有结果,因为日期是错误的。我建议做的是将这些日期参数的值作为普通的.NET DateTime
值传递,并将其转换为存储过程中的varchar
。您可以在SQL中使用CONVERT
函数来实现这一功能,请查看this link以获取有关CONVERT
日期格式的更多信息。
希望这有帮助。