Sql 如何比较Firebird时间戳和Delphi DateTime?
由于Firebird/Interbase中的时间戳数据类型不是DateTime(*),因此我有一个从未检索任何数据的脚本 我该如何修理它??德克萨斯州Sql 如何比较Firebird时间戳和Delphi DateTime?,sql,delphi,firebird,Sql,Delphi,Firebird,由于Firebird/Interbase中的时间戳数据类型不是DateTime(*),因此我有一个从未检索任何数据的脚本 我该如何修理它??德克萨斯州 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 =
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是时间戳数据类型,如“2010-11-09 12:00”
//参数返回数据类型,如“2010-11-09”
(*)时间戳是Firebird/Interbase/SQL Server中可用的列数据类型。。。这有助于确保数据完整性。每次插入或更新包含时间戳列的行时,时间戳都会自动更新。时间戳列中的值不是日期时间数据,而是二进制(8)变量二进制(8)数据。时间戳数据类型与系统时间无关,它只是一个单调递增的计数器,其值在数据库中总是唯一的(使其基本上是唯一的随机数)。下面用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;
下面是用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;
您不是误解了Firebird中的时间戳数据类型吗?在SQL92中,时间戳是一种标准数据类型,用于保存日期和时间值。它不会自动更新,返回时间戳值的函数与数据库时间相关 好的,Firebird时间戳实现遵循SQL92规则(),并且它应该与Delphi.AsDateTime参数完美结合
正如您所描述的,这是SQL Server时间戳,不应与日期和时间相比使用,“SQL Server时间戳数据类型与时间或日期无关”您是否误解了Firebird中的时间戳数据类型?在SQL92中,时间戳是一种标准数据类型,用于保存日期和时间值。它不会自动更新,返回时间戳值的函数与数据库时间相关 好的,Firebird时间戳实现遵循SQL92规则(),并且它应该与Delphi.AsDateTime参数完美结合
正如您所描述的,它是SQL Server时间戳,不应与日期和时间进行比较,“SQL Server时间戳数据类型与时间或日期无关”通常,由于时间部分的原因,我将其用作字符串参数。 想法是设置独立的格式,例如“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)
由于时间的原因,我通常将其用作字符串参数。 想法是设置独立的格式,例如“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)
本例中的时间戳是您自己的自定义数据类型吗?因为我们经常使用标准时间戳数据类型,与查询参数相比,它工作得很好。这是火鸟2.5。如上所示,scrip从不返回代码正常工作的任何数据(因为参数pTranDate的值是日期格式,仅在调试器中可见)。查询不返回结果的原因可能与此不同。检查其他参数。例如:Delphi将“2010-11-09”作为pTranDate参数的值。使用此值,脚本不返回任何数据。如果我将此参数值替换为“2010-11-09 00:00”,那么脚本将返回数据。“2010-11-09”是字符串值,如何将其设置为参数?本例中的时间戳是您自己的自定义数据类型吗?因为我们经常使用标准时间戳数据类型,与查询参数相比,它工作得很好。这是火鸟2.5。如上所示,scrip从不返回代码正常工作的任何数据(因为参数pTranDate的值是日期格式,仅在调试器中可见)。查询不返回结果的原因可能与此不同。检查其他参数。例如:Delphi将“2010-11-09”作为pTranDate参数的值。使用此值,脚本不返回任何数据。如果我将此参数值替换为“2010-11-09 00:00”,那么脚本将返回数据。“2010-11-09”是一个字符串值,如何将其设置为参数?通常最好以数字格式保存日期,并让驱动程序/客户端/数据库处理其余内容。它也稍微快一些,因为引擎不需要解析和转换字符串。Firebird的问题较少,因为它理解一组固定的字符串文本,但在其他数据库中,“标准”日期文本格式可能会根据操作系统区域设置、数据库设置以及客户端区域设置和设置而改变。这是一个避免字符串的好方法。谢谢这个函数和参考Sofija-它将在我的应用程序的其他部分有所帮助。现在,我使用Firebird时间戳和Delphi DateTime正确地处理了问题。通常最好以数字格式保存日期,并让驱动程序/客户机/数据库处理其余内容。它也稍微快一些,因为引擎不需要解析和转换字符串。Firebird的问题较少,因为它理解一组固定的字符串文本,但在其他数据库中,“标准”日期文本格式可能会根据操作系统区域设置、数据库设置以及客户端区域设置和设置而改变。这是一个避免字符串的好方法。谢谢这个函数和参考Sofija-它将在我的应用程序的其他部分有所帮助。现在我使用Firebird时间戳和Delphi DateTime作为