Delphi DBEdit OnExit primary key validation - database

I am using Delphi 10.4, when connecting a DBEdit to a table from a database which contains a primary key (eg: student_num). What I want to do is to perform a search on the key the user types in that DBEdit when the user exits or moves to the next DBEdit and not after filling all the fields then hitting a submit button.
Can someone help me with that?
Much gratitude.
I used DBEditChange, but that didn't work as expected. The code I'm trying to write should show a message in case the entered key already exists in the database, immediately after exiting DBEdit field.

Related

Access form not working after migrating backend from Access to SQL Server [duplicate]

Currently, I am trying to move from an Access backend to a SQL backend for my database while still keeping the Access form as the frontend. This is done via linked tables with ODBC connections to my backend. The form is designed to add new records to the table. The problem is with AutoNumber. The ID was set as an AutoNumber and the form would simply display (New) while waiting for the user to add the remaining columns. I have set up my SQL data with the IDENTITY property, so it will increment once a new record is created. However, I cannot get the form to behave the same way as it did because, even though the backend will automatically add the next sequential ID, I cannot automatically fill that data into the form prior to a user actually saving the form data. Is there a way maintain the form functionality that AutoNumber provides?
TL;DR: Form is not working correctly after AutoNumber is changed to Number.
Well, there are "rare" cases in which you actually need the autonumberr before you save the record. For example, if you have a sub-form, then Access ALWAYS does a automatic save of the main record, and thus the autonumber is and will have been created .So a main form, and sub form (child table) will work fine, and do so without code.
Now, there are some cases in which you need the autonumber. Say you have some "code" that needs to run and spit out some child records.
The general approach is to simply execute a record save at that point in time.
So, say there is a button, or some code you need to run in the form, and you NEED the PK autonumber?
You can use this code:
If isnull(me!ID) = true then
me.dirty = false ' force record save - autonumber now created
end if
the record for above to work will have to be "dirty", but in near all cases, this tends to be the case. The "rare" exceptions would suggest that you could check me.IsNewRecord, but in most cases the above bit of code will suffice.
I can't really imagine that the "display" of some autonumber is oh so important WHEN the user is starting to enter data.
However, if you want the autonumber to appear after ANY keypress (data entry on the form)?
Simply put this line of code in the after insert event:
me.dirty = false
So, now when looking at a form, the FIRST key press by the user in any text box will force the autonumber to be generated and appear. However, it is a VERY bad practice to assign any meaning of the autonumber ID to the end users. In fact that ID should in most cases be hidden.
the only issue or downside of above is of course that if you have any required columns, then the above may error out or case an issue.
Solution
For this problem, I needed to set my identity_insert to ON in the SQL backend. Here is the code to do so:
SET IDENTITY_INSERT tableName ON;
Also, if you get the error: Table <Table Name> does not have the identity property. recreate the table with the autoincrementing column having an identity.
Example:
CREATE TABLE new_employees (id_num int IDENTITY(1,1), fname varchar (20), minit char(1), lname varchar(30));
More on IDENTITY in Microsoft offical documentation: here

MS Access <> SQL Server : save current record which creates GUID in SQL and go back to this record

The title is maybe not the best. My current setting: MS Access frontend with a SQL Server backend.
The SQL Server backend will create the PK with a GUID as soon the row is saved.
I need to save my record and go back to that record to use the created PK GUID.
When I do a Me.Refresh or Me.Requery, it will loose the connection to the record showing #Name? on all fields.
I need to get to GUID because I want to upload a file which is done in a FILESTREAM table and the link to the content table is done via the GUID of the content table.
So I need the content table GUID but as the record is not yet saved, I don't have one.
How to save the record, get its GUID and "stay" on that record?
I tried following which is not working:
DoCmd.RunCommand acCmdSaveRecord 'Here it will show '#Name? on all fields
Me.Refresh
Use Me.Requery instead of Me.Refresh and hope you stay on the same record. You can, of course, navigate to the last record, which opens a small door for race conditions (someone could in theory insert a record between you saving yours and you requerying).
Access does strange things to add records and then fetch the default data, as can be read here. It doesn't play well with GUID columns (or, really, anything that isn't a numeric identity primary key column without triggers). By forcing a requery you refetch all data.
Alternatively, you can bind the form to an ADO recordset and work with that, but that approach has some problems on its own, such as trouble with the built-in refresh/filter/sort options.

Inserting data in Many-to-Many relationship (intermediate table) via MS Access linked to SQL server database

I have a contact database, created on SQL server. An example of its many to many relationships is below:
1- Contact table (ContactID, Fname, Lname, ...)
2-Contact_Skill table (ContactID, SkillID, Score)
3-Skill table (SkillID, Skill_name, Skill_type)
For easier interaction, I linked this databse with MS access file (which will be the interface, used by users). Users mainly use it for insertion, and I have somewhere else a SQL report server to retrieve some data and do some reports.
My issue now is that, I'm trying to find an easier way (without programming) to insert data in the intermediate table (Contact_Skill), other than getting the IDs manually. A thing like a drop down menu, that enables the user to choose the skill and it turns into its ID. Any easier way would be so welcomed as well. Thanks
Ok, you likely don't need code, or at the very least VERY little code, and you certainly don't have to write code to insert the records.
So, I would create the form (bound directly to the linked contact table.
So, you can use ctrl-f, or whatever to search, find, jump to your record you want to edit. (so built in search features will suffice for now).
In that form, you will drop in a sub form. (a continues form - multiple items would work nice here.
So, in that form you have this:
In this example, I have
customers
Invoices
Invoice details
So, really, I have near example the same kind of setup. One master table (customers)
Then a child table of invoices.
And then for each invoice, we have details of the invoice.
So, your main form will have that sub form dropped in that shows the contact skills.
In my case, I have this:
So, for this, you not really written any code.
Now, do note that for each invoice (or your case of contact skills).
Note how I have a edit button in that continues form.
This allows our "drill" down.
The code behind this button is:
if me.Dirty = true, then me.Dirty = False
docmd.OpenForm "frmInvoice",,,"ID = " & me!id
So, clicking on edit will launch a new "main" form based on invoice (or in your case skills) the ONE record.
Now for that skills record, it not clear if you have another drill down (child table), but lets assume you do!
so, In that form, you simply drop in another sub form (again continues items), and you thus are now free to add more skills to that one contact skill.
In my case, it is invoice details, so we have this:
The above screens are rather crude (they are test scenes), but it shows a design in which you dealing with 3 typical related tables.
So the whole system works with about 6 lines of code. Just keep in mind that when you drop in a sub form to relate child items? Access will setup the foreign key value that belongs to the parent table that has the one "main" record, and that sub-form of child records. All that is required is that the link master/child setting is setup correct. Once done, then Access will manage and set the correct values used to relate the tables to each other, and you don't have to write any SQL or even any code for that matter. (you are free to add a sub form record, and then hit Edit button for further details to edit, or as noted add more child records to that form you just launched.
So related tables, and adding of child records is VERY automatic in Access, and you don't write code to add the records - access will do all this work for you if you follow the above design pattern. About the only code you ever had to add is the the "edit" button to launch the next form in the sequence.

Change appengine ndb key

I have a game where I've (foolishly) made the db key equal to the users login email. I did this several years ago so I've got quite a few users now. Some users have asked to change their email login for my game. Is there a simple way to change the key? As far as I can tell I'd need to make a new entry with the new email and copy all the data across, then delete the old db entry. This is the user model but then I've got other models, like one for each game they are involved in, that store the user key so I'd have to loop though all of them as well and swap out for the new key.
Before I embark on this I wanted to see if anyone else had a better plan. There could be several models storing that old user key so I'm also worried about the process timing out.
It does keep it efficient to pull a db entry as I know the key from their email without doing a search, but it's pretty inflexible in hindsight
This is actually why you don't use a user's email as their key. Use ndb's default randomly generated key ids.
The efficiency you're referring is not having to query the user's email to retrieve the user id. But that only happens once on user login or from your admin screens when looking at someones account.
You should rip the bandade off now and do a schema-migration away from this model.
Create a new user model (i.e. UsersV2) and clone your existing user model into it to generate new ids.
On all models that reference it add a duplicate field user_v2 = ndb.KeyProperty(UsersV2) and populate it with the new key.
Delete the legacy user model
You should use the taskqueue to do something like this and then you won't have to worry about the process timing out:
https://cloud.google.com/appengine/articles/update_schema
Alternatively, if you are determined to do this cascading update everytime a user changes an email, you could set up a similar update_schema task for just that user.
I ended up adding a new property to my user model and running a crawler to copy the string key (the email) to that new property. I changed my code search for that property rather then the key string to get a user item. Most of my users still have keys that equal their email, but I can safely ignore them as if the string is meaningless. I can now change a users email easily without making a new recored and my other models that have pointers to these user keys can remain unchanged.

CakePHP Insert Statements

I am having trouble inserting data into a MySQL table using CakePHP. I am making a table that once a row is inserted, it should not be able to be overwritten. With the save method of CakePHP, if I try to enter something with the same primary key but different information, it will just update that entry instead of returning an error. I tried to unset the id for the model and also tried to do Model->create() before the call, but it still just overwrites the data.
Additionally, I have been trying to use the Model->query() method instead, but I cannot get it to properly check for errors. I want it to insert, but return an error message if the ID is already taken, so I tried this.
$insertQuery = ("INSERT INTO `students` VALUES ('{$id}', '{$lastname}', '{$firstname}', '')");
$this->Student->query($insertQuery) or die("error" .mysql_error());
However, the query command returns an array and not a truth value, so this will call die every time. I would appreciate any advice someone can give.
Your table should have only the Id as the primary key and it should be IDENTITY.
In CakePHP if you dont specify the Id in the form you create to submit your data it will create another record, even with the same values.
But you should revise your model to be sure that the id is not required or something like that.

Resources