I have two table Country and City (country_id is PK in Country table and country_id is FK in City table).
Which component use to create relation between two query for fast report.
Which structure should be:
Query 2. Client Data set .... 3. ? 4.?
This is usually called a Master-Detail relationship between the datasets involved.
In Delphi, you set one up by connecting the Detail dataset to a TDataSource whose dataset is the connected to the Master dataset. You can do this on the server side (i.e between the two queries, using the DataSource property of the Detail or between two clientdatasets using the MasterSource property of the.Detail. When doing it on the server side, you write the SQL for the query as a parameterised query, with the parameter being one whose value matches the Master's PK as in
Select * from mydetailtable where masterid = :masterid
Once a Master-Detail relationship has been set up between two datasets, it should work with virtually any report generator, FastReports included.
See e.g. http://docwiki.embarcadero.com/RADStudio/Rio/en/Setting_Up_Master-Detail_Linked_Relationships which talks about this in terms of DBExpress components, but the principle is applicable to other Delphi dataset components.
Related
In SSRS I am trying to create a table or matrix using two datasets that have a one-to-many relationship. The table/matrix needs to be tied to the one relationship and join to the many.
I initially tried to do a lookup function, but that is a one-to-one relationship and just returned one value. I'm looking to return all values and each one on a separate row. Here is an example of two datasets, I want to join on the CustomerID column and return the CountriesOfBusiness column. Is there a different function in SSRS that will do this?
Try this expression in table/matrix: (set Dataset name to be: DataSet1)
=Join(LookupSet(Fields!CustomerID.Value, Fields!CustomerID.Value, Fields!Countries.Value, "DataSet2"), VbCrlf)
I want to create only certain columns on my "dbgrid" at run-time, and set them to
other table field(s) or same field . How do you do that :
illustration:
I have 3 Tables :
Student(IdStudent, NameStudent ...) ,
Module(idModul,NameModule...),
Notes(idNote,idStudent,idModul,Note).
I Want to insert All Notes in one Dbgrid and names of columns of DBgrid are names of Module Table. I have No idea?
Thanks.
You cannot do this with a dbgrid; dbgrids have only one datasource and a datasource has only one dataset. If you are using an SQL compliant database you should look into a join and/or crosstab to return a single dataset. (I think this is what MartynA is talking about) Or create a clientdataset at run-time and build it with the columns/data you want if you want data-aware. I would look into using a stringgrid, listview or treeview and build the whole thing by hand.
I am rewriting an existing BDE database program to use Firebird using the FibPlus components.
Since I almost every where used TQuery components, the change is fairly straightforward.
Apart from one thing I dont't seem to find :
In one of my forms I have two grids above each other, linked to TTable components, where the grid below only displays records with the same key as the selected record in the upper grid - so master/detail relationship.
This was done easy in BDE using the MasterSource and MasterFields properties.
How can this be achieved using the FibPlus FibDataset or FibQuery components ?
I don't think it's possible with a FibQuery, but with a FibDataSet there is a DataSource property which you should point to a DataSource connected to the master DataSet.
In the Detail fibDataSet a where clause shoudl be used where the parameter has the same name as the master field for the detail table in the master table.
For example:
master pFibDataSet CustomerspFibDataSet with the following SQL:
select cusotmerid, name, address, country from customers
A master DataSource CustomersDataSource with property DataSet set to CustomerpFibDataSet
detail pFibDataset OrderspFibDataSet with the property DataSource set to CustomersDataSource and the following SQL:
select orderid, date, amount from orders
where customerid = :customerid
I need a little help with ClientDatasets in Delphi.
What I want to achieve is a grid showing customers, where one of the columns shows the number of orders for each customer.
I put a ClientDataset on a form and load Customers.xml from Delphi demo-data.
Another ClienDataset is loaded with orders.xml.
Relatively simple, I can define an aggregate on the orders CDS showing the total amount per customer (or the count). (See Cary Jensens article on this: http://edn.embarcadero.com/article/29272)
The problem is getting this aggregate result from orders dataset into the customer dataset.
It is kind of an reverse lookup, since there is a 1-n relationship between customers and orders, not an n-1 as normally in lookup scenarios.
Any ideas ?
Søren
Maybe you could define a calculated field in the customers dataset which would simply take the value of the aggregated field in the orders dataset.
Have you tried to do a Master (Customers) - Detail (Orders) relation?
It's not a lookup situation.
Now I have seen this question in another forum but it didn't had an acceptable answer.
Suppose I have two tables, the Groups table and the Elements table. The tables have no defined relationships. The Elements table has an IdGroup field that refers to the IdGroup (PK) field of the Groups table.
I use the following query through an ADO recordset to populate the tables values to a datagrid:
SELECT Elements.*, Groups.GroupName
FROM Elements
INNER JOIN Groups ON Elements.IdGroup = Groups.IdGroup
From that grid I want to press Delete in order to delete an Element. Here is my problem. When I used DAO, the DAO Delete() function deleted only the record in the Elements group. This was the expected behavior.
When I changed to ADO, the Delete() function deleted records in both tables, the element record and the group to which the element belonged!
Is there any way to reproduce the DAO behavior in ADO without having to define relationships into the tables?
Note: I know there are alternatives (executing DELETE querys could do the job). Just show me a way to do this in ADO, or say it cannot be done.
Rewrite you query to:
replace the INNER JOIN with a WHERE clause consisting of an EXISTS;
use a subquery in the SELECT clause to return the value of Groups.GroupName.
Example:
SELECT Elements.*,
(
SELECT Groups.GroupName
FROM Groups
WHERE Elements.IdGroup = Groups.IdGroup
)
FROM Elements
WHERE EXISTS (
SELECT *
FROM Groups
WHERE Elements.IdGroup = Groups.IdGroup
);
I've tested this using SQL Server 2008 with a ADO recordset set as the DataSource property of a Microsoft OLEDB Datagrid Control (MSDATGRD.OCX) then deleting the row via the gird (I assume you are doing something similar) and the row is indeed deleted from table Elements only (i.e. the row in Groups remains undeleted).
Note the revised query may have a negative impact on performance when fetching rows.