Re-Introduction to FireDAC Data Access (3)
Embarcadero Japan - 16/Jun/2020
Embarcadero Japan - 16/Jun/2020
[SHOWTOGROUPS=4,20]
Exercises for creating an application that updates data
In this blog, I will explain the basic usage of FireDAC for those who have used Delphi / C++Builder to some extent.
The third theme
Datasets are one of the most important items to keep in mind when developing applications that access data.
FireDAC dataset overview
The data set is, in short, the concept of a "container" for holding the records (data) retrieved from the database in memory.
A Delphi/C++Builder dataset maps and holds records from single or multiple tables retrieved from a database into a manageable data format (in Delphi/C++Builder). And that data can all be represented in rows and columns.
However, the dataset is not just a container, it provides processes involving complicated operations such as organizing records (data) and manipulating data as an encapsulated dataset object (class).
The Delphi/C++Builder dataset object (hereafter dataset) has a class named "TDataSet" that has the basic properties, events and methods, which is the base class for all datasets. Become.
Applications that access databases created with Delphi / C++Builder all use datasets derived from TDataSet. This means that whatever data set you use, the method determined by TDataSet can be used, greatly simplifying data access by the data set.
The FireDAC dataset is also derived from the TDataSet class and has been extended to a dataset with FireDAC-specific features.
The FireDAC dataset inheritance diagram is shown below.
The main types of datasets that are frequently used in FireDAC are as follows.
*Details of TFDMemTable will be introduced in another part of this blog series.
The general characteristics of FireDAC datasets are that they are highly compatible with BDE datasets and are easy to migrate in terms of code level and functionality.
However, please note that there are some precautions regarding the transition from BDE TTable.
FireDAC provides TFDTable which is compatible with TTable for migration from BDE, but there are many restrictions regarding the use of TFDTable, and extra overhead may occur especially when acquiring data. This can cause performance issues. For details, Для просмотра ссылки Войдиили Зарегистрируйся see here.
*Tips for improving the execution performance of FireDAC will be introduced in another part of this blog series.
Now let's look at a concrete example of using the FireDAC dataset.
Specific example of using data set
Before we do the exercise of creating an application in the next section, we will explain some basic usages by using the TFDQuery data set as an example.
If you already know how to use datasets, skip this section and do the exercises.
Data acquisition and reference
You can get the data (result set) by executing the Open method of the data set.
Delphi:
FDQuery1.Open('select * from Employee');
Or
FDQuery1.SQL.Text:='select * from Employee';
FDQuery1.Open();
C++Builder:
FDQuery1->Open("select * from Employee");
Or
FDQuery1->SQL->Text = "select * from Employee";
FDQuery1->Open();
TFDQuery has SQL properties. If you specify the SQL statement before opening, you can execute the Open method without parameters.
You can also execute a query with parameters. The following is an example.
Delphi:
FDQuery1.SQL.Text:='select * from Employee where EMP_NO = :empno';
FDQuery1.ParamByName('empno').AsInteger:=11;
FDQuery1.Open();
C++Builder:
FDQuery1->SQL->Text="select * from Employee where EMP_NO = :empno";
FDQuery1->ParamByName("empno")->AsInteger=11;
FDQuery1->Open();
Use the :<name> syntax to include the parameter in the SQL text . You can then specify the parameter by assigning a value to TFDQuery's ParamByName( <name> ) method.
Be sure to specify the same (name) character string for <name> .
In the code example above, <name>=empno.
The result set obtained by opening the data set can be referenced using the FieldByName( <field name>) method of TFDQuery.
The following is an example.
Delphi:
FDQuery1.Open('select FIRST_NAME from Employee');
while not FDQuery1.Eof do
begin
// Output the referenced data to a memo
Memo1.Lines.Add(FDQuery1.FieldByName('FIRST_NAME').AsString);
FDQuery1.Next;
end;
C++Builder:
FDQuery1->Open("select FIRST_NAME from EMPLOYEE");
while (!FDQuery1->Eof) {
// Output referenced data to memo
Memo1->Lines->Add(FDQuery1->FieldByName("FIRST_NAME")-> AsString);
FDQuery1->Next();
}
Close the dataset
Call the Close method to close the dataset.
The following is a code example that reopens a dataset.
Delphi:
FDQuery1.Close;
FDQuery1.Open('select * from Employee');
C++Builder:
FDQuery1->Close();
FDQuery1->Open("select * from Employee");
Edit/update data
You can call the Edit method to edit the data in the dataset's current cursor row, and the Post method to update the edited data.
The code example for updating the data is as follows.
Delphi:
FDQuery1.SQL.Text:='select * from EMPLOYEE Where EMP_NO=:empno';
FDQuery1.ParamByName('empno').AsInteger:=11;
FDQuery1.Open;
FDQuery1.Edit;
FDQuery1.FieldByName('FIRST_NAME'). AsString:='Marco';
FDQuery1.FieldByName('LAST_NAME').AsString:='Cantu';
FDQuery1.Post;
C++Builder:
FDQuery1->SQL->Text="select * from EMPLOYEE Where EMP_NO=:empno";
FDQuery1->ParamByName(“empno”)->AsInteger=11;
FDQuery1->Open();
FDQuery1->Edit();
FDQuery1 ->FieldByName("FIRST_NAME")->AsString="Marco";
FDQuery1->FieldByName("LAST_NAME")->AsString="Cantu";
FDQuery1->Post();
When updating data in the FireDAC dataset, the following error may occur.
In FireDAC, if the table does not have a primary key , multiple [x] rows may be detected in the update target , and the above error occurs.
Please be careful, especially when you move from BDE to FireDAC.
If you encounter this error, try the following settings. (excerpt from docwiki)
SQL statement execution
TFDQuery can directly execute SQL statements to add, update, or delete records.
The following is a code example that executes record update (update statement).
Delphi:
FDQuery1.SQL.Text :='update EMPLOYEE set FIRST_NAME=:NAME where EMP_NO=15';
FDQuery1.ParamByName('NAME').AsString:='Marco';
FDQuery1.ExecSQL;
C++Builder:
FDQuery1->SQL->Text :="update EMPLOYEE set FIRST_NAME=:NAME where EMP_NO=15";
FDQuery1->ParamByName("NAME")->AsString="Marco";
FDQuery1->ExecSQL;
If you want to execute an SQL statement such as insert, update, or delete that does not require result set retrieval, execute the ExecSQL method instead of the Open method.
In FireDAC, you can select the TFDQuery placed on the form and right-click the mouse to start [Query Editor].
In FireDAC's Query Editor, you can enter a SQL statement in [SQL Command] and execute it on the fly.
When the [OK] button is clicked, the SQL statement entered in the SQL command is saved as is in the TFDQuery.SQL property.
[/SHOWTOGROUPS]
Exercises for creating an application that updates data
In this blog, I will explain the basic usage of FireDAC for those who have used Delphi / C++Builder to some extent.
The third theme
- FireDAC dataset overview
- Specific example of using data set
- Exercises for creating an application that updates data
Datasets are one of the most important items to keep in mind when developing applications that access data.
FireDAC dataset overview
The data set is, in short, the concept of a "container" for holding the records (data) retrieved from the database in memory.
A Delphi/C++Builder dataset maps and holds records from single or multiple tables retrieved from a database into a manageable data format (in Delphi/C++Builder). And that data can all be represented in rows and columns.
However, the dataset is not just a container, it provides processes involving complicated operations such as organizing records (data) and manipulating data as an encapsulated dataset object (class).
The Delphi/C++Builder dataset object (hereafter dataset) has a class named "TDataSet" that has the basic properties, events and methods, which is the base class for all datasets. Become.
Applications that access databases created with Delphi / C++Builder all use datasets derived from TDataSet. This means that whatever data set you use, the method determined by TDataSet can be used, greatly simplifying data access by the data set.
The FireDAC dataset is also derived from the TDataSet class and has been extended to a dataset with FireDAC-specific features.
The FireDAC dataset inheritance diagram is shown below.
The main types of datasets that are frequently used in FireDAC are as follows.
Data set name | Use | Characteristic |
---|---|---|
TFDTable | Data set dealing with a single table | BDE equivalent to TTable |
TFDQuery | Data set that handles SQL statement execution and result set(s) | Execution performance is better than using TFDTable |
TFDMemTable | In-memory dataset | Can be used as a local DB like TClientDataSet |
The general characteristics of FireDAC datasets are that they are highly compatible with BDE datasets and are easy to migrate in terms of code level and functionality.
However, please note that there are some precautions regarding the transition from BDE TTable.
FireDAC provides TFDTable which is compatible with TTable for migration from BDE, but there are many restrictions regarding the use of TFDTable, and extra overhead may occur especially when acquiring data. This can cause performance issues. For details, Для просмотра ссылки Войди
| TFDQuery is recommended as a candidate for a replacement dataset from TTable. TFDQuery has the same properties and methods as BDE's TTable and has better execution performance than TFDTable, so TFDQuery is the best candidate for replacement. |
Now let's look at a concrete example of using the FireDAC dataset.
Specific example of using data set
Before we do the exercise of creating an application in the next section, we will explain some basic usages by using the TFDQuery data set as an example.
If you already know how to use datasets, skip this section and do the exercises.
Data acquisition and reference
You can get the data (result set) by executing the Open method of the data set.
Delphi:
FDQuery1.Open('select * from Employee');
Or
FDQuery1.SQL.Text:='select * from Employee';
FDQuery1.Open();
C++Builder:
FDQuery1->Open("select * from Employee");
Or
FDQuery1->SQL->Text = "select * from Employee";
FDQuery1->Open();
TFDQuery has SQL properties. If you specify the SQL statement before opening, you can execute the Open method without parameters.
You can also execute a query with parameters. The following is an example.
Delphi:
FDQuery1.SQL.Text:='select * from Employee where EMP_NO = :empno';
FDQuery1.ParamByName('empno').AsInteger:=11;
FDQuery1.Open();
C++Builder:
FDQuery1->SQL->Text="select * from Employee where EMP_NO = :empno";
FDQuery1->ParamByName("empno")->AsInteger=11;
FDQuery1->Open();
Use the :<name> syntax to include the parameter in the SQL text . You can then specify the parameter by assigning a value to TFDQuery's ParamByName( <name> ) method.
Be sure to specify the same (name) character string for <name> .
In the code example above, <name>=empno.
The result set obtained by opening the data set can be referenced using the FieldByName( <field name>) method of TFDQuery.
The following is an example.
Delphi:
FDQuery1.Open('select FIRST_NAME from Employee');
while not FDQuery1.Eof do
begin
// Output the referenced data to a memo
Memo1.Lines.Add(FDQuery1.FieldByName('FIRST_NAME').AsString);
FDQuery1.Next;
end;
C++Builder:
FDQuery1->Open("select FIRST_NAME from EMPLOYEE");
while (!FDQuery1->Eof) {
// Output referenced data to memo
Memo1->Lines->Add(FDQuery1->FieldByName("FIRST_NAME")-> AsString);
FDQuery1->Next();
}
Close the dataset
Call the Close method to close the dataset.
The following is a code example that reopens a dataset.
Delphi:
FDQuery1.Close;
FDQuery1.Open('select * from Employee');
C++Builder:
FDQuery1->Close();
FDQuery1->Open("select * from Employee");
Edit/update data
You can call the Edit method to edit the data in the dataset's current cursor row, and the Post method to update the edited data.
The code example for updating the data is as follows.
Delphi:
FDQuery1.SQL.Text:='select * from EMPLOYEE Where EMP_NO=:empno';
FDQuery1.ParamByName('empno').AsInteger:=11;
FDQuery1.Open;
FDQuery1.Edit;
FDQuery1.FieldByName('FIRST_NAME'). AsString:='Marco';
FDQuery1.FieldByName('LAST_NAME').AsString:='Cantu';
FDQuery1.Post;
C++Builder:
FDQuery1->SQL->Text="select * from EMPLOYEE Where EMP_NO=:empno";
FDQuery1->ParamByName(“empno”)->AsInteger=11;
FDQuery1->Open();
FDQuery1->Edit();
FDQuery1 ->FieldByName("FIRST_NAME")->AsString="Marco";
FDQuery1->FieldByName("LAST_NAME")->AsString="Cantu";
FDQuery1->Post();
When updating data in the FireDAC dataset, the following error may occur.
| [FireDAC][DApt]-400. The Update command updated the [x] records, not the [1] records. Possible reasons: update table does not have a primary key or row identifier. Record modified or deleted by another user |
Please be careful, especially when you move from BDE to FireDAC.
If you encounter this error, try the following settings. (excerpt from docwiki)
| Exclude fiMeta from FetchOptions.Items and use one of the following: • Set UpdateOptions.KeyFields to a semicolon (';') separated list of column names. · Include pfInKey in the corresponding TField.ProviderFlags property. For more information, please see the note Для просмотра ссылки Войди |
SQL statement execution
TFDQuery can directly execute SQL statements to add, update, or delete records.
The following is a code example that executes record update (update statement).
Delphi:
FDQuery1.SQL.Text :='update EMPLOYEE set FIRST_NAME=:NAME where EMP_NO=15';
FDQuery1.ParamByName('NAME').AsString:='Marco';
FDQuery1.ExecSQL;
C++Builder:
FDQuery1->SQL->Text :="update EMPLOYEE set FIRST_NAME=:NAME where EMP_NO=15";
FDQuery1->ParamByName("NAME")->AsString="Marco";
FDQuery1->ExecSQL;
If you want to execute an SQL statement such as insert, update, or delete that does not require result set retrieval, execute the ExecSQL method instead of the Open method.
In FireDAC, you can select the TFDQuery placed on the form and right-click the mouse to start [Query Editor].
In FireDAC's Query Editor, you can enter a SQL statement in [SQL Command] and execute it on the fly.
When the [OK] button is clicked, the SQL statement entered in the SQL command is saved as is in the TFDQuery.SQL property.
[/SHOWTOGROUPS]