很常見的一個問題要查詢數據庫中某個時間段的記錄?在寫sql語句時查詢肯定要傳入開始結束時間參數,翻閱程序工程代碼發現不同人寫法不同,仔細想想其實寫sql查詢語句傳入日期時間參數是比傳入整形或字符串類型要復雜些,因為設計到日期時間的現實格式,把常見的幾種寫法總結如下:
-
最普通最麻煩的寫法,sql語句直接用+連接來寫:比如Delphi中直接傳入TdateTime類型的參數StartTime、StopTime方法如下:
SQL.Add(' and (a.begin_time BETWEEN CONVERT(DATETIME, ''' + FormatDateTime('yyyy-mm-dd hh:nn:ss', StartTime) + ''', 102) ');
SQL.Add(' and CONVERT(DATETIME, ''' + FormatDateTime('yyyy-mm-dd hh:nn:ss', StopTime) + ''', 102))');
Delphi中直接傳入string類型的格式為yyyymmdd類型的日期參數寫法如下:
SQL.Add(' and convert(int,(convert(varchar,inquestinfo.begin_time,112)))<= ' + EndDate);
SQL.Add(' and convert(int,(convert(varchar,inquestinfo.end_time,112)))>= ' + BeginDate);
這種寫法要熟悉sqlserver中函數convert的用法,還要知道最后一個參數值對應的整數值的格式,很麻煩也浪費時間。
-
聲明sql變量的寫法
qry.SQL.Add('declare @begin_time datetime');
qry.SQL.Add('declare @stop_time datetime');
qry.SQL.Add('declare @inquest_serial int');
qry.SQL.Add('set @begin_time = CONVERT(DATETIME, ''' + FormatDateTime('yyyy-mm-dd hh:nn:ss', BegTime) + ''', 102)');
qry.SQL.Add('set @stop_time = CONVERT(DATETIME, ''' + FormatDateTime('yyyy-mm-dd hh:nn:ss', EndTime) + ''', 102)');
這種方法給變量賦值還是要用到CONVERT函數,繞個玩麻煩。
-
最簡單最省時的寫法,參數化SQL法
SQL.Add(' and begin_time < :endTime and end_time > :beginTime');
Parameters.ParamByName('endTime').Value := EndTime;
Parameters.ParamByName('beginTime').Value := BeginTime;
此法簡單省時,還可以避免SQL注入等安全問題,充分利用了系統封裝的便利高效性。不過要注意:動態加入tadoquery.sql的參數化SQL語句在調用參數前先解析下SQL,如下: Parameters.ParseSQL(SQL.Text, True);
代碼例下:
with self.qry do begin
try
SQL.Clear();
Parameters.Clear();
Close();
Prepared := False;
SQL.Text := 'SELECT [CurrentNO], [Mask], [CurrentDate] FROM [CurrentID]' +
' WHERE [TabName]= :TabName AND [KeyField]=:KeyField;';
Parameters.ParseSQL(SQL.Text, True); //一定要加,否則運行時報告異常edatabaseerror parameter 'table' not found,就是說參數table在SQL中找不到
Parameters.ParamByName('TabName').Value := Table;
Parameters.ParamByName('KeyField').Value := KeyField;
Prepared := True;
Open();
