Introduction

The purpose of the command-line LinkRefCheck tool is to make sure that the value in the link reference tag of linked fields in a database points to an existing linked record, and that no value is stored in the linked field itself. It also empties any accidentally stored merged-in fields, because merged-in fields shouldn’t be stored in the database either.
If a correct link reference is present (pointing to an existing record in the linked database), and the linked field value itself and any merged-in field values do not appear in the stored record, then things are how they should be, so nothing is changed. Different erroneous situations for a linked field can in principle exist though, which will all be fixed by LinkRefCheck as follows:

A correct link reference is present (pointing to an existing record in the linked database), and the linked field tag itself appears in the stored record, either filled in or empty: LinkRefCheck will check if the local value in the tag matches the linked record, if not, LinkRefCheck reports the error. The linked field tag plus its value will always be removed, so the link reference remains.
No link reference is present but a value has been stored in the linked field itself: LinkRefCheck will check whether the value appears in the linked database. If it does, the record number will be copied to the link reference tag of the linked field, and the linked field tag plus value will be removed. If it doesn’t, a new linked record will be created and its record number will be copied to the linkref tag of the linked field, after which the linked field tag plus value will be removed.
If the indexed value appears in the linked database table multiple times, LinkRefCheck cannot select the proper linked record (it won’t check data in the records themselves) and it will generate a message stating that multiple terms were found. The linked field tag plus value won’t be removed, so you’ll have to make a proper link in the relevant record manually later on (and then run LinkRefCheck again).
When a record is forced into the linked database table, LinkRefCheck has no knowledge of datasets. In the Thesaurus there usually are no datasets, so no problem there, but in a database with datasets the new record would just get the highest, first available record number, regardless of the dataset containing that record number. In this case you would have to move (derive) records from one dataset to another manually later on, if records were forced into the wrong dataset, and maybe also edit automatically stored data like the material type.
Links on secondary, term (Text) indexed long text fields are problematic. For example, from the Collect database table to the Document database table in older model applications, there was such a link on the documentation.title field. In Document, the title field is primarily indexed as a word (Free text) index and secondarily as a term index on a dummy field. The link from Collect must use this secondary index. LinkRefCheck will also use this index to find out if a title stored in the linked field occurs in Document already (also when earlier forced by LinkRefCheck), but when it forces a new title record in Document, it cannot store the title in the proper title field because it doesn’t know the tag: it’ll store the title in the dummy field instead. This means the forced records will have an empty title field, so again, you’ll have to edit such forced records later on by hand to fix this. You’ll know which records were forced into the linked database because of the messages LinkRefCheck generates during the process.
The link reference points to a non-existing record in the linked database table, and the linked field tag itself has (correctly) not been stored in the record: LinkRefCheck reports the error and will remove the faulty link reference.
The link reference points to a non-existing record in the linked database table, and the linked field tag itself has a value: LinkRefCheck will first remove the erroneous link reference. Then it will check whether the linked field value appears in the linked database. If it does, the record number will be copied to the link reference tag of the linked field, and the linked field tag plus value will be removed. If it doesn’t, a new linked record will be created and its record number will be copied to the linkref tag of the linked field, after which the linked field tag plus value will be removed. LinkRefCheck will report the error.
For a reversely linked field in record A a correct link reference to a record B exists while for the associated reversely linked field in record B no link reference to record A exists: LinkRefCheck will add the missing record A link reference to the relevant link reference field in record B.
LinkRefCheck does not deal with inherited fields. Prior to version 1.10.1.1031, inheritance could lead to an error processing certain records, giving an Object reference not set to an instance of an object error.

 

Running LinkRefCheck

1.For safety reasons, create a backup of your Collections application and database, if you haven’t done that yet. It is also wise to try out LinkRefCheck in a test environment before applying it to a live database.
2.LinkRefCheck requires that all source and destination fields used as merged-in fields with a linked field (see the Linked field mapping properties tab of a linked field in the data dictionary (the database structure) in the Designer Application browser) have actual field definitions in the data dictionary, so it’s not enough to use undefined tags. Use the Designer Application tester tool on your application to find out if there are such undefined merge tags in your data dictionary. If so, you should look up each relevant mapping and decide if source and/or destination field definitions should be added to the data dictionary or whether to remove that mapping: if both source and destination tags have no field definition, you can remove that row from the relevant mapping; if only the target tag has no field definition, you should create one for it; if the target field definition exists while the source tag doesn’t, you should decide for your-self.
3.Copy the LinkRefCheck files to a temporary folder on the machine that also runs the SQL server. This will spare your local network the extra load. (The Collections \data folder doesn’t need to be on that same server though.)
4.To run LinkRefCheck as efficiently as possible, make a few settings for the database. Open the properties of your database in Microsoft SQL Server Management Studio (or a similar tool), set the Autogrowth size on the Files page to 100 MB, and on the Options page, set the Recovery model to Simple.
5.Only run LinkRefCheck after making sure that your indexes are correct, in other words: by using IndexCheck (or Adcopy) first.
6.LinkRefCheck can be controlled by command-line parameters. To provide command-line parameters, open a command line window – type cmd in the Windows Explorer address field and press Enter to open a command line window - and execute LinkRefCheck using the following syntax:

 

<(path to)linkrefcheck> <path_to_the_data_folder> [fix|check|createtables] [list_of_databases] [list_of_tags] [priref] [user_name] [log_file]

 

The data folder is mandatory and should point to the location where the .inf files are stored. Everything between [] is optional:

If you use the parameter check, then LinkRefCheck will only report errors and does nothing to fix them. If you use fix, LinkRefCheck both checks and fixes any errors. The createtables parameter checks if there are index definitions for which no matching SQL table exists yet and then creates those tables. The default value is check (or use an asterisk instead).
Use an asterisk to indicate the position of a parameter with a default value, if not all optional parameters must be used in the default setting. See the examples.
list_of_databases is a comma-separated list (use no spaces) of database structure files to check (names of .inf files without the extension). Not providing this list, or entering an asterisk, checks all database tables.
list_of_tags is a comma-separated list of field tags of linked fields to check. By default, LinkRefCheck checks all tags. Entering an asterisk at this position also checks all tags.
priref is either the number of a single record to check, a comma-separated list of prirefs to check (separate only by a comma and use no spaces) or a range of prirefs (provide the first and last priref in the range and separate them by a hyphen without spaces around it). The list and range options are available from LinkRefCheck version 1.10.1.1025. By default (without providing any prirefs), LinkRefCheck checks all records in the provided databases. Entering an asterisk at this position also checks all records.
user_name is an optional user name that must be written to the management details in records edited by LinkRefCheck, if you don’t want LinkRefCheck to use your own login name (the system user) for this purpose. Date and time of editing and the current database table name will also be written in the record. LinkRefCheck uses the standard field tags nm, dm, tm and vm to write to. If you built your database table yourself, and are using these tags for other purposes, then be aware that these tags can be overwritten by LinkRefCheck. Entering an asterisk means LinkRefCheck will use the system user name.

If you want reports of faulty link references to be written to a log file, then provide the name of that text file in log_file. The log file will always contain an overview comparable to the following:

LinkRefCheck started...Check, 5-11-2010 17:10:00
Running in folder ..\CMS.20102969\data
Starting linkref check for database address
Finished linkref check for database address, 17902 records checked, 0 updated.
Link ref check completed, 5-11-2010 18:32:33

The following messages may appear in the log file:

Message example

Meaning

Added missing reverse linkref 10128, link ref tag = ly in database address, record 4426

A missing reverse link was added.

Deleted link to non-existent record from record 127, field=BC, linkref=125, LinkRefTag=ly, Linked database=address

A link (the link reference tag) to a non-existing record was removed by LinkRefCheck. A possible cause for the error might have been that in the past, feedback links hadn’t been set, and records in the linked database had been removed when references to them in other database tables were still present.

Deleted merge data for record: 10985, Tag=BD, Occ=1, 'Data=London Historical Museum, LinkRef = 4296, LinkRefTag=lz, Linked database=address

A local (filled or empty) linked field was removed because the linked field itself should not appear in the record, only the link reference tag should.

Mismatch in record: 10277 between link reference and linked field; data is removed; reference is preserved, Occ=3, linkref=ly, value=16282, linked field=BC, 'data=Brandt, W.A.'

The contents of the linked field (which shouldn’t have been stored) does not match the contents of the field in the linked record referenced in the link reference field. The link has been repaired by deleting the linked field and keeping the link reference tag and its contents.

New domain forced in 'thesau', priref = 3037, domain = 'SU144'

A domain was added to a linked Thesaurus record.

Record forced in 'thesau', priref = 104296, key = 'Landscape'

A linked record has been forced into the Thesaurus.

Removed circular link 10080, link ref tag = ly from database address, record 10080

A link to the record itself (a circular link) was removed.

Resolved link for record: 10599, Tag=CH, Occ=1, "Data='van'", LinkRefTag=li, linkRef=21174, Linked database=thesau

A non-processed link was processed by means of the value in the linked field, so the link reference tag was filled after which the linked field was removed.

 

Examples:

linkrefcheck "..\Axiell\data" check "collect,document" * * "AIS" "logfiles\check2.log"

linkrefcheck "..\Axiell\data" fix * * * * "logfiles\fix3.log"

linkrefcheck "..\Axiell\data" fix collect * 2,4,100 * "logfiles\fix3.log"

linkrefcheck "..\Axiell\data" fix collect * 1-120 * "logfiles\fix3.log"

linkrefcheck "..\Axiell\data" check

 

Typical problems with link references

If many records have faulty link references (pointing to non-existing records), while feedback links are missing in the linked database, it is likely that someone removed authority records in the linked database without first cleaning up all the records referencing those authority records.
If many records contain stored values in the linked fields, while they do have an associated link reference tag (filled in or not), it is likely that someone changed the definition of a normal field into a linked field while data was present in the normal field.