2013-02-18 55 views
0

SQL:DateTime和文化

select * 
from tvideoconference 
where del = 'false' 
and iduserpatient = 0 and startdate >= N'18.02.2013 20:37:07' 
order by startdate 

錯誤:

The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.

我得到這個錯誤,當我試圖在de-DE屆文化使用下面的方法。更重要的是,在pl-PLen-US文化中,這種方法是完美的。

public static DataSet getSpecialistConfs(int iduserspecialist) 
{ 
    DateTime? today = DateTime.Now; 
    today = today.Value.AddHours(-today.Value.Hour).AddMinutes(-(today.Value.Minute + 1)); 
    string sql = "select * from tvideoconference where del='false' and startdate >=N'" + today.Value + "' and iduserspecialist=" + iduserspecialist; 
    sql += " order by startdate "; 

    return Tools.SQLTools.getDataSet(sql); 
} 

我該如何解決?我嘗試了很多解決方案(子串,日期格式),效果相同。

回答

2

各種設置(語言,日期格式)隻影響在SQL Server Management Studio中向您顯示DateTime的方式 - 或者當您嘗試將字符串轉換爲一個DateTime

SQL Server支持多種格式 - 請參閱MSDN Books Online on CAST and CONVERT。這些格式中的大多數是,依賴於,因此您可以設置哪些設置 - 因此,這些設置可能會工作一些 - 有時不會。

解決這個問題的方法是使用(稍作改動)ISO-8601日期由SQL Server支持的格式 - 這種格式的作品總是 - 不管你的SQL Server的語言和日期格式設置。

ISO-8601 format由SQL Server支持有兩種形式:

  • YYYYMMDD只是日期(沒有時間部分);請注意:沒有破折號!,這非常重要! YYYY-MM-DD不是獨立於您的SQL Server中的dateformat設置,並將在所有情況下工作!

或:

  • YYYY-MM-DDTHH:MM:SS的日期和時間 - 這裏需要注意:這種格式破折號(但他們可以可省略),並固定T的日期和時間之間的分隔符你的部分DATETIME

這對SQL Server 2000及更新版本有效。

如果你使用SQL Server 2008或更高版本和DATE數據類型(僅DATE - !DATETIME),那麼你的確可以同時使用YYYY-MM-DD格式,將工作,也與任何設置在你的SQL Server 。

不要問我爲什麼這整個話題如此棘手,有點令人困惑 - 這就是它的方式。但使用YYYYMMDD格式,對於任何版本的SQL Server以及SQL Server中的任何語言和dateformat設置,都應該可以。

4

How can I resolve it?

首先使用參數化SQL。不要在查詢本身中包含這些值;使用參數並設置這些參數的值。

目前還不清楚Tools.SqlTools是什麼,但你真的,真的應該使用參數化的SQL。這樣你就不會將DateTime的值轉換成一個字符串,所以文化和格式不會妨礙。此外,你會不會容易SQL injection attacks ...

(此外,它不是完全清楚爲什麼你使用DateTime?代替DateTime - 它不喜歡DateTime.Now可以爲空...你應該考慮使用而不是...或DateTime.UtcNow.Date。)

+0

感謝您的回覆。我明白這一點,但我很感興趣的是,爲什麼這種方法與其他文化一起工作,並且不適用於「DE-DE」文化。對於這種情況我沒有合理的理由。 – whoah 2013-02-18 19:58:08