This tip shows you how to prevent users from saving more than one document with the same key data.
Based on one or two fields in a document, I wanted to make sure that the user does not try to create/save more than one document with the same information in these fields.
In this example, there are two fields, "Yr" and "DataSet", and the pair must be unique among documents. I put the following validation formula behind the "DataSet" field.
The view "(By Yr-Dataset)" contains @Text(Yr)+"-"+DataSet for the first column and @Text(@DocumentUniqueID) for the second column.
IF ---- @IsError(rulefound), then a document with this combination of Yr and Dataset doesn't exist so it's OK. IF ---- @IsNewDoc & !@IsError(rulefound), THEN this is a new document and this combination of Yr and Dataset already exists, so generate an error: IF ---- !@IsNewDoc & !@IsError(rulefound) & ! (docid=@Text(@DocumentUniqueID)) Then this is an existing document which is being edited, AND a document already exists with this combination Yr and Dataset, AND, the docid for the current document does not match the doc ID of the found document, THEN this is an existing document which is being edited to match an existing document, so generate an error. The validation formula behind the last field makes up the key. key:=@Text(Yr)+"-"+DataSet; rulefound := @DbLookup("" : "NoCache"; "" : ""; "(By Yr-Dataset)"; key; 1); docid:= @DbLookup("" : "NoCache"; "" : ""; "(By Yr-Dataset)"; key; 2); @If( @IsError(rulefound);@Success; @IsNewDoc & !@IsError(rulefound); @Failure("Tape set for "+key+" already exists in database."); !@IsNewDoc & !@IsError(rulefound) & !(docid=@Text (@DocumentUniqueID));@Failure( "Tape set for "+key+" already exists in database."); @Success )
The code in itself is not bad in that it will prevent users from duplicating reference keys, but my preference would be to calculate the key for the user rather than let them select it. I personally would not like it if I had to try several combinations before I could save my document which would be increasingly likely as the application contained more documents.
When I use reference keys I normally calculate based on the current date and time and turn this into a string. If you add to the front of this the users first initial and first letter of their surname then it is virtually impossible to get a duplicate key in two different documents.
I see two problems with this way to ensure a unique identifier:
- When implementing it in Web the user will have to tip all the data again if the key is not unique.
- It won't work on clustered servers. While a user saves a document on server # 1, another user can save a document with the same key on server # 2, as often several seconds may occur until a document is replicated from one server to another.
Previous reviews of this tip may have missed the goal, or else I see another application where it is a good solution.
This solution DOES apply when you have a class of objects with a property that should not be duplicated, or "overlap." Certainly a unique ID fits this description, but there are others. Say you have a resource that is rented out by the day, or you are scheduling patients for a certain doctor/room by the hour, half-hour, whatever. It's not so much that you want the patients or timeslots to be unique, but that you don't want them to overlap, and that is a solution domain not addressed by unique ID's, but certainly addressed by this solution.
Second, regarding unique identifiers, there are two easy ways to get them. @Right (@Unique; "-") gives you a 6-position alphanumeric ID. I prefer to trim off the first four letters and "-" returned by @Unique, which are only unique to a user. This is nice, quick, convenient, and is generally guaranteed to be unique, especially if they are generated on the server (by an agent or Web-based app). If you don't like that one and you are working in LotusScript or Java, you can create a NotesDocument object and steal its Universal ID. It doesn't get much more unique than that. One of the commentators is absolutely correct that you don't (generally) want your ID's to be chosen by or based on the input of users.
Do you have comments on this tip? Let us know.
This tip was submitted to the SearchDomino.com tip exchange by member Tandy Wine. Please let others know how useful it is via the rating scale at the end of the tip. Do you have a useful Notes/Domino tip or code to share? Submit it to our monthly tip contest and you could win a prize and a spot in our Hall of Fame.