SQL 查询和 SqlClient 操作之间的区别



我正在尝试使用存储过程从 SQL Server 2008 R2 数据库中查询数据。代码执行时没有错误,但查询不会返回任何结果。当使用完全相同的参数通过 SQL Server Management Studio 调用相同的存储过程时,将正确返回数据。我不知道是什么原因导致这种情况,可能是 SqlClient 实现的特定原因?查询返回两个DateTime2值之间的所有数据;如果我使这些DateTime2值相距足够远,则返回数据。显然,这不是所需的行为。

C# 代码(在这种情况下,startTime.HasValueendTime.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

假设存储过程中的@startTime@endTime参数是类型 DATETIME,则执行从日期时间到字符串的双重转换,首先在 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函数来实现这一点,请查看此链接以获取有关CONVERT日期格式的更多信息。

希望这有帮助。

更改 CommandText 属性将清除Parameters集合。完成文本后设置所有参数。

此外,您拥有的东西将容易受到SQL注入攻击。你应该使用 sp_executesql 而不是 exec() ,以便安全地处理时间参数。我将为您提供一个怀疑的好处,即 @tableName 参数不是用户可以输入任意文本的东西,而是必须从服务器验证的表列表中进行选择。

相关内容

  • 没有找到相关文章

最新更新