2011-09-23 60 views
4

我簡短的是實現其中有看起來像下面「GetValuesSqlStatement」的方法的接口的最佳實踐:現在什麼是查詢日期的SQL時,參數化查詢是不可能

public string SqlPattern { get { ... } } 
//this varies; eg. "SELECT name FROM someTable WHERE startDate < {0}" 

public string DatabaseType { get { ... } } 
//this varies; eg. "SqlServer" 

public string GetValuesSqlStatement(List<object> paramValues) 
{ 
    //...desired logic here, using DatabaseType, SqlPattern and paramValues 
} 

,因爲這必須產生一個可執行的SQL語句,我不能在執行查詢時使用參數。我必須實現的接口是不可協商的。繼續確保結果中的日期由數據庫查詢引擎正確解釋的最佳方法是什麼?假設paramValues包含.NET DateTime對象,在插入SQL模式字符串之前,這些對象應該如何格式化爲字符串?必須數據庫中最常用的通用日期格式是什麼? (比如'dd-mmm-yyyy')。

注:我只需要真正擔心從2005年開始的SQL Server和Oracle 10g以上。所以SQL必須是有效的T SQL和PL SQL,並且在這兩種口味中意味着相同的東西。

回答

1

我認爲SQL Server的唯一明確的日期格式是年月日:

http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/16/bad-habits-to-kick-mishandling-date-range-queries.aspx

http://www2.sqlblog.com/blogs/aaron_bertrand/archive/2011/09/20/bad-habits-to-kick-using-shorthand-with-date-time-operations.aspx

甲骨文使用DATE「YYYY-MM-DD '符號:

http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/sql_elements003.htm#BABGIGCJ

雖然可能有這個符號適用於兩種情況,我懷疑是否有適用於所有可能的區域服務器設置的符號。如你所說,YYYY-MON-DD可能是有用的 - 這是Oracle的默認設置。

+0

那麼我有DatabaseType字符串來幫助我構建這個查詢。如果你說'yyyy-mm-dd'適用於除SQL Server之外的所有應用程序,那麼我可以使用條件邏輯。如果'yyyy-mon-dd'同時適用於SQL Server和Oracle,那當然會滿足我的需求,但這並不一定是我猜的最佳實踐。 – Lisa

+1

@Lisa,你必須嘗試。我從來沒有法國服務器,我總是使用YYYY-MM-DD。您會在Aaron的文章中看到該連接項,它不適用於新的date和datetime2數據類型。在SQL Server中。根據我在Oracle中的經驗,文字總是要求DATE限定詞將它們與字符串區分開來。你可能需要將你的日期字符串生成封裝在特定於數據庫的東西中。 –

+0

我突然有了一個更好的主意,哪種讓這個問題沒那麼有用。即使不是嚴格回答問題,我也可以將其作爲第三個答案添加。 – Lisa

1

如果你使用任何數據庫的日期格式'yyyy-mm-dd',你應該沒問題。這是根據ISO 8601(http://www.iso.org/iso/date_and_time_format

+1

在SQL Server中,問題依然存在http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/16/bad-habits-to-kick-mishandling-date-range-queries.aspx(Connect http: //connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=290971) –

+0

我認爲這將是最普遍的,你可以得到。你知道你的服務器本地化嗎? – mwan

+0

遍佈全球。好的,這個特定的項目將是+ 8GMT或+ 9.30GMT,但不能讓它突然不能爲不同的客戶工作。 – Lisa

0

即使它從問題的範圍轉向,我也提供了我自己的答案,因爲這可能對於有類似問題的其他人有用。

我剛剛意識到我可以簡單地期望每個實例(或世界上不同地方的每個客戶)在參數佔位符的後半部分中可選地指定格式字符串。例如。執行:

public string SqlPattern { get { 
    return "SELECT name FROM someTable WHERE startDate < {0:yyyy-mm-dd}"; 
} } 

然後我的組件不需要擔心如何格式化日期。默認情況下,我可以使用'yyyymmdd',或者更好的是使用服務器的文化來選擇默認值。否則使用自定義指定的模式。這將是一種通用的方法,適用於需要格式化爲SQL字符串的其他類型。