Topic: Linking 2 tables on specific fields

I have 2 tables; CLIENT and CALLS

CLIENT has fields "accountnumber", "name", "address" & "phonenumber". Records in this table will be done manually.

CALLS has fields "accountnumber", "date", "duration" & "cost". Records in this table will be imported from an Excel or csv file.

How can I link CLIENT to CALLS by the "accountnumber" fields, so that when I look at a particular clients details all their calls are also shown?

Thanks

Re: Linking 2 tables on specific fields

Hello Knobby,


If I am not mistaking, creating a relationship between tables in MVD is easily done by using the relationship type of field at design time. But the foreign key is always linked to the id field in MVD. I do not think you can change that behavior directly in MVD.


I see two different approches to your problem :


What you can do to stick to your specifications is add this constraint manually, keeping in mind that during the all conception process, each time you will recompile your application add start with a blank database, this feature will drop sad


To add a foreign key by script, you'll need something like :

ALTER TABLE calls
ADD FOREIGN KEY (accountnumber)
REFERENCES clients(accountnumber)

You'll have to double check that script, I'm working by head, drinking my morning coffee in the garden and not fully awake yet smile


As I said, this modification will drop each time you delete your database and recreate a new one with MVD. Once the script was run once, as long as you keep the same database file, even if you recompile MVD, the modification will stand.

What I usually do in such cases is, on start of the application I distribute, I check a flag in a parameters table to see if this is the first time the application is run. If yes, the the script fires before anything else, if no then the application starts normally.


Also keep in mind that you are creating constraints manually, so you'll have to check yourself for consistency. You said that the calls would be imported. Make sur there is no accountnumber in your imported file that would not be present in your clients table or you'll get errors.


The second approach would be to add a relationship table between the clients and the calls table. You could name it clients_calls and just add a relationship to the clients table and to the calls table. This would probably be easier than modifying the database by script.


Anyway, I hope this is not to theorical as an explanation. Don't let yourself be discouraged by this little problem, there is always a solution and people here on the forum will help you further if needed. Do not hesitate to ask.


Cheers



Math

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Linking 2 tables on specific fields

Thanks for taking the time to reply.

It seems very complicated for what should be a very simple operation. I used to use Alpha 5 database and you could create a relationship using any field you wanted.

How would option 2 work, i.e. having a link table between CLIENTS and CALLS? What would be the fields required and how would the relationship work?

4 (edited by mathmathou 2016-11-28 05:28:15)

Re: Linking 2 tables on specific fields

Hello knobby,


I think I did not read carefully you request, or I should have noticed what you were writing : you can show all the calls related to a client without using the accountnumber as a link between them.

Furthermore, you can not in MVD link your calls to your clients on the accountnumber. This needs a lot of scripting and is just not practical for the average user. But you will need it in your import file if you want to be able to link your imported calls with your clients.
But with a very slight modification, you can achieve what you want.


I noticed you did not mention any ID for either you clients or your calls tables. Such denormalized tables can not be build with MVD, for the same reason as stated previously, it is not easy nor useful for the average user.


One more thing before giving you the sample project : forget about my complicated solutions : I tend to script as much as I can (because I love it). I am known on the forum for that and I sometimes tend to forget that the simpler, the better smile


Now, on to your project :


1 client can have multiple calls. So I just added a reference to the id of the client in the calls table.


Take a look at the Button1 (hidden when the application is running) and how it is configured. It's a search button, fetching the calls table according to the client you select in the left tablegrid (the tablegrid has increm. search parameter linked to button1), and displaying the results in the right tablegrid


Had a new call with the button and you'll see it appear right away. No code, no script, just pure MVD.



Sorry if I frightened you with my complicated solutions, I'll try to keep it simple next time.


Cheers



Mathias

PS : if you need help for the CSV of Excel import, do not hesitate. There will be script needed for that because your file to import will not contain the client id.
1- read one line of the file and get accountnumber
2 - get the client id based on accountnumber (sql query)
3- insert the data in the calls table (second sql query)
4- read next line...

Post's attachments

Attachment icon clients_calls.zip 334.7 kb, 419 downloads since 2016-11-28 

I'm a very good housekeeper !
Each time I get a divorce, I keep the house

Zaza Gabor

Re: Linking 2 tables on specific fields

knobby
There is no need to have the field "accountnumber" in the table "CALLS", because it's information belong  to CLIENT.
The table "CALLS" must have foreign key to "CLIENT" table.


Please attach your project with CSV file (zip file without exe and dlls), I will try to help you.

Dmitry.

Re: Linking 2 tables on specific fields

Knobby,
I am familiar with Alpha 5. I have used it as well and still do on occasion. You are right that you can set relationships on any field in Alpha. However, I always used auto increment integers for primary keys, much like MVD does. It's really a better database design to do so. Having said this I used Mathias project and adjusted it to include the CSV import so you can see how it all works using MVD's relationship definition. There is nothing fancy with the code. The only error checking I did was to check to see if there is no matching account number in the CLIENTS table. Errors are imported into an Error table so you can see which calls were not imported. Hope this helps.

Post's attachments

Attachment icon clients_calls (2).zip 585.2 kb, 425 downloads since 2016-11-30 

Re: Linking 2 tables on specific fields

Morning EHwagner, Mathias, Knobby,
Thanks for the example - very nice. 
And easy to alter to suit other applications that require data to be loaded from .csv. 
A definite "keeper".
Regards,
Derek.

Re: Linking 2 tables on specific fields

Thanks everyone for your help and input. I'm still trying to understand how I can make this work.

So..... it appears that I will have to manipulate my CALLS data before I import it, to add a field which converts my "accountnumber" field into the id for the corresponding record in the CLIENTS table. Is this correct?

I don't understand what is meant by "foreign key".

I thought what I was trying to do would be really simple but it appears not to be the case.

I don't have a project to show yet as I'm just playing around to see how I can achieve what I want, which is to show a list of calls made by someone (the list is generated in another application) against their name. The list of calls contains the data "accountnumber", "date/time", "duration" and "cost". It does not contain any CLIENT details other than the account number. I've attached a csv file showing the data which will need to be imported and linked to each client. For example, when you look at the data in the csv file I am accountnumber 100.

The more I think about this the more I get confused!

Post's attachments

Attachment icon MVD Test.csv 8.21 kb, 497 downloads since 2016-12-01 

Re: Linking 2 tables on specific fields

Knobby, You do not need to manipulate your calls.csv file before importing. Download and run the attached project and use your MVD Test.csv file as the import file. No changes were made to your file. I did have to change the script slightly to accommodate your file, ie. skip the first line of your csv file because it was a heading line. I also had an error in the import counting. Once you do the import, click on each row of in the Clients tablegrid and you will see the calls for that selected client in the Calls tablegrid.

The Calls table does not need the accountnumber stored in there. However I used the accountnumber from the Calls.csv to lookup the accountnumber in the Clients table to retireve the primary key (Id) and insert that key into the Calls table (id_Clients) so you have a relationship between Clients and Calls. You do not define relationships in MVD based on user fields. Child tables store the related parent primary key (Id) rather than another parent field such as accountnumber in your case. I hope I didn't confuse you more.

Post's attachments

Attachment icon clients_calls (3).zip 589.96 kb, 441 downloads since 2016-12-02 

Re: Linking 2 tables on specific fields

Thanks again for your help. Unfortunately I cannot import any data - I get and error which says "07/31/2016 20:18:26 is not a valid date and time".

But it looks like you have added the account number to the calls records via this script. Is this correct? If so, and I have to do this level of scripting to accomplish the simple task of linking two tables together then I think that MVD is much too complicated for me.

This was to be a simple little starter project to get me used to MVD before I attempted something more complicated like a sales/stock control system. This would need tables to be linked together via multiple ways and fields. Very simple to achieve using Alpha 5, but appears nigh on impossible for a relative beginner like me using MVD.

Re: Linking 2 tables on specific fields

Hello Knobby, EHW,
Just to try and help clarify things. 
The script that has been written is SOLELY to load data from a .csv file.  It has NOTHING to do with creating any relationship between tables.  That is done when you define your data tables.  All you need to do is to indicate you want a relationship between two tables and MVD does it for you automatically using internally generated IDs;  it is a far simpler, easier and more rigorous approach than many of the other relational database products.
The script that uploads the .csv data does not add the account number to the calls records.  The script matches the account number from the .csv file to the account number on the CLIENTS table to obtain the relevant record id (the primary key) and then uses that record id as the foreign key on the CALLS table - that is how the relationship between the two tables is maintained.  The screen capture (calls.jpg) in the attachment shows the raw data as it is held in the two tables and may help you see how it all hangs together.
If you look at the attachment, this is pretty much how your application would be if you were entering the calls manually and as you can see, everything is done without scripts.
Hope this helps,
Derek.

Post's attachments

Attachment icon knobby.zip 711.31 kb, 438 downloads since 2016-12-03 

Re: Linking 2 tables on specific fields

I was about to reply to try to clarify things when I noticed Derek already did. I couldn't have said it any better. Thank you Derek. If I may add more info for Knobby. This may not be evident in the beginning for folks first learning MVD, but whenever you create a table in MVD, an auto increment unique primary key called "Id" is defined for you automatically in each table behind the scenes. If you have a parent-child relationship (linking 2 tables in your terminology), all you have to do in the child table (Calls in your case) is to define a relationship field and select the parent table (Clients in your case). MVD, as Derek mentioned, will define the relationship automatically for you. This is the Foreign Key. The field name is defined automatically for you as "id_parenttable" ("id_Clients" in your case).

If you go into the Database tab in either my project or Derek's project and click on the Database Schema button next to the New Table button, you will be presented with the Database schema which will show the primary keys "Id" in each table and the relationship between the Clients table and the Calls table. It really is an easy process in MVD and much simpler than with Alpha where you have to define and create "Sets" to do the same thing. As I mentioned before I am familiar with Alpha and even though you can set the relationships on other user fields, I never did or do. I always created the parent-child relationship sets using ID key fields, much like MVD does automatically. It's just good database design to do so.

Just to reiterate what Derek said, the only purpose for the script in my project was to populate the Calls table from the CSV file. Again, you do not need to manipulate your CSV file to import into MVD. Derek's example is a good one to show the relationships (linking of tables) without the confusion of the import script which obviously threw you off a bit. I apologize for that confusion and I surely hope I haven't confused you more.

Re: Linking 2 tables on specific fields

Thanks you all again for taking the time to try and help me with this - it's very much appreciated, and I apologise for being a bit dumb! In my defence it's 15 years since I did any database development so I'm very rusty.

I now understand the parent - child relationship in MVD and how it automatically creates a foreign key in the child table based upon the id field in the parent (Derek, your picture really helped).

However (and this is where I think I am going to be a bit dumb again), I can't see how I can accomplish my goal of linking calls to clients using this relationship method. Let me try and explain why.

My CLIENT table would have the following fields:

id
accountnumber
name
address

My CALLS table would have the following fields:
id
id_client
accountnumber
date
duration
cost

When you import (not directly enter) the data into the CALLS table there is no way of associating the calls data to a particular client unless you can tell it that accountnumber 100 = id_client 1, accountnumber 101 = id_client 2, etc.  So lines of data imported into the CALLS table would look something like:

id: 1
id_client:
accountnumber: 100
date: 20/11/2016
duration: 5
cost: 1.22

id: 2
id_client:
accountnumber: 107
date: 30/11/2016
duration: 12
cost: 2.75

id: 3
id_client:
accountnumber: 104
date: 21/11/2016
duration:1 5
cost: 4.36

The field id_client could not be populated as the data does not exist in the imported csv file, and I can't see how MVD could add this without being told (somewhere, somehow) that accountnumber 100 = id_client 1, accountnumber 101 = id_client 2, etc.

This is where I'm getting lost!

Re: Linking 2 tables on specific fields

Don't ever feel dumb. We've all been there and this forum is here to help each other. I'm still learning things with it myself. I'm glad you are understanding how parent-child relationships are done in MVD. As far as the CSV file import, what you described as to the process is exactly what the script I provided does. Download the attached project. It's the same as before except I commented all the relevant lines so you can see how the Id from the Clients table (parent) is loaded into the id_Clients field of the Calls table (child). The Calls table does not need the account number defined in it because the relationship is in place with the Id fields. Duplication of the account number is not necessary. The account number only needs to be defined in the Clients table.

Just so you understand generally the import process. Each line of the CSV file is read and loaded into variables. The account number in the CSV file is used to do a lookup into the Clients table and retrieve the Id field.  Script  - SqlExecute('Select Id From Clients where accountnumber = accountnumber from the CSV file....') This Id field from the Clients table is then used in the SQLExecute('Insert.....' ) to place into the id_Clients field of the Calls table. The rest of the variables are loaded into the Calls table with the same Sql Insert. Take a look at the commented script in the attached project and see if it makes more sense now. Hope It does.

Post's attachments

Attachment icon clients_calls Knobby.zip 590.97 kb, 469 downloads since 2016-12-03