【问题标题】:Why does "WHERE (Time_Stamp >= TDateTime-variable)" ignore fractional seconds?为什么“WHERE (TimeStamp >= DateTime-variable)”会忽略小数秒?
【发布时间】:2016-05-24 12:18:26
【问题描述】:

使用 Delphi 6 和 Microsoft SQL Server 2000。

我需要提取 TDateTime 字段为 > 传递的 TDateTime,“FromDate”的记录。
就好像传递的 TDateTime 秒的小数部分始终为零一样失败。
调试打印输出确认分数存在。

WHERE 部分忽略 :Fdate 的小数部分。
假设以下 3 条记录:
记录 1:Time_Stamp 为 1.2
记录 2:Time_Stamp 为 1.4
记录 3:Time_Stamp 为 1.6

然后将值 1.3 发送到 :Fdate 中的查询。
结果数据集返回所有 3 条记录。
从 1.3 > 1.2 开始,我预计只有记录 2 和 3

数据库中的“Time_Stamp”字段是 SQL 的“日期时间”字段。
一切都在整数秒内完美运行,
即每秒一条记录,或者在小数部分不重要时更少记录。

谁能指出我的错误在哪里?

SQL语句由代码生成(如下图):

SELECT TOP 6 * FROM T_TransactionLog  
INNER JOIN T_LookUp_TransTypes  
ON T_TransactionLog.TransType = T_LookUp_TransTypes.TransType  
WHERE (Time_Stamp >= :Fdate)  
AND T_TransactionLog.TransType IN (  
3,  
4,  
5  
)  
AND LockerNo < 60001  
ORDER BY Time_Stamp ASC 

代码如下:

Query.Connection := Sys_DB_Form.ADOConnection;  
DataSource.DataSet := Query;  

Query.SQL.Add('SELECT TOP ' + IntToStr(cNoTransactions) + ' * FROM
  T_TransactionLog');  

Query.SQL.Add('INNER JOIN T_LookUp_TransTypes');  
Query.SQL.Add('ON T_TransactionLog.TransType =  
  T_LookUp_TransTypes.TransType');  

Query.SQL.Add('WHERE (Time_Stamp ' + S_Condition + ' :Fdate)');  
Query.SQL.Add('AND T_TransactionLog.TransType IN (');  
Query.SQL.Add(IntToStr(ord(Apl_TrLog.ttEA)) + ',');  
Query.SQL.Add(IntToStr(ord(Apl_TrLog.ttMO)) + ',');  
Query.SQL.Add(IntToStr(ord(Apl_TrLog.ttMC)));  
Query.SQL.Add(')');  
Query.SQL.Add('AND LockerNo < ' +
IntToStr(Apl_Config.cLNoOfFirstgate));  
if Locker <> 0 then  
  begin  
    Query.SQL.Add('AND LockerNo = ' + IntToStr(Locker));  
  end;  
Query.SQL.Add(S_OrderBy);  

Query.Parameters.FindParam('Fdate').Value := FromDate; // <<< Fail???? 

Query.SQL.SaveToFile(GetApplicationDataPath + 'Sql.txt');  
try  
  Query.Open;  
except  
  ShowMessage('Query open fail on ME Show Transaction log');  
end;  

【问题讨论】:

  • :FDate 是什么数据类型?只要数据正确,直接运行 SQL 就会得到预期的结果。
  • @Tom H. 我不知道。那条特定的行取自某处的示例。我试图了解如何使用 FindParam,但没有成功。我确实为它分配了一个 TDateTime,希望它可以处理它,如果没有分数它可以。 .Value 应该是别的东西吗?
  • 你为什么需要FindParam?使用ParamByName,因为您知道参数存在。
  • 如果您直接在 Sql 中测试会发生什么,例如"如果 Time_Stamp > somevalue select 'after' else select 'not after' "?
  • 我很困惑。重新阅读您的问题,很不清楚您在数据库中的列中的数据类型。 TDateTime 是日期和时间,您显然是在完全基于您的Record 1: Time_Stamp is 1.2 传递其他内容。 Time_Stamp 是什么 SQL 数据类型(在创建列的 DDL 中)?我知道您说过它是 DATETIME,但您没有为其分配 DATETIME 值(除非您的意思是在 1899 年 12 月 31 日凌晨 4:48:00 存储 12/31/1899)。

标签: sql sql-server delphi sql-server-2000


【解决方案1】:

请在 MSDN 上查看SQL Server datetime and time data types 的准确性说明

上面写着: 精度四舍五入到 0.000、0.003 或 0.007 秒的增量

这意味着 23:59:59.997 没问题 但 23:59:59.998 将四舍五入为 23:59:59.997 和 23:59:59.999 将四舍五入到第二天的 00:00:00

【讨论】:

  • 我知道准确性问题。然而,记录之间的小数差异在几十到几百毫秒。
  • 我无法使 Query.Parameters 工作。我重写了那行,现在是:WHERE (Time_Stamp >= CONVERT(DATETIME, '2016-05-24 00:00:00.000',102))
猜你喜欢
  • 1970-01-01
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多