2013-10-24 20 views
2

我有一臺應用服務器連接到另一臺SQL Server 2008R2服務器。兩臺服務器的圖形用戶界面都是法語的,並且都有日期和數字格式。此外,SQL Server和用於執行命令語言的用戶被設置爲法語(全部默認)。但是,我將這個標籤在web.config中設置的格式在我的WCF服務爲「en-GB」: 當從LINQ調用SQL Server存儲過程到SQL時,無法將nvarchar轉換爲datetime

我已經包括在我的LINQ一個存儲過程SQL的DbContext文件,我m傳遞日期參數而不將其轉換爲字符串(因爲ORM將其識別爲日期)。

事情一直很好,直到今天早些時候,程序停止執行拋出一個異常說,字符串不能轉換爲日期。

我跟蹤與SQL事件探查器的查詢,發現它執行以下查詢:

declare @p9 int 
set @p9=NULL 
exec sp_executesql N'EXEC @RETURN_VALUE = [GIS].[GetOnlineTrackingRecords] 
@CompanyId = @p0, @EntityIds = @p1, @MinDate = @p2, @MinRecordId = @p3, @TrackingType = @p4, @TrackAllEntities = @p5', N'@p0 int,@p1 varchar(8000),@p2 datetime,@p3 bigint,@p4 tinyint,@p5 bit,@RETURN_VALUE int output', 
@p0=1,@p1='168',@p2='2013-10-24 16:36:28.690',@p3=NULL,@p4=1,@p5=0,@[email protected] output 
select @p9 

(用@ P2的主要問題)

的ORM方法總結我的存儲過程是這樣的:

[global::System.Data.Linq.Mapping.FunctionAttribute(Name= "GIS.GetOnlineTrackingRecords")] 
public ISingleResult<FMS2.Framework.TrackEntities.GetOnlineTrackingRecordsResult> GetOnlineTrackingRecords([global::System.Data.Linq.Mapping.ParameterAttribute(Name="CompanyId", DbType="Int")] System.Nullable<int> companyId, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="EntityIds", DbType="VarChar(MAX)")] string entityIds, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="MinDate", DbType="DateTime")] System.Nullable<System.DateTime> minDate, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="MinRecordId", DbType="BigInt")] System.Nullable<long> minRecordId, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="TrackingType", DbType="TinyInt")] System.Nullable<byte> trackingType, [global::System.Data.Linq.Mapping.ParameterAttribute(Name="TrackAllEntities", DbType="Bit")] System.Nullable<bool> trackAllEntities) 
    { 
     IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), companyId, entityIds, minDate, minRecordId, trackingType, trackAllEntities); 
     return ((ISingleResult<FMS2.Framework.TrackEntities.GetOnlineTrackingRecordsResult>)(result.ReturnValue)); 
    } 

當我試圖執行在SQL Server Management Studio中相同的查詢失敗了,但它在我的機器上成功運行(與英語小號ql服務器)。在將SQL Server引擎的語言和用戶默認語言更改爲us_english後,它成功運行,但只能從SQL Server運行,並且在從我的WCF應用程序調用時仍然失敗並顯示相同的錯誤消息。我已經使用sys.dm_exec_sessions和SQL Profiler雙重檢查了用us_english語言在用戶下執行的查詢。我讀過從'yyyy-MM-dd HH:mm:ss'字符串到目前爲止的演員應該在任何機器上正常工作,但它似乎不是:( 接下來我該怎麼做,考慮到觸摸代碼將是。非常難...

感謝

回答

2

你不應該通過像yyyy-mm-dd hh:mm:ss串這裏的原因:

SET LANGUAGE FRENCH; 
SELECT CONVERT(DATETIME, '2013-05-06'); 

,因爲它被解釋爲yyyy-dd-mm這將返回6月5日,而不是5月6日, 。如果你使用你的日期('2013-10-24'),你會得到一個錯誤,因爲SQL Server不知道第24個mont h是。

現在,我不知道如何在你的ORM中做事情,但理想情況下,你應該永遠不會傳遞一個字符串,所以格式應該不重要。您應該傳遞日期/時間值,而不是字符串。當你確實需要傳遞一個字符串時(你可能會再次因爲我不知道你選擇的ORM的限制,我只知道沒有ORM涵蓋所有的基礎),你應該總是使用一個100 %明確的格式。嘗試:

@p2='2013-10-24T16:36:28.690' 
---------------^ that T is important 

讓我說出爲什麼,只爲Alireza。 From this document

如果日期和時間顯示在同一行上,則始終在時間前寫入日期。如果日期和時間值一起存儲在單個數據字段中,那麼ISO 8601建議它們應該用拉丁大寫字母T分隔,如19951231T235959中所示。

當您添加T時,您將刪除SQL Server以任何其他方式解釋日期的能力。這不是因爲它是T,或者是因爲ISO 8601的建議,而是因爲SQL Server中的代碼簡單地說,如果有T,則將日期解釋爲y-m-d,而不考慮區域,區域設置,日期格式或語言設置。

+0

@Alireza你爲什麼一直試圖找到理由來編輯我的答案?如果您有需要添加的內容,請隨時添加評論。 –

+0

你的答案很好,很完整,只需要對T進行一點說明。也許有些讀者看不到T的意思。 – Alireza

+0

@Alireza你的建議編輯並沒有真正解釋T,如果您要編輯其他人的答案,請將這些編輯值得。 –

相關問題