为什么使用 date/time 值的 TADOTable 中的 Locate() 不起作用
Why Locate() in TADOTable with date/time value is not working
我正在开发一个用于记录用户 activity 的小型子系统。该系统使用 MS SQL Server 作为数据库,Delphi7 和 ADO 构建界面。
我遇到的问题是无法找到具有特定 datetime
值的记录。
下面是问题的示例再现:
1.数据库:MS SQL Server 2005 Express Edition。
-- Table creation
CREATE TABLE [tlog] (
[USERN] [numeric](10, 0) NULL,
[USERDATE] [datetime] NULL,
[LOGTEXT] [varchar](250) COLLATE Cyrillic_General_CS_AS NULL
);
-- Insert date/time value
INSERT INTO [tlog] (USERN, USERDATE, LOGTEXT)
VALUES (1, CURRENT_TIMESTAMP, 'Record current activity')
-- Insert date only value
INSERT INTO [tlog] (USERN, USERDATE, LOGTEXT)
VALUES (1, '20180202', 'Record current activity')
-- Table's content
-------------------------------------------------------------
| USERN | USERDATE | LOGTEXT |
-------------------------------------------------------------
| 1 | 26/10/2015 17:13:36.597 | Record current activity |
-------------------------------------------------------------
| 1 | 02/02/2018 00:00:00.000 | Record current activity |
-------------------------------------------------------------
2。示例代码: Delphi 7和ADO
procedure TfrmMain.btnLocateClick(Sender: TObject);
var
d: TDateTime;
tblLog: TADOTable;
begin
//
ThousandSeparator := ' ';
DecimalSeparator := '.';
DateSeparator := '/';
ShortDateFormat := 'dd/mm/yyyy';
LongDateFormat := 'dd/mm/yyyy';
TimeSeparator := ':';
ShortTimeFormat := 'hh:mm';
LongTimeFormat := 'hh:mm';
TwoDigitYearCenturyWindow := 50;
ListSeparator := ';';
//
tblLog := TADOTable.Create(Application);
try
//
tblLog.ConnectionString :=
'Provider=SQLOLEDB.1;'+
'Password=xxxx;'+
'Persist Security Info=True;'+
'User ID=xxxxxxxx;'+
'Initial Catalog=xxxxxxxxx;'+
'Data Source=127.0.0.1\xxxxxxx,1066';
tblLog.TableName := '[tlog]';
tblLog.Open;
// First try - locate with exact value. NOT WORKING.
d := StrToDateTime('26/10/2015 17:13:36.597');
if tblLog.Locate('USERDATE', d, []) then
ShowMessage('Exact value, no Locate options: Located')
else
ShowMessage('Exact value, no Locate options: Not located');
if tblLog.Locate('USERDATE', d, [loPartialKey]) then
ShowMessage('Exact value, with Locate options: Located')
else
ShowMessage('Exact value, with Locate options: Not located');
// Second try - locate with value that matches format settings. NOT WORKING.
d := StrToDateTime('26/10/2015 17:13');
if tblLog.Locate('USERDATE', d, []) then
ShowMessage('Hours and minutes, no Locate options: Located')
else
ShowMessage('Hours and minutes, no Locate options: Not located');
if tblLog.Locate('USERDATE', d, [loPartialKey]) then
ShowMessage('Hours and minutes, with Locate options: Located')
else
ShowMessage('Hours and minutes, with Locate options: Not located');
// Locate with date only value. WORKING.
d := StrToDateTime('02/02/2018');
if tblLog.Locate('USERDATE', d, []) then
ShowMessage('Located')
else
ShowMessage('Not located');
finally
//
tblLog.Close;
tblLog.Free;
end;
end;
3。预期结果: 找到记录。
4.实际结果: TADOTable.Locate()
returns false
.
我做错了什么以及如何将 datetime
值传递给 TADOTable.Locate()
方法?
提前致谢!
您使用了 Locate almost correctly. Almost, because the loPartialKey 搜索 TDateTime 值时包含的选项毫无意义。在这种情况下,您需要搜索确切的日期时间值。问题出在你的测试中。
您的第一次测试的日期时间值有误。它的毫秒部分在您的转换中被忽略,因此您实际上是在尝试定位日期时间 26/10/2015 17:13:36 这不在您的 table.
在第二种情况下,您试图找到日期时间 26/10/2015 17:13,这不在您的 table.[=12 中=]
我建议使用例如EncodeDateTime function for building date time rather than that string conversion and removing those extra calls with loPartialKey 选项。
使用类型字符串定位或查找格式为 yyyy-mm-dd 的日期
示例:
在定位中:
if tblLog.Locate('USERDATE', '2015-10-26', []) then ...
其中:
select * from tbllog where userdate = '2015-10-26'
我正在开发一个用于记录用户 activity 的小型子系统。该系统使用 MS SQL Server 作为数据库,Delphi7 和 ADO 构建界面。
我遇到的问题是无法找到具有特定 datetime
值的记录。
下面是问题的示例再现:
1.数据库:MS SQL Server 2005 Express Edition。
-- Table creation
CREATE TABLE [tlog] (
[USERN] [numeric](10, 0) NULL,
[USERDATE] [datetime] NULL,
[LOGTEXT] [varchar](250) COLLATE Cyrillic_General_CS_AS NULL
);
-- Insert date/time value
INSERT INTO [tlog] (USERN, USERDATE, LOGTEXT)
VALUES (1, CURRENT_TIMESTAMP, 'Record current activity')
-- Insert date only value
INSERT INTO [tlog] (USERN, USERDATE, LOGTEXT)
VALUES (1, '20180202', 'Record current activity')
-- Table's content
-------------------------------------------------------------
| USERN | USERDATE | LOGTEXT |
-------------------------------------------------------------
| 1 | 26/10/2015 17:13:36.597 | Record current activity |
-------------------------------------------------------------
| 1 | 02/02/2018 00:00:00.000 | Record current activity |
-------------------------------------------------------------
2。示例代码: Delphi 7和ADO
procedure TfrmMain.btnLocateClick(Sender: TObject);
var
d: TDateTime;
tblLog: TADOTable;
begin
//
ThousandSeparator := ' ';
DecimalSeparator := '.';
DateSeparator := '/';
ShortDateFormat := 'dd/mm/yyyy';
LongDateFormat := 'dd/mm/yyyy';
TimeSeparator := ':';
ShortTimeFormat := 'hh:mm';
LongTimeFormat := 'hh:mm';
TwoDigitYearCenturyWindow := 50;
ListSeparator := ';';
//
tblLog := TADOTable.Create(Application);
try
//
tblLog.ConnectionString :=
'Provider=SQLOLEDB.1;'+
'Password=xxxx;'+
'Persist Security Info=True;'+
'User ID=xxxxxxxx;'+
'Initial Catalog=xxxxxxxxx;'+
'Data Source=127.0.0.1\xxxxxxx,1066';
tblLog.TableName := '[tlog]';
tblLog.Open;
// First try - locate with exact value. NOT WORKING.
d := StrToDateTime('26/10/2015 17:13:36.597');
if tblLog.Locate('USERDATE', d, []) then
ShowMessage('Exact value, no Locate options: Located')
else
ShowMessage('Exact value, no Locate options: Not located');
if tblLog.Locate('USERDATE', d, [loPartialKey]) then
ShowMessage('Exact value, with Locate options: Located')
else
ShowMessage('Exact value, with Locate options: Not located');
// Second try - locate with value that matches format settings. NOT WORKING.
d := StrToDateTime('26/10/2015 17:13');
if tblLog.Locate('USERDATE', d, []) then
ShowMessage('Hours and minutes, no Locate options: Located')
else
ShowMessage('Hours and minutes, no Locate options: Not located');
if tblLog.Locate('USERDATE', d, [loPartialKey]) then
ShowMessage('Hours and minutes, with Locate options: Located')
else
ShowMessage('Hours and minutes, with Locate options: Not located');
// Locate with date only value. WORKING.
d := StrToDateTime('02/02/2018');
if tblLog.Locate('USERDATE', d, []) then
ShowMessage('Located')
else
ShowMessage('Not located');
finally
//
tblLog.Close;
tblLog.Free;
end;
end;
3。预期结果: 找到记录。
4.实际结果: TADOTable.Locate()
returns false
.
我做错了什么以及如何将 datetime
值传递给 TADOTable.Locate()
方法?
提前致谢!
您使用了 Locate almost correctly. Almost, because the loPartialKey 搜索 TDateTime 值时包含的选项毫无意义。在这种情况下,您需要搜索确切的日期时间值。问题出在你的测试中。
您的第一次测试的日期时间值有误。它的毫秒部分在您的转换中被忽略,因此您实际上是在尝试定位日期时间 26/10/2015 17:13:36 这不在您的 table.
在第二种情况下,您试图找到日期时间 26/10/2015 17:13,这不在您的 table.[=12 中=]
我建议使用例如EncodeDateTime function for building date time rather than that string conversion and removing those extra calls with loPartialKey 选项。
使用类型字符串定位或查找格式为 yyyy-mm-dd 的日期
示例:
在定位中:
if tblLog.Locate('USERDATE', '2015-10-26', []) then ...
其中:
select * from tbllog where userdate = '2015-10-26'