简体   繁体   中英

Datasnap client raises “invalid ordinal” error

I created a Datasnap server (stand-alone tcp/ip using the Wizard) and added the following server method:

function TServerMethods1.GetSomeData(tablename : String): TDataSet;
var 
  qry: TSQLQuery;
begin
  qry := TSQLQuery.Create(nil);
  qry.SQLConnection := SQLConnection1;
  qry.SQL.Add('select *');
  qry.SQL.Add('from ' + tablename);
  qry.Open;
  Result := qry;
end;

On the client side, I have a ClientModuleUnit with a TSQLConnection->TsqlServerMethod->TDataSetProvider->TClientDataSet->DataSource->dBGrid chain "wired up" to retrieve the readonly data from the server. There are tutorials about how to do this, and I have made it work.

procedure TForm3.GetSomeDataClick(Sender: TObject);
begin
  if combobox1.ItemIndex > -1 then
  begin
    // ClientModule.SQLConnection1.Close;
    ClientModule.ClientDataSet1.Close;
    ClientModule.ClientDataSet1.Params.ParamValues['TableName'] := Trim(combobox1.Text);
    ClientModule.ClientDataSet1.Open;
  end;
end;

There are several tablenames in the combobox1. The first time I select a table, the data is retrieved and populates the DBGrid. If I then choose a table that has less fields than the first table, I get an Invalid Ordinal exception. Interestingly, if I choose a table that has less fields first, then the second call uses the fields from the first call - and not all fields are displayed.

The error is raised in Data.DBXCommon.TDBXValueList.GetValueType - too deep and complicated for me to understand, really.

Of course, if I close and open the Datasnap connection (commented above), then the invalid ordinal message isn't raised and it works as I expect it should.

Is this a bug, or just a limitation of the current Datasnap (DBX) implementation?

This behavior implies that your fields remain between calls. So I would clear the fields on those datasets (sqlServerMethod1 & Clientdataset1) before loading them with new data.

procedure TForm3.GetSomeDataClick(Sender: TObject);
begin
  if combobox1.ItemIndex > -1 then
  begin
    ClientModule.ClientDataSet1.Close;

    ClientModule.ClientDataSet1.FieldDefs.Clear;
    ClientModule.sqlServerMethod.FieldDefs.Clear;

    ClientModule.ClientDataSet1.Params.ParamValues['TableName'] := Trim(combobox1.Text);
    ClientModule.ClientDataSet1.Open;
  end;
end;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM