儘量簡短。這是我的桌子和SP在SQL Server 2008 R2數據庫:ADO.NET和SSMS以不同方式解釋SP參數或SQL分析器有錯誤?
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#代碼:我特意指定的日期時間@參數1的類型
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();
}
}
留意。 現在啓動SQL Server Profiler並運行.NET代碼。完成後,不要停止分析器,只需查看輸出即可。我看到了RPC以下文字:完成事件類:
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 @[email protected]
在這種情況下,這將是很清楚,爲什麼我有790毫秒,而不是789.這是因爲日期時間類型也不是很準確。它被四捨五入爲.000,.003或.007秒的增量。請參閱:datetime (Transact-SQL)這也將是明確的爲什麼我'2013年12月10日12:34 PM'而不是'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事件探查顯示了一些奇怪和困惑?有沒有任何方法可以解決這個問題?
是的,你是對的 - 我們不應該混合使用數據類型。不過,我想留意一下,我是故意透露這個問題的。事實上,問題是關於SQL Server Profiler的混淆行爲。 – Alex
讓我們想象我有第三方應用程序,並且無法訪問源代碼。所以我不知道SqlDbType分配給SqlParameter的是什麼。也許它有SqlDbType.DateTime或SqlDbType.VarChar。在這種情況下,看看發生了什麼的唯一方法是使用分析器。所以我啓動它並看到以下內容: 'exec USP_TEST_PROCEDURE @Param1 ='2013-12-10 12:34:56。790'' 我如何知道「應用程序正在發送日期時間」,而不是字符串?這並不明顯。探查器中是否有任何參數可以強制探查器顯示此信息? – Alex
@Alex我認爲你錯誤的工作使用了錯誤的工具,我甚至不知道爲什麼。首先,profiler已被棄用,不用擔心它不是爲你正在做的任務而設計的。你可以從執行計劃中獲得更多的信息(參數類型,隱式轉換等),這些信息遠遠超過了探查器。你試圖問出租車司機是誰開車送我去機場的,我什麼時候會到達目的地。 –