ADO.NET和SSMS以不同方式解释SP params或SQL profiler有错误吗?

时间:2013-12-10 23:29:52

标签: c# sql ado.net sql-server-2008 sql-server-profiler

尽量简短。这是我在SQL Server 2008 R2数据库中的表和SP:

CREATE TABLE dbo.TEST_TABLE
(
    ID INT NOT NULL IDENTITY (1,1) PRIMARY KEY, 
    VALUE varchar(23)
)
GO

CREATE PROCEDURE USP_TEST_PROCEDURE
( 
    @Param1 varchar(23)
)
AS
BEGIN
    INSERT INTO TEST_TABLE (VALUE) VALUES (@Param1)
END
GO

这是C#代码:

using (SqlConnection con = GetConection())
{
    using (var cmd = new SqlCommand("USP_TEST_PROCEDURE", con))
    {
        cmd.CommandType = CommandType.StoredProcedure;
        cmd.Parameters.Add("@Param1", SqlDbType.DateTime, 23).Value = "2013-12-10 12:34:56.789";
        cmd.Connection.Open();
        cmd.ExecuteNonQuery();
    }
}

注意我故意将@ Param1的类型指定为DateTime。 现在启动SQL Server Profiler并运行.NET代码。完成后,不要停止探查器,只需查看输出。我看到RPC的以下文本:Completed EventClass:

exec USP_TEST_PROCEDURE @Param1='2013-12-10 12:34:56.790'

现在复制此文本,打开SSMS,粘贴到新查询窗口并运行而不做任何更改。现在停止探查器并确保SSMS在探查器中生成与ADO.NET应用程序相同的文本:

exec USP_TEST_PROCEDURE @Param1='2013-12-10 12:34:56.790'

现在从TEST_TABLE表中选择。我看到以下结果:

ID VALUE
1  Dec 10 2013 12:34PM
2  2013-12-10 12:34:56.790

问题是为什么两个相同的命令(从SQL Server Profiler的角度来看)产生不同的结果?

似乎探查器无法正确显示场景背后的情况。运行.NET应用程序后,我希望看到以下内容:

DECLARE @Param1 Datetime = '2013-12-10 12:34:56.789';
exec USP_TEST_PROCEDURE @Param1=@Param1

在这种情况下,我很清楚为什么我有790毫秒而不是789.这是因为日期时间类型不是很精确。它四舍五入到.000,.003或.007秒的增量。见:datetime (Transact-SQL)我也很清楚为什么我有'2013年12月10日下午12:34'而不是'2013-12-10 12:34:56.790'。这是因为当datetime转换为字符串时,默认使用'mon dd yyyy hh:miAM(或PM)'格式。请参阅CAST and CONVERT (Transact-SQL)以下示例演示了:

DECLARE @Param1 Datetime = '2013-12-10 12:34:56.789';
DECLARE @Param1_varchar varchar(23);

SELECT @Param1 --2013-12-10 12:34:56.790
SET @Param1_varchar = @Param1;
SELECT @Param1_varchar; --Dec 10 2013 12:34PM
GO

如果我的理解是正确的,那么我想重新解释一下这个问题:为什么SQL Server Profiler会显示一些奇怪而令人困惑的东西?有没有更正的选择?

1 个答案:

答案 0 :(得分:0)

您的应用程序正在发送日期时间,但由于您选择了varchar列,因此会在进入时隐式转换。就像print中所发生的那样:

DECLARE @d DATETIME = GETDATE();

SELECT @d; -- this is still a datetime

PRINT @d; -- this is implicitly converted to a string

如果您不喜欢这种令人困惑的行为,请停止混合数据类型。绝对没有理由将日期时间值存储在varchar列中。