Icon Creating and Loading DataSets

Before using the TDataSet component in a client or server application, you must first create an instance of the component, which you can do at design-time or at run-time.

Creating a DataSet at Design-Time
The easiest way to create a dataset is by using the server manager in the IDE to define a database and its contained datasets/commands. Once a dataset has been defined under a database in the server manager, you can easily add the dataset to an existing application by simply dragging it from the server manager and dropping it on a form, request handler, or database designer surface. The relevant property information, including the column definitions, will automatically be populated for the dataset. A database defined in the server manager can be used to create a database in an existing client or server application project by dragging and dropping the database on to the tab gutter of the work area in the IDE:

Image

When the database is dropped on the tab gutter of the work area, a new TDatabase (or descendant) instance will be created for the project, along with an associated source unit, and all of the defined datasets for the database will automatically be created as TDataSet instances in the new database instance. Please see the Using the Server Manager topic for more information.

If you do not wish to use the server manager to create a dataset, you can also create a new dataset by dragging a TDataSet component from the component library and dropping it on a form, request handler, or database designer surface. Please see the Using the Designer topic for more information on adding a component to a designer instance. Once you have dropped the TDataSet component on a form, request handler, or database designer surface, you can manually define the columns in the dataset by double-clicking on the TDataSet's Columns property. This will launch the Columns Editor directly under the component inspector, and you can then use the Columns Editor to add, edit, or delete the columns in the dataset. Please see the Using the Component Inspector topic for more information on how to modify properties in the IDE.

Creating a DataSet at Run-Time
In cases where forms, request handlers, and databases are not being used at design-time, such as with a non-visual project or in a library procedure/function, you can create a dataset instance at run-time using code. The following is an example of creating a dataset, opening it, and populating it with some rows at run-time:

function CreateStatesDataSet: TDataSet;
begin
   Result:=TDataSet.Create(nil);
   with Result.Columns.Add do
      begin
      Name:='Abbrev';   
      DataType:=dtString;
      Length:=2;
      end;
   with Result do
      begin
      Open;
      Insert;
      Columns['Abbrev'].AsString:='CA';
      Save;
      Insert;
      Columns['Abbrev'].AsString:='FL';
      Save;
      Insert;
      Columns['Abbrev'].AsString:='NY';
      Save;
      end;
end;

Datasets are associated with a given database by being created with the database as the (sole) owner parameter. As you can see in the above example, the dataset is created with a nil owner parameter, which will cause this dataset instance to be associated with the global Database TDatabase instance.

Loading a DataSet at Run-Time
As seen in the above example, you can insert rows directly into a dataset at run-time without interacting with the web server. However, most applications will need to load the rows into a dataset using the web server. For both client and server applications, there are two different ways to load rows into a dataset at run-time: the TDatabase LoadRows method and the TDataSet LoadRows method.

TDatabase LoadRows Method

The TDatabase LoadRows method should be used when you want to load the dataset rows from the web server. For client applications, this method automatically handles the server request to the web server. For server applications, the rows are loaded directly from the web server using native API calls.

The TDatabase component uses the following properties to load the dataset rows from the web server:
  • TDatabase BaseURL
    This public property is a read-only, calculated property that returns the concatenation of the TServerSession BaseURL and DatabasesResource properties of the server session referenced in the ActiveServerSession property with the TDatabase DatabaseName property:

    <TServerSession.BaseURL>/<TServerSession.DatabasesResource>/<TDatabase.DatabaseName>

    This property is used by a TDatabase instance in client applications to build the URL used for the server request to the web server. This property is not used in server applications, and is unavailable.


  • TDatabase DatabaseName
    This property defaults to the same value as the TDatabase component's Name property, but is automatically populated for you if you use the drag-and-drop method of creating a TDatabase at design-time. This property is used to identify the database in database access requests and must match the name of an existing database defined on the web server.


  • TDatabase Params
    This property is a string list (TStrings) of "name=value" pairs that represents any application-specific parameters to be used with all dataset commands executed for the database. Please see the Web Server Database Access topic for more information on how dataset commands are defined and how they use input parameters.


  • TDataSet DataSetName
    This property defaults to the same value as the TDataSet component's Name property, but is automatically populated for you if you use the drag-and-drop method of creating a TDataSet at design-time. This property is used to identify the dataset in database access requests and must match the name of an existing dataset defined on the web server within the database specified by the TDatabase DatabaseName property (see above).


  • TDataSet Params
    This property is a string list (TStrings) of "name=value" pairs that represents the parameters used along with the parameters defined in the TDatabase Params property (see above) by the web server to populate any input parameters in the Select dataset command. Please see the Web Server Database Access topic for more information on how dataset commands are defined and how they use input parameters.
As an example, consider a database and dataset that are defined as follows on the web server:

Database Name: Production

DataSet Name: CustomerOrders

Select DataSet Command:

SELECT * FROM custord
WHERE CustomerID=:CustomerID

Assuming that a dataset instance called "CustomerOrders" was created at design-time by dragging and dropping the dataset from the server manager on to a form called "MasterDetailForm", the following code is all that would be needed to load the dataset:

procedure TMasterDetailForm.LoadOrders;
begin
   CustomerOrders.Params.Clear;
   CustomerOrders.Params.Add('CustomerID='+Customer.Columns['CustomerID'].AsString);
   Database.DatabaseName:='Production';  // Uses the default global Database TDatabase instance
   Database.LoadRows(CustomerOrders);
end;

If you aren't using the global Database TDatabase instance and, instead, have created a TDatabase instance in the application, then the code is only slightly different. Assuming that a database instance called "Production" and a dataset instance called "CustomerOrders" was created at design-time by dragging and dropping the database from the server manager on to the tab gutter of the work area in the IDE, the following code is all that would be needed to load the dataset:

procedure TProduction.LoadOrders;
begin
   CustomerOrders.Params.Clear;
   CustomerOrders.Params.Add('CustomerID='+Customer.Columns['CustomerID'].AsString);
   LoadRows(CustomerOrders);
end;

After the rows are successfully retrieved from the web server, the TDatabase LoadRows method will automatically open the dataset using the TDataSet Open method and then automatically call the TDataSet LoadRows method to load the rows into the in-memory cache of the dataset.

TDataSet LoadRows Method

For both client and server applications, the TDataSet LoadRows method directly accepts the dataset rows as a JSON string. This means that this method is more useful for situations where the dataset rows are stored in memory or local storage as a JSON string and need to be directly loaded from one of those locations. It is recommended that you always use the TDatabase LoadRows method for loading rows from a web server and not resort to making custom server requests.

Information The LoadRows method requires that the dataset be open prior to being called. Use the Open method to open the dataset.

Tracking Load Operations
The TDataSet BeforeLoad event is fired before the dataset load actually begins. To prevent the load from occurring, return False as the result in an event handler for this event.

If a dataset load server request was sent to the web server and was not successful due to the web server returning an HTTP status code other than 200 (OK), the OnLoadError event will be fired and will include the error message. If an event handler is not defined for the OnLoadError event, then an exception will be raised with the error message. If a load fails for any reason, then the load request is placed in a pending requests queue for the database. This queue ensures that the database requests can be retried and, when retried, are sent to the web server in the order in which they occurred. You can see if there are any pending database requests by examining the TDatabase NumPendingRequests property. If the NumPendingRequests property is greater than 0, then there are database access requests that need to be retried at some point. Use the TDatabase RetryPendingRequests method to retry any pending database access requests, and the TDatabase CancelPendingRequests method to cancel any pending database access requests.

The TDataSet AfterLoad event is fired after the dataset load completes successfully. If there were any errors during the load process, then this event handler will not get called.
Image