当你有一个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 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) 我在发布表单时有一个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) 我正在尝试使用 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 中看到该常量。
谢谢你。
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, …
我在自定义组件上有一个属性,我不想将其保存在 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) 我正在尝试构建一个使用 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) 我想使用正则表达式从我的源代码中提取信息。你能帮我构建一个正则表达式来检索源代码中使用的单位吗?。
源代码示例:
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 子句,但它不会分别返回每个文件名。
谢谢你。
我的应用程序上的第三方组件(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)将要使用的区域设置的方法?