2017-04-06 92 views
1

我有一個簡單的測試查詢針對SQL Server數據庫運行。當ADO.Net運行查詢時,什麼規定DB的日期時間格式?

SELECT IsDate('1' + '/' + '25' + '/' + '1993') 

當我與

set dateformat dmy 

它正確返回0

當我與

set dateformat mdy 

運行對一個數據庫它正確地返回1

運行對數據庫

現在的問題是,當我從.Net中的SqlCommand對象運行此查詢時,我得不到我期望的結果。

問題在於我將線程的文化信息和日期時間格式設置爲d/m/y。即使當我的線程以d/m/y格式運行並且我的數據庫設置爲d/m/y時,從SqlCommand運行時,我仍然從我的查詢中返回1。

樣品的編號:(注:QuickQuery只是它運行一個SqlCommand對我所選擇的數據庫的包裝方法)

string query = $" SELECT IsDate('1' + '/' + '25' + '/' + '1993')"; 
var dt = QuickQuery(query); 

return $"{dt.Rows[0][0]}" + $"   {new DateTime(1993, 1, 25)}"; 

這樣做的輸出=「1 25/01/1993 00:00: 00「

當我的實際數據庫和當前線程設置爲d/m/y時,什麼是確定SqlCommand在m/d/y的上下文中運行?

我已經證明了我的數據庫

DBCC USEROPTIONS 

編輯1設置:

只是一個快速的說明 - 我欣賞的做事更好的方式輸入,即是有價值的。對於這種特殊情況,我不能很好地選擇問題的背景,我只是想解決它。每個月份,每天和每年的值有一個varchar列。它們可以爲空或文本。從那裏我必須創建與實際datetime列的日期時間比較,並能夠在服務器上和正在運行的線程上處理任何日期時間格式!

+0

看看文檔,它看起來像'set dateformat'適用於*當前會話*。理想情況下,只要確保完全不依賴日期格式 - 如果您始終使用參數化SQL並使用DateTime值,則不應該成爲問題。 –

+0

您應該爲使用DataTime參數而不是String的查詢添加一個參數(VarChar)。 – jdweng

+0

@JonSkeet感謝文檔信息。我從https://docs.microsoft.com/en-us/sql/t-sql/statements/set-dateformat-transact-sql閱讀,並沒有看到任何這樣的評論!你找到了哪些官方文檔,以便我能夠快速瞭解​​這些細節? –

回答

0

本質上:完全避免這個問題。從不談論日期作爲字符串。使用參數,這些參數已經很好的定義和輸入。

本質(切換到Dapper syntax,因爲它支持參數):

DateTime date = ... 
var dt = connection.QuerySingle<DateTime>("select @date + 2", new {date}); 

這同樣適用於其他的數據 - 你得到的數字和小數點分隔符和組分隔類似問題的方式,以及得到它的權利不是以瞭解SQL Server需要的格式:不使用字符串,而是傳遞參數化值。這也會使意外陷入SQL注入漏洞變得更加困難。

+0

我很欣賞你的建議,並會嘗試儘可能使用參數。但是,我正在研究一個現有的數據庫,其中包含大量邏輯的大小合適的查詢。我無法更改數據庫,但我必須嘗試並支持不同的格式。我必須在現有結構和設計的範圍內做到這一點。 –

+0

@AdamHeeg我沒有建議改變數據庫 - 只是你查詢的方式 –

+0

我不明白爲什麼查詢很大使得它不可用的參數化SQL ... –