小编nol*_*ker的帖子

如何使Firebird客户端应用程序等待行解锁

我熟悉使用ADO(dbGo)的Microsoft SQL服务器世界,我已经为该环境编写了许多应用程序.现在我有一个遗留的Delphi 7应用程序和Firebird 2.5数据库,我必须维护它.

但我发现如果2个客户端应用程序执行此操作:

SQLQuery.SQL.Text := 'Update mytable set field1 = 11 where keyfield = 99'
SQLQuery.Execute;
Run Code Online (Sandbox Code Playgroud)

在几乎完全相同的时间,第二个应用程序立即出现"死锁"错误.在SQL Server中,会有一段等待时间

ADOConnection.Isolationlevel = ilCursorstability;
ADOConnection.CommandTimeout := 5;
Run Code Online (Sandbox Code Playgroud)

在第二个客户端应用程序中引发任何异常之前.异常处理可能涉及在批处理过程中被视为非常不寻常的情况的回滚.这是合理的.5秒是计算机处理时间非常长的时间.

现在,我在Firebird客户端上使用相同方法的尝试毫无结果,因为"死锁"(实际上是使用中的记录)立即发生.

如果无法将数据库引擎配置为等待一些条件来改进(记录锁定要发布),那么现在责任必须由客户端应用程序开发人员负责,他们必须编写疯狂的慢速代码来克服我认为是主要的Firebird失败了.

一旦检测到"死锁",除非断开连接组件,否则不会清除该情况

while rowsupdated = 0 and counter < 5 do
begin
  try
    rowsupdated := SQLQuery.Execute;
  except
    SQLConnection.Connected := False;
    SQLConnection.Connected := True;
  end;
  Inc(Counter)
end;
Run Code Online (Sandbox Code Playgroud)

当您在使用Delphi中的DBX时在Firebird中没有任何实质性的锁定容差时,如何构建健壮的多用户表更新客户端?

delphi firebird interbase dbexpress

16
推荐指数
1
解决办法
2924
查看次数

如何在分配参数之后但在打开之前记录SQL.text

我试图在大型项目中记录SQL调用,而不对代码进行大量更改.为了开始这个过程,我们决定尝试记录执行的DBX查询.

所以我有:

procedure TRService.GetContactInfo(sessionid: String; msrno: Integer);
var
  SQL: String;
  qryContact: TSQLQuery;
  username: String;
begin
  qryContact := TSQLQuery.Create(nil);
  qryContact.SQLConnection := TSQLConnection1;
  qryContact.SQL.Add('select name, address');
  qryContact.SQL.Add('from contact');
  qryContact.SQL.Add('where (msrno = :msrno)');
  qryContact.ParamByName('msrno').AsInteger := msrno;
  {$ifdef LOGSQL}
  SQL := qryContact.???
  LogSQL(SQL);
  // CallNewServer(SQL);
  {$else}
  qryContact.Open;
  {$endif}
end;
Run Code Online (Sandbox Code Playgroud)

结束;

调用LogSQL函数时,我希望它能够记录

'从联系人中选择*(msrno = 12345)'

哪个属性'.???' 我可以使用TSQLQuery来为我提供已经用值替换的参数的SQL字符串吗?理想情况下,我想在此之前执行此操作qryContact.open,因为在将来的版本中,qryContact.open将由对不同服务器的调用替换.

sql delphi

3
推荐指数
1
解决办法
242
查看次数

android.os.FileUriExposedException: &lt;filename&gt; 通过 Intent.getData() 暴露在应用程序之外

在针对 Android API < 24 的早期版本的 Delphi(10.3 Rio 之前)中,可以创建文件意图,如使用 delphi 使用外部图库打开图像的问题的答案中所示

但是,现在 10.3 以 Android API >= 24 为目标,该代码会产生作为此问题主题的错误。

我努力在Delphi Use android fileprovider to send intent to open and image file with the default android gallery中回答这个问题,但该问题被关闭为重复,即使答案更接近,是在 Android Java 中而不是在 Delphi 中。我的答案如下(经过几个小时的研究)

delphi android

3
推荐指数
1
解决办法
2082
查看次数

如何在txmldocument.xml中获取encoding ="utf-8"?>?

这在Delphi XE2中对我不起作用.

Var
  XMLDoc : IXMLDOCUMENT;
begin
  XMLDoc := NewXMLDocument;
  XMLDoc.Active := True;
  XMLDoc.Version := '1.0';
  XMLDoc.Encoding := 'utf-8';
  XMLDoc.Options := [doNodeAutoIndent];
  Memo1.Text := XMLDoc.XML.Text;
Run Code Online (Sandbox Code Playgroud)

我仍然没有得到encoding="utf-8"?>生成的文档.但如果我说

  XMLDoc.Encoding := 'utf-16';
Run Code Online (Sandbox Code Playgroud)

那么我确实得到encoding="utf-16"?>了最终的文档.

有任何想法吗?任何人?

delphi txmldocument

2
推荐指数
1
解决办法
7427
查看次数

带字符串元素的Delphi XE7 Android记录无法编译

在Delphi FMX XE7,Win32中,我有一个记录类型:

type TSettingsRec = record
  SessionTimeOut: Word;
  EventString: String[50];
end;
Run Code Online (Sandbox Code Playgroud)

当我将目标更改为Android时,我收到编译错误:

[DCC错误] MainForm.pas(45):E2029';' 预期,但'''发现

我需要定义EventString元素的长度[50],因为TRecord实际上是从数据库(Firebird)读取的,该数据库是由Delphi 7程序使用Bin2Hex写入数据库的(原因只有作者才知道)程序):

var
  rec: TSettingsRec;
  settings: string;

SetLength(settings, SizeOf(rec)*2);
BinToHex(@rec, @settings[1]), SizeOf(rec));
Run Code Online (Sandbox Code Playgroud)

我使用XE7(win32)有效解码:

var
  rec: TSettingsRec;
  settings: String;

SetLength(settings, SizeOf(rec) * 2);
System.Classes.HexToBin(Pchar(settings), @rec, SizeOf(rec));
Run Code Online (Sandbox Code Playgroud)

但是,当我为Android编译时,这不起作用.那么如何在Android平台上指定EventString的长度[50]呢?

delphi android firemonkey delphi-xe7

2
推荐指数
1
解决办法
1065
查看次数

Delphi FMX将焦点设置为特定控件,以便显示光标

我创建了一个测试新的FMX项目.添加了TabControl.使用上下文菜单添加3个选项卡.在第3个标签页中添加了一个TEdit.为tabcontrol添加了OnChangeEvent处理程序.编码如下:

procedure TForm1.TabControl1Change(Sender: TObject);
begin
  if TabControl1.ActiveTab = TabItem3 then
  begin
    self.ActiveControl := Edit1;
    self.Focused := Edit1;
    Edit1.SetFocus;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

如您所见,我根据之前的VCL体验尝试了各种组合.输入/光标焦点不会通过代码更改为Edit1.当然,在Win32的运行时,如果我点击edit1,焦点矩形(我正在使用一种样式)现在就像光标一样显示.(正如预期的那样)在Android上.当我自己转移焦点时,VK才出现.

有没有办法以编程方式执行此操作,以便用户可以开始键入?(无需将焦点转移到TEdit本身).

delphi firemonkey

2
推荐指数
1
解决办法
3055
查看次数

利用编译器错误是一种好习惯吗?

最近我发现了一些奇怪的(对我而言)Delphi代码,我把它分离到一个单独的小项目中.这是我发现的.Unit1编译没有错误.Unit2(我提供用于比较)没有.区别在于Classes的方式used.

unit Unit1;

interface

uses Classes; // difference here

type TThread = class(Classes.TThread)
public
   property Terminated;
end;

implementation

end.
Run Code Online (Sandbox Code Playgroud)

Unit2无法编译.产生各种错误.

unit Unit2;

interface

uses System.Classes; // difference here

type TThread = class(Classes.TThread)
public
  property Terminated;
end;

implementation

end.

[dcc32 Error] Unit1.pas(7): E2003 Undeclared identifier: 'Classes'
[dcc32 Error] Unit1.pas(7): E2029 ',' or ':' expected but ')' found
[dcc32 Error] Unit1.pas(9): E2147 Property 'Terminated' does not exist in base class
Run Code Online (Sandbox Code Playgroud)

所以我担心的是这个项目正在利用编译器错误来实现它的目标.编译器错误可能会在以后的版本中修复,然后代码将不再起作用.

delphi

2
推荐指数
2
解决办法
287
查看次数

编译器错误可能吗?{$ define未按预期工作

我正在使用10.3.1(4899).在我项目中表单的最顶部,我有几行看起来像这样:

{$ifdef AA}
  {$define BB}
{$endif]
{$define CC}
Run Code Online (Sandbox Code Playgroud)

在我的代码中,我检查定义并采取相应的行动:

procedure TForm1.Button1Click(Sender: TObject);
begin
  {$ifdef AA}
  ShowMessage('AA');
  {$endif}
  {$ifdef BB}
  ShowMessage('BB');
  {$endif}
  {$ifdef CC}
  ShowMessage('CC');
  {$endif}
end;
Run Code Online (Sandbox Code Playgroud)

也许这应该是一个竞争:当我点击按钮时会显示哪条消息?好的,放弃?答案是没有显示消息.行为是预期的,还是一个错误?

delphi

1
推荐指数
1
解决办法
114
查看次数

防止Android应用.关闭

随着XE7中非阻塞MessageDlg的出现,似乎现在无法有条件地阻止该应用程序.从我们在Windows中关闭(或在XE5中):

procedure TfrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
    CanClose := False;
    FCanClose := False;
    FMX.Dialogs.MessageDlg('Exit?'
        ,
        TMsgDlgType.mtConfirmation, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0,
          procedure(const AResult: TModalResult)
          begin
            if AResult = mrYes then
              FCanClose := True;
          end
    );
    CanClose := FCanClose;

end;
Run Code Online (Sandbox Code Playgroud)

仅在表单已关闭后才调用MessageDlg(和匿名过程),从而使对象失效.哦,如果你想知道我为什么使用FCanclose,那是因为我在匿名程序中遇到了"无法捕获Canclose"的编译器错误.

现在我尝试的另一种可能性是将MessageDlg放在FormKeyUp事件处理程序中并捕获vkHardwareBack.

procedure TfrmMain.FormKeyUp(Sender: TObject; var Key: Word; var KeyChar: Char;
  Shift: TShiftState);
var
  FService: IFMXVirtualKeyboardService;
begin
  if Key = vkHardwareBack then
  begin
    TPlatformServices.Current.SupportsPlatformService(IFMXVirtualKeyBoardService,
        IInterface(FService));
      if (FService <> nil) then
      begin
        if (TVirtualKeyBoardState.Visible in FService.VirtualKeyBoardState) then

        else
        begin
          FMX.Dialogs.MessageDlg('Exit?'
          , …
Run Code Online (Sandbox Code Playgroud)

delphi android firemonkey delphi-xe7

0
推荐指数
1
解决办法
1161
查看次数