如何比较Firebird TimeStamp和Delphi DateTime?

时间:2010-11-11 05:10:43

标签: sql delphi firebird

我有以下脚本永远不会检索任何数据,因为Firebird / Interbase中的TimeStamp数据类型不是DateTime(*)

我该如何解决? TX。

 with DMApp.qryValidPeriod_ do
  begin
    Close;
    SQL.Clear;
    SQL.Add('select P.* from PERIOD P, FISCAL_YR F');    
    SQL.Add('where');
    SQL.Add('P.FISCAL_YR_ID = F.FISCAL_YR_ID and');     
    SQL.Add('F.ENTITY_DB_ID = :PRIMARY_DB_ID and');     
    SQL.Add('F.FISCAL_YR_ID = :CURR_FY_ID and');        
    SQL.Add(':pTranDate BETWEEN P.BEG_PERIOD and P.END_PERIOD');

    ParamByName('pTranDate').AsDateTime :=  sBATCH_DATE; 

// BEG_PERIOD和END_PERIOD是TimeStamp数据类型,例如'2010-11-09 12:00' //参数返回数据类型,例如'2010-11-09'


(*)时间戳是Firebird / Interbase / SQL Server中可用的列数据类型...有助于确保数据完整性。每次插入或更新包含时间戳列的行时,时间戳都会自动更新。 timestamp列中的值不是datetime数据,而是binary(8)varbinary(8)数据。 timestamp数据类型与系统时间无关,它只是一个单调递增的计数器,其值在数据库中始终是唯一的(使其基本上是一个唯一的随机数。)

3 个答案:

答案 0 :(得分:5)

你是不是误解了Firebird中的TIMESTAMP数据类型?在SQL92中,TIMESTAMP是一种标准数据类型,用于保存日期和时间值。它不会自动更新,返回TIMESTAMP值的函数与数据库时间有关。

AFAIK,Firebird TIMESTAMP实现遵循SQL 92规则(http://www.firebirdsql.org/index.php?op=guide&id=ib6_newfeatures#datetime),它应该与Delphi .AsDateTime参数完美配合。

正如您所描述的那样是SQL Server TIMESTAMP - 并且永远不应该与日期和时间进行比较,“SQL Server时间戳数据类型与时间或日期无关”http://msdn.microsoft.com/en-us/library/ms191240(SQL.90).aspx

答案 1 :(得分:1)

通常,我将它用作字符串参数,因为时间部分。 想法是设置独立的格式,例如'11 -NOV-2010 12:32:25'

例如,您可以尝试

ParamByName('pTranDate').AsString :=  FormatSQLDateTime(sBATCH_DATE);

你应该在哪里有类似这些的功能

function FormatSQLDate(date: TDate) : string;
const months : array[1..12] of string[3] =
('JAN','FEB','MAR','APR','MAY','JUN','JUL','AUG','SEP','OCT','NOV','DEC');
 var d, y : integer;
     m : string[3];
begin
   d := DayOf(date);
   y := YearOf(date);
   m := months[MonthOf(date)];
   Result := Format('%d-%s-%d', [d, m, y]);
end;


function FormatSQLDateTime(date : TDateTime) : String;
var
  d : String;
  h, m, s : Integer;
begin
  d := SQLDate(date);
  h := HourOf(date);
  m := MinuteOf(date);
  s := SecondOf(date);
  Result := d + Format(' %d:%d:%d', [h, m, s]);
end;

请注意,您还可以使用sql extract

在服务器端执行某些操作
extract(day from timestamp_field)

http://www.firebirdsql.org/refdocs/langrefupd20-extract.html

答案 2 :(得分:0)

下面用Delphi编写的UDF。它获取日期的三个部分并以Firebird格式返回日期值。也许这有助于您了解如何在Delphi和FB之间转换日期。

type
  PIBDateTime = ^TIBDateTime;
  TIBDateTime = record
    Days,                           // Date: Days since 17 November 1858
    MSec10 : Integer;               // Time: Millisecond * 10 since midnigth
  end;

const                               // Date translation constants
  MSecsPerDay10 = MSecsPerDay * 10; // Milliseconds per day * 10
  IBDateDelta = 15018;              // Days between Delphi and InterBase dates

// ==============================================
//  declare external function ...
//    smallint, smallint, smallint, date
//  returns
//    date
//  ...
// ==============================================

function g_d_encodedate(var Year, Month, Day: SmallInt;
  var IBDateTime: TIBDateTime): PIBDateTime; cdecl; export;
var
  DateTime: TDateTime;
  DelphiDays : Integer;
begin
  DateTime := EncodeDate(Year, Month, Day);
  DelphiDays := Trunc(DateTime);
  with IBDateTime do begin
    Days := DelphiDays + IBDateDelta;
    MSec10 := Trunc((DateTime - DelphiDays) * MSecsPerDay10);
  end;
  Result := @IBDateTime;
end;