Firebird时间戳字段的Delphi DBGrid日期格式

时间:2018-07-10 14:49:32

标签: delphi firebird datetime-format dbgrid

我将Firebird数据库的内容显示到TDBgrid中。数据库有一个“ TIMESTAMP”数据类型字段,我想以日期/时间格式显示: 'YYYY / MM / DD HH:mm:ss'。 (现在显示为“ YYMMDD HHmmss”)

如何实现?

我尝试过:

procedure TDataModule1.IBQuery1AfterOpen(DataSet: TDataSet);
begin
  TDateTimeField(IBQuery1.FieldByName('timestamp_')).DisplayFormat := 'YYYY/MM/DD HH:mm:ss';
end;

但是,这在程序的其他部分会引起一些副作用,因此它不是替代方法。例如,在“ IBQuery1.Open”语句中,我通过清除数据库的方法得到了“ ... timestamp_ not found ...”调试器消息。

function TfrmLogger.db_events_clearall: integer;
begin
  result := -1;
  try
    with datamodule1.IBQuery1 do begin
      Close;
      With SQL do begin
        Clear;     
        Add('DELETE FROM MEVENTS')
      end;
      if not Prepared then 
        Prepare;      
      Open;          //Exception here          
      Close;
      Result := 1;
    end;
  except
    on E: Exception do begin
      ShowMessage(E.ClassName);
      ShowMessage(E.Message);          
      Datamodule1.IBQuery1.close;
    end;
  end;
end;

当尝试打开查询以写入数据库时​​,我收到相同的异常消息。

*编辑>>

我对数据库进行了如下修改:

function TfrmLogger.db_events_clearall: integer;
var
  IBQuery: TIBQuery;
  IBTransaction: TIBTransaction;
  DataSource: TDataSource;
begin
  result := -1;

  //Implicit local db objects creation
  IBQuery := TIBQuery.Create(nil);
  IBQuery.Database := datamodule1.IBdbCLEVENTS;

  DataSource := TDataSource.Create(nil);
  DataSource.DataSet := IBQuery; 

  IBTransaction := TIBTransaction.Create(nil);
  IBTransaction.DefaultDatabase := datamodule1.IBdbCLEVENTS;
  IBQuery.Transaction := IBTransaction;

  try
    with IBQuery do begin
      SQL.Text := DELETE FROM MSTEVENTS;
      ExecSQL;
      IBTransaction.Commit;
      result := 1;
    end;
  except
    on E : Exception do
    begin
      ShowMessage(E.ClassName + ^M^J + E.Message);
      IBTransaction.Rollback;
    end;
  end;

  freeandnil(IBQuery);
  freeandnil(DataSource);
  freeandnil(IBTransaction);
end;

清除数据库后,我仍可以将记录加载到dbgrid中,好像数据库尚未更新。程序重新启动后,我可以看到所有记录都已删除。

1 个答案:

答案 0 :(得分:1)

整个function TfrmLogger.db_events_clearall似乎非常可疑。

  1. 您没有提供SQL_DELETE_ROW,但是通过回答,这似乎不是返回“结果集”的SELECT请求。因此,很可能它不应由“ .Open”运行,而应由“ .Execute”或“ .ExecSQL”或类似名称运行。

UPD。 SQL_DELETE_ROW = 'DELETE FROM MEVENTS';被添加,确认了我之前和以后的期望。几乎。常量名称建议您要删除一个行,而查询文本显示您要删除所有行,这是正确的,我想知道吗?..

此外,由于没有“结果集”-.Close之后没有.Exec....的内容-但是您可以检查.RowsAffected,看看DBX中是否有这样的属性,以查看实际计划删除多少行。

此外,不,此功能不删除行,它仅计划将其删除。在处理SQL时,您必须花费时间和精力来学习有关TRANSACTIONS的知识,否则您很快就会被副作用所淹没。

尤其是在这里,您必须提交删除事务。为此,您必须显式创建,启动并绑定到IBQuery事务,或者找出IBQuery1.Commit;隐式使用的事务。还有.Rollback的例外情况。

是的,很无聊。您可能希望IBX足够聪明,可以偶尔为您执行提交。但是,如果不通过事务隔离数据更改,您将不可避免地会产生来自各种“竞争条件”的可重现的“副作用”。

示例

  FieldDefs.Clear;  // frankly, I do not quite recall if IBX has those, but probably it does.
  Fields.Clear;     // forget the customizations to the fields, and the fields as well
  Open;      // Make no Exception here          
  Close;
  Halt;  // << insert this line
  Result := 1;

尝试一下,我敢打赌即使查询是“打开”和“关闭”而没有错误,您的表也不会被清除。

  1. 整个With SQL do begin怪物都可以用单线SQL.Text := SQL_DELETE_ROW;代替。了解Delphi中的TStrings类是什么-在Delphi库的很多地方都使用了该类,因此可以节省许多时间来了解此类服务和功能。

  2. 您无法忘记Prepare的一次性查询。在不更改SQL.Text而是仅更改参数的情况下,对查询进行了准备,然后使用“相同的文本”但使用不同的值重新打开查询。 好的,有时我确实使用(滥用?)显式准备来确保库从服务器获取参数数据类型。但是在您的示例中没有。但是,您的代码不使用参数,也不会使用具有相同的不变SQL.text的许多打开。因此,它变成一种噪音,使打字时间更长,阅读更困难。

  3. 尝试使用ShowMessage(E.ClassName + ^M^J + E.Message)或仅尝试Application.ShowException(E)-没有意义使两个停止模式窗口而不是一个停止。

  4. Datamodule1.IBQuery1.close;-实际上,这是回滚事务的地方,而不仅仅是关闭一直未打开的查询。

  5. 现在,使两个(或更多?)SQL请求抛出一个Delphi查询对象的想法本身就值得怀疑。您对查询进行自定义,例如修复DisplayFormat或设置字段的事件处理程序,那么该查询就值得永久地进行自定义。您甚至可以在设计时设置DisplayFormat,为什么不这样呢?

在单个TIBQuery对象上进行骑行没有什么意义-拥有所需的数量即可。到目前为止,您必须普遍且准确地推断出程序中每个函数中的文本都位于IBQuery1中。

这再次产生了潜在的未来副作用。想象一下,您在某个地方可以做function1; function2;,后来您决定要交换它们并去做function2; function1;。你可以做到吗?但是,如果function2更改IBQuery1.SQL.Textfunction1取决于先前的文本,该怎么办?那怎么办?

因此,基本上,对查询进行排序。应该存在确实存在于函数调用中的那些查询,然后它们最好具有专用的查询对象,并且不要被其他查询过度使用。而且应该有“一次”查询,这些查询只能在一个函数内部使用,而不能在函数外部使用,例如SQL_DELETE_ROW -如果谨慎使用,您可能会过度使用这些查询。但是,最好还是重新制作这些函数,使其查询成为局部变量,只有他们自己看不见。

PS。似乎您对IBX库感到困惑,然后建议您看一下此扩展http://www.loginovprojects.ru/download.php?getfilename=uploads/other/ibxfbutils.zip 除其他功能外,它还提供了通用的插入/删除功能,该功能将在内部创建和删除临时查询对象,因此您无需考虑。

交易管理仍然需要牢记和控制。