小编Mar*_*lot的帖子

检查查询是否返回比创建时更多的字段并定义其持久字段

当你有一个select*from XXX查询时,你最终可以获得比预期更多的字段,你知道是否有办法检查自创建该查询以来是否添加了新字段并定义了其持久字段?

通常,您可以打开查询,而不必担心是否添加了新字段.如果新字段不在您的持久字段中,那么您将无法看到它们.但是在Datasnap REST服务器上,当您尝试从现在具有比创建其持久字段时更多字段的查询返回数据集时,您会获得AV.

如果想知道是否有快速检查我可以这样做,我可以返回一个更有用的错误而不是AV.

就像是 :

MyQuery.Open;
if MyQuery.FieldDefs.Count <> MyQuery.Fields.Count then begin
  raise Exception.Create('The number of returned Fields doesn''t match the expected');
end;
Run Code Online (Sandbox Code Playgroud)

谢谢

delphi firedac delphi-10.1-berlin

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

无法从Datasnap Server检索大于260.000字节的TStream

我有一个Delphi 10.1 Berlin Datasnap Server,它不能返回大于260.000字节的数据包(通过TStream).

我在Delphi 的\ Object Pascal\DataSnap\FireDAC示例之后编写了它,它也显示了这个问题.

只需打开该示例,在ServerMethodsUnit.pas上将qOrders组件的IndexFieldName设置为空白,并将其SQL属性更改为:

select * from Orders
union 
select * from Orders
Run Code Online (Sandbox Code Playgroud)

现在要发送的数据量超过260.000字节,这似乎是您无法从客户端检索它的点.获得EFDException [FireDAC] [Stan] -710.二进制存储格式无效.

数据作为Stream从服务器上的FDSchemaAdapter获取,然后加载到客户端上的另一个FDSchemaAdpater.客户端和服务器之间的连接也是FireDAC.

这是服务器返回该流的方式:

function TServerMethods.StreamGet: TStream;
begin
  Result := TMemoryStream.Create;
  try
    qCustomers.Close;
    qCustomers.Open;
    qOrders.Close;
    qOrders.Open;
    FDSchemaAdapter.SaveToStream(Result, TFDStorageFormat.sfBinary);
    Result.Position := 0;
  except
    raise;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

这就是客户端检索它的方式:

procedure TClientForm.GetTables;
var
  LStringStream: TStringStream;
begin
  FDStoredProcGet.ExecProc;
  LStringStream := TStringStream.Create(FDStoredProcGet.Params[0].asBlob);
  try
    if LStringStream <> nil then
    begin
      LStringStream.Position := 0;
      DataModuleFDClient.FDSchemaAdapter.LoadFromStream(LStringStream, TFDStorageFormat.sfBinary);
    end;
  finally
    LStringStream.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

客户端无法获取Blob参数的所有数据.我在服务器上保存Stream的内容,以及在客户端上到达Blob参数的内容,并且它们具有相同的大小,但Blob参数的内容的内容被截断,最后几个Kbytes为零.

这就是我在服务器上保存将转到Stream的内容的方法:

FDSchemaAdapter.SaveToFile('C:\Temp\JSON_Server.json', TFDStorageFormat.sfJSON); …
Run Code Online (Sandbox Code Playgroud)

delphi datasnap firedac delphi-10.1-berlin

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

压缩和发送TFDDataset数据后释放表格时的AV

我在发布表单时有一个AV,它在我压缩并将FireDAC数据集的数据发送到远程服务器时出现.

这是我用来压缩TFDDataset数据的代码:

function CompressDataset(Dataset: TFDDataset): TMemoryStream;
var Data: TMemoryStream;
    Compress: TZCompressionStream;
begin
  Result := TMemoryStream.Create;   
  Data := TMemoryStream.Create;
  try
    Compress := TZCompressionStream.Create(Result);
    Dataset.SaveToStream(Data, TFDStorageFormat.sfBinary);
    Data.Position := 0;
    Compress.CopyFrom(Data, Data.Size);
  finally
    Data.Free;
    Compress.Free;
  end;
  Result.Position := 0;
end;
Run Code Online (Sandbox Code Playgroud)

这是将压缩数据发送到远程调用(Datasnap)的代码.

procedure TfrmRentFacturacion_Facturar.btnSendDesgloseClick(Sender: TObject);
var Stream: TMemoryStream;
begin
  if qryFacturacion_Desglose.State = dsEdit then qryFacturacion_Desglose.Post;

  Stream := CompressDataset(qryFacturacion_Desglose);
  try
    spActualizaDesglose.ParamByName('AStream').AsStream := Stream;
    spActualizaDesglose.ExecProc;
  finally
    Stream.Free;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

这段代码留下了一些不稳定的东西,很可能是TFDDataset qryFacturacion_Desglose,并在释放表单时引发AV.但我没有得到可能出错的东西.

PS:感谢@J ...建议检查调用堆栈我找到了问题的根源.这是调用堆栈:

:000000000040E735 TObject.Free + $15
:00000000007F1123 TParamObject.Destroy + $43
:000000000041A155 TInterfacedObject._Release + $55
:000007FEFF2211CE …
Run Code Online (Sandbox Code Playgroud)

delphi memory-management stream firedac delphi-10.1-berlin

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

未声明的标识符 soAllDirectories

我正在尝试使用 TDirectory.GetFiles 函数,但是当我添加 TSearchOptions 第三个参数以强制进行递归搜索时,编译器会引发错误,指出尚未声明 soAllDirectories。

uses System.IOutils,
     System.Types;

procedure TfrmConversio.btnConversioClick(Sender: TObject);
var FilesPas: TStringDynArray;
begin
  FilesPas := TDirectory.GetFiles('C:\Project', '*.pas', soAllDirectories);
  ProgressBar1.Max := Length(FilesPas);
end;
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么 ?。我可以在 System.IOUtils 中看到该常量。

谢谢你。

delphi delphi-10.3-rio

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

How to create an instance of every form in my project?

I have ported an application from ADO to FireDAC applying several RegExp replaces on the source code to convert the ADOQuery, ADOTables, ADOCommands, ADOStoredProcs, etc. ... to the corresponding FireDAC components.

It has worked fine, but now when running that application plenty of forms raise errors because of the type of the persistent fields being different than the type expected (the one defined from ADO when the persistent field was created).

I'm trying to make a list of those errors, …

delphi delphi-10.3-rio

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

Delphi 组件自定义属性不会保存在 DFM 文件中

我在自定义组件上有一个属性,我不想将其保存在 DFM 文件中。我已经覆盖了 DefineProperties 方法以不提供 ReadData 和 WriteData 过程,期望它不会保存其值,但它仍然会保存。

procedure TAEFDQuery.DefineProperties(Filer: TFiler);
begin
  inherited;
  // Set the ADO Compatibility custom properties to not be saved on the DFM
  Filer.DefineProperty('CommandText', nil, nil, False);
end;
Run Code Online (Sandbox Code Playgroud)

不保存此属性的原因是因为我已将一个项目从 ADO 移植到 FireDAC,并且我创建了“假”属性,允许某些 ADO 代码原样运行,将其重定向到相应的 FireDAC 属性。

type
    TAEFDQuery = class(TFDQuery)
    private
        function GetCommandText: string;
        procedure SetCommandText(AValue: string);
    protected
        procedure DefineProperties(Filer: TFiler); override;
    published
        property CommandText: integer read GetCommandText write SetCommandText;
    end;

implementation

procedure TAEFDQuery.SetCommandText(AValue: string);
begin
  SQL.Text := AValue;
end;

function TAEFDQuery.GetCommandText: string;
begin
  Result …
Run Code Online (Sandbox Code Playgroud)

delphi delphi-10.4-sydney

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

触发定期删除数据

我希望触发器在给定时间内(例如每天上午10点)删除给定表中的某些行.我该如何实现?

sql sql-server triggers

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

在 Windows 服务上通过 WinSCP 下载 SFTP 文件冻结

我正在尝试构建一个使用 SFTP 下载一些日志文件并将它们导入数据库的服务。

因为 Delphi 没有自带 SFTP 组件,所以我创建了一个 BAT 文件来使用 WinSCP 下载日志

DownloadLogs.bat:
  WinSCP.com < DownloadLogs.commands

DownloadLogs.commands:
  open sftp://root:password@myserver.com
  option confirm off
  get -delete /var/lib/3cxpbx/Instance1/Data/Logs/CDRLogs files
  exit
Run Code Online (Sandbox Code Playgroud)

这是我的服务:

procedure TsrvCentralita.ServiceExecute(Sender: TService);
const SecondsBetweenExecutions = 10;
var Counter: integer;
    dmLogs: TdmLogs;
begin
  Counter := 0;
  while not Terminated do begin
    Inc(Counter);
    if Counter > SecondsBetweenExecutions then begin
      Counter := 0;
      dmLogs := TdmLogs.Create(Self);
      try
        if dmLogs.DownloadLogs then dmLogs.ImportLogs;
      finally
        dmLogs.Free;
      end;
    end;
    Sleep(1000);
    ServiceThread.ProcessRequests(False);
  end;
end;
Run Code Online (Sandbox Code Playgroud)

这就是我调用 BAT 文件的方式:

function ExecAppWait(AppName: …
Run Code Online (Sandbox Code Playgroud)

windows delphi sftp windows-services winscp

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

使用 RegEx 从源代码中提取逗号分隔的单位

我想使用正则表达式从我的源代码中提取信息。你能帮我构建一个正则表达式来检索源代码中使用的单位吗?。

源代码示例:

unit ComandesVendes;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Manteniment;

type
  TFComandesVendes = class(TFManteniment,ActualitzacioFinestra)
    QRCapsaleraNumero: TIntegerField;
    QRCapsaleraData: TDateTimeField;
    QRCapsaleraDataEntrega: TDateTimeField;
...
...     
Run Code Online (Sandbox Code Playgroud)

我需要从uses子句到下一个;. 在该示例中,输出必须是:

Windows
Messages
SysUtils
Variants
Classes
Graphics
Controls
Forms
Dialogs
Manteniment
Run Code Online (Sandbox Code Playgroud)

我正在尝试类似的东西

^ *uses(\n* *(\w*),)* *\n* *(\w*) *;
Run Code Online (Sandbox Code Playgroud)

它匹配 uses 子句,但它不会分别返回每个文件名。

谢谢你。

regex delphi delphi-10.3-rio

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

更改Sysem.Variants.VarToWideStr的区域设置格式

我的应用程序上的第三方组件(FastReports)广泛使用System.Variants.VarToWideStr函数,该函数很好,但它忽略了我需要该应用程序使用的区域设置。

例:

FormatSettings.ShortDateFormat := 'dd/mm/yyyy';
ShowMessage(VarToWideStr(Date));
FormatSettings.ShortDateFormat := 'yyyy/mm/dd';
ShowMessage(VarToWideStr(Date));
Run Code Online (Sandbox Code Playgroud)

此代码始终返回相同的字符串,而忽略了我指示要使用的应用程序的区域设置。

您是否知道另一种更改应用程序(具体是VarToWideStr)将要使用的区域设置的方法?

delphi date-formatting delphi-10.1-berlin

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