当你有一个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)
谢谢
在我们现有的代码中,我们有一堆这样的表单,其中使用MainForm作为所有者(而不是nil)创建表单,但我们明确地释放它.
function SomeFunc(): Boolean;
var
form: TMyForm; // subclasses TForm
begin
with TMyForm.Create(Application.MainForm) do
try
ShowModal;
Exit(True);
finally
Free;
end
end;
Run Code Online (Sandbox Code Playgroud)
这会导致任何形式的错误或崩溃,还是安全的?
我似乎无法通过阅读文档来解决这个问题:
http://docwiki.embarcadero.com/Libraries/Berlin/en/System.Classes.TComponent.Owner
http://docwiki.embarcadero.com/Libraries/Berlin/en/System.Classes.TComponent.Create
我有一个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) 我有一个要移植到FireMonkey的VCL应用程序。我遇到的一件事MessageDlg(...)是FireMonkey不推荐使用。关于进一步的挖掘,我了解我必须使用该FMX.DialogService.MessageDialog方法。所以我创建了一个显示对话框的函数:
function TfMain.GetDeleteConfirmation(AMessage: String): String;
var
lResult: String;
begin
lResult:='';
TDialogService.PreferredMode:=TDialogService.TPreferredMode.Platform;
TDialogService.MessageDialog(AMessage, TMsgDlgType.mtConfirmation,
[ TMsgDlgBtn.mbYes, TMsgDlgBtn.mbCancel ], TMsgDlgBtn.mbCancel, 0,
procedure(const AResult: TModalResult)
begin
case AResult of
mrYes: lResult:='Y';
mrCancel: lResult:='C';
end;
end);
Result:=lResult;
end;
Run Code Online (Sandbox Code Playgroud)
我不认为我做对了,因为我不确定是否可以在匿名方法中设置局部变量,但是仍然可以编译。
我这样称呼它:
if GetDeleteConfirmation('Are you sure you want to delete this entry?')<>'Y' then
exit;
Run Code Online (Sandbox Code Playgroud)
当我运行它时,显示的消息对话框是这样的:
它不显示2个按钮(是,取消)。有人可以帮我解决这个问题-即用2个按钮正确显示消息对话框,并将消息对话框的模态结果作为函数的结果发送回去。
我正在使用Delphi 10.1 Berlin Update 2。
提前谢谢了!
编辑20170320:我根据下面的@LURD的正确答案更正了我的代码,为了完整性起见在这里包括了它:
function TfMain.GetDeleteConfirmation(AMessage: String): String;
var
lResultStr: String;
begin
lResultStr:='';
TDialogService.PreferredMode:=TDialogService.TPreferredMode.Platform;
TDialogService.MessageDialog(AMessage, TMsgDlgType.mtConfirmation,
FMX.Dialogs.mbYesNo, TMsgDlgBtn.mbNo, 0,
procedure(const AResult: TModalResult) …Run Code Online (Sandbox Code Playgroud) 有System.SysUtils.TShortIntHelper(和其他人)我可以写:
output := 5.ToString();
Run Code Online (Sandbox Code Playgroud)
将数字格式化5为string.同样,有System.SysUtls.TExtendedHelper,但我无法编译:
output := (5.0).ToString();
Run Code Online (Sandbox Code Playgroud)
E2018:需要记录,对象或类类型
其他不起作用的版本:
5.0.ToString()(1.0+5.1).toString()(5+0.).toString() (说E2029:')'预期但'''找到了)实际工作的版本:
(1+5.1).toString()(1.1+1+5.1).toString()5.9e0.toString()如果声明了扩展值const,它也不起作用:
function TestFormat(): String;
const
q = 5.5;
begin
Result := q.ToString();
end;
Run Code Online (Sandbox Code Playgroud)
但它的定义是q : extended = 5.5;有效的.所以,我想知道为什么编译器会以这种方式运行.
这与具有子窗体的Delphi应用程序有关,该子窗体已显示然后隐藏但未释放。如果用户将鼠标悬停在应用程序的(Windows 10)任务栏“迷你视图”上,则隐藏的窗体将变得可见(在悬停期间)。当用户单击迷你视图以将焦点更改为时,它们将隐藏。应用程序。有什么办法可以避免这种情况?
重新创建:
请注意,最小化应用程序并还原它可以“修复”影响,直到下次显示表单为止。也许这是导致问题的线索或解决方法的线索?这并不是一个大问题,因为它似乎并没有引起任何实际问题,但是看起来确实不专业。
根据要求添加代码(但是,这不会很有趣。)
program Project1;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TForm2, Form2);
Application.Run;
end.
// Only code that was added to TForm1:
procedure TForm1.Button1Click(Sender: TObject);
begin
// Show and then hide the form or use ShowModal and close it before testing the hover.
Form2.Show;
Form2.Hide;
// Form2.ShowModal;
end;
Run Code Online (Sandbox Code Playgroud)
更新:如何仅使用Delphi IDE显示问题。
我很惊讶没有得到除零异常.我怎样才能找回来?
柏林10.1最近安装,新项目,
procedure TForm1.Button1Click(Sender: TObject);
var
a: Double;
begin
a := 5/0; // No exception
ShowMessage(a.ToString); // -> 'INF'
end;
Run Code Online (Sandbox Code Playgroud) 我需要按整数字段对数组进行排序,1-n在开头排序,最后为零:0,0,3,1,2 - > 1,2,3,0,0
我不知道如何一次性排序,所以我尝试了两种,但它没有产生正确的结果:
它确实在最后添加了零,但它弄乱了1-n个有序物品:
0,0,3,1,2 - >(第一种)0,0,1,2,3 - >(第二种)2,3,1,0,0
procedure TForm2.Button1Click(Sender: TObject);
var
Arr: TArray<integer>;
begin
SetLength(Arr, 5);
Arr[0] := 0;
Arr[1] := 0;
Arr[2] := 3;
Arr[3] := 1;
Arr[4] := 2;
// First sort: Sort 1-n
TArray.Sort<integer>(Arr, TComparer<integer>.Construct(function(const Left, Right: integer): Integer
begin
if Left < Right then
Result := -1
else if Left > Right then
Result := 1
else
Result := 0;
end
));
// Second sort: Put zeros at the end
TArray.Sort<integer>(Arr, TComparer<integer>.Construct(function(const …Run Code Online (Sandbox Code Playgroud) 在VCL Forms程序中,我有一个Form,它实现了一种处理Windows消息和更新Form上某些控件的方法,如:
procedure OnMsgTest (var Msg: TMessage); message WM_CUSTOMTEST;
Run Code Online (Sandbox Code Playgroud)
我使用PostMessage自定义消息到此表单,使用如下代码:
h := FindWindow('TFrmTest', nil);
if IsWindow(h) then begin
PostMessage(h, WM_CUSTOMTEST, 0, 0);
end;
Run Code Online (Sandbox Code Playgroud)
当Form实例化多次时,使用上面的代码发送消息,只有一个Form实例更新屏幕上的信息.我希望所有打开和实例化的表单都能收到消息.
一个重要的注意事项:PostMessage可以在Form进程本身内发生,也可以从另一个进程发生.所以,我认为通过Forms的循环不起作用.
达到目标的最佳方法是什么?
我在柏林的Delphi 10.1中有一个简单的项目。在项目设置中,我一次选中了“预发布”。
现在,我有两件事,无论我更改多少次,我都会回来并且不会保存。这些是:
Release号(从更改0为1)请注意,在屏幕截图中,下面的“文件版本”显示了保存时的正确版本号0.2.0。但是上面的Release数字已更改为1。
实际上,我删除了在所有其他构建配置中包括版本设置的选项。它仅在Win32 - Release构建下存在。
编辑
看来实际上什么也没有保存!例如,我更改了“自动增量生成”选项,但该选项也没有保留。如果我导航到其他构建配置,然后再次切换回去,我的条目也会丢失。它唯一保留的是底部的网格。
编辑
一些更奇怪的行为-如果将设置Release为更大的数字,例如2,它将保存它。但是,如果我将其设置为0,则会将其重置为1。好像不希望这样0(尽管这是新项目的默认设置)。
delphi ×10
firedac ×2
arrays ×1
datasnap ×1
exception ×1
firemonkey ×1
integer ×1
sorting ×1
versioning ×1