在項目開發過程中,我們經常要做一些以時間為條件的查詢,比如查詢指定時間范圍內的歷史記錄,然而這些時間都是從UI傳遞過來的參數,所以我們寫的sql語句就必須用到字符串拼接。當然,在C#中寫SQL語句還好處理,可以使用C#的字符串函數做對應的數據類型轉換。但是,如果用的是存儲過程的話,就有點糾結了。下面來說一下我在寫存儲過程中遇到的問題:
為了更加直接的說明問題,寫如下一個簡單的例子:
declare @dateFrom datetime; declare @dateTo datetime; declare @str nvarchar(500); declare @strOne nvarchar(100); declare @strTwo nvarchar(200); declare @sql nvarchar(1000); set @dateFrom = '2014-01-01'; set @dateTo = getdate(); set @strOne = ' and DateCreated >= ' + @dateFrom; set @str = 'select * from Users where 1 = 1'; set @sql = @str + @strOne; print @sql; exec sp_executesql @sql
這個時候,執行SQL的話,就會出現如下錯誤:
分析原因,主要是因為@dateFrom數據類型為Datetime,和字符串連接時類型不匹配,所以下面就來做類型轉換:
SQL Server中有個Convert函數,可以用來做類型轉換,用法如下:
定義和用法
CONVERT() 函數是把日期轉換為新數據類型的通用函數。
CONVERT() 函數可以用不同的格式顯示日期/時間數據。
語法
CONVERT(data_type(length),data_to_be_converted,style)
data_type(length) 規定目標數據類型(帶有可選的長度)。data_to_be_converted 含有需要轉換的值。style 規定日期/時間的輸出格式。
實例
下面的腳本使用 CONVERT() 函數來顯示不同的格式。我們將使用 GETDATE() 函數來獲得當前的日期/時間:
CONVERT(VARCHAR(19),GETDATE()) CONVERT(VARCHAR(10),GETDATE(),110) CONVERT(VARCHAR(11),GETDATE(),106) CONVERT(VARCHAR(24),GETDATE(),113)
結果類似:
Dec 29 2008 11:45 PM 12-29-2008 29 Dec 08 29 Dec 2008 16:25:46.635
參照上面用法,我們修改代碼如下:
declare @dateFrom datetime; declare @dateTo datetime; declare @str nvarchar(500); declare @strOne nvarchar(100); declare @strTwo nvarchar(200); declare @sql nvarchar(1000); set @dateFrom = '2014-01-01'; set @dateTo = getdate(); -- set @strOne = ' and DateCreated >= ''' + convert(nvarchar(20),@dateFrom,20) + ''''; -- set @strTwo = ' and DateCreated <= ''' + convert(nvarchar(20),@dateTo,20) + ''''; set @strOne = ' and t68DateCreated between ''' + convert(nvarchar(20),@dateFrom,20) + ''' and ''' + convert(nvarchar(20),@dateTo,20) + ''''; -- select * from Authors_t68 where Users between @dateFrom and @dateTo set @str = 'select * from Authors_t68 where 1 = 1'; -- set @sql = @str + @strOne + @strTwo; set @sql = @str + @strOne; print @sql; exec sp_executesql @sql
這個時候,執行,就可以查詢出結果了。兩種拼接方法,注釋掉的使用了兩個條件來限定時間范圍,后一種方法用的是between...and方法。