Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
Assignment of primary keys
Message
De
09/02/2003 19:27:45
 
 
À
09/02/2003 09:44:55
Information générale
Forum:
Visual FoxPro
Catégorie:
Autre
Divers
Thread ID:
00751165
Message ID:
00751235
Vues:
19
Hi Jeffrey.

>Does anyone have a program or method that handles the assignment of primary keys for the many tables I have in my application.

Here's code I've used for years. Of course, since VFP 8 now supports auto-incrementing fields, I won't be using it anymore.

Doug
*==============================================================================
* Function:			NEXTID
* Purpose:			Get the next available value for the specified field
* Author:			Doug Hennig
* Copyright:		(c) 1995 Stonefield Systems Group Inc.
* Last Revision:	04/29/99
* Parameters:		tcAlias - the alias of the table of interest (optional:
*						if it wasn't specified, the current table is used)
*					tcField - the name of the field to assign (optional: if
*						it wasn't specified, the primary key is used)
* Returns:			the next available key value (either numeric or left-
*						justified string, depending on the field type), or a
*						null string if there was a problem
* Environment in:	the table of interest is open
*					the NEXTID table is either open or is available to be
*						opened
* Environment out:	if NEXTID was open, it is positioned to the appropriate
*						record for the field and table
*					if there was no record for the field and table in NEXTID,
*						one is created with a starting value of 1
*					the KEY field of the appropriate record in NEXTID is
*						incremented
*==============================================================================

lparameters tcAlias, ;
	tcField
local lcCurrTalk, ;
	lcCurrTalkWindow, ;
	lcAlias, ;
	luReturn ,;
	lcDatabase, ;
	lcField, ;
	lcCurrDBC, ;
	lcTable, ;
	lcTag, ;
	llUsed, ;
	lnCurrReprocess, ;
	liKey, ;
	lcMax, ;
	laID[1]

* Save the setting of TALK and turn it off.

if set('TALK') = 'ON'
	set talk off
	lcCurrTalk       = 'ON'
	lcCurrTalkWindow = set('TALK', 1)
else
	lcCurrTalk = 'OFF'
endif set('TALK') = 'ON'

* If the alias wasn't passed, use the currently selected table. Give an
* error and return if there is no table.

lcAlias = iif(vartype(tcAlias) <> 'C' or empty(tcAlias), alias(), ;
	upper(tcAlias))
assert not empty(lcAlias) ;
	message 'NEXTID: no table selected'

* Initialize the return value and get the database for the table.

luReturn   = 0
luReturn   = .NULL.
lcDatabase = iif(used(lcAlias), cursorgetprop('Database', lcAlias), '')
do case

* If the field was passed, use it.

	case vartype(tcField) = 'C' and not empty(tcField)
		lcField = upper(tcField)

* If the field wasn't passed and the table isn't in a database, we won't have
* a field.

	case empty(lcDatabase)
		lcField = ''

* If the field wasn't passed and we have a database, find the primary key for
* the table. If we can't or if it's a compound key, we won't have a field.

	otherwise
		lcCurrDBC = dbc()
		lcCurrDBC = iif(empty(lcCurrDBC), '', '"' + lcCurrDBC + '"')
		set database to (lcDatabase)
		lcTable = cursorgetprop('SourceName', lcAlias)
		lcTag   = dbgetprop(lcTable, 'Table', 'PrimaryKey')
		set database to &lcCurrDBC
		if empty(lcTag)
			lcField = ''
		else
			lcField = key(tagno(lcTag, '', lcAlias), lcAlias)
			if ',' $ lcField or '+' $ lcField
				lcField = ''
			endif ',' $ lcField ...
		endif empty(lcTag)
endcase

* Open the NEXTID table (if necessary).

llUsed = used('NEXTID')
if not llUsed
	use NEXTID again shared in 0
endif not llUsed

* Try to find a record for the field. If there isn't one, create it.

lnCurrReprocess = set('REPROCESS')
set reprocess to 10 seconds
if not seek(padr(lcAlias, len(NEXTID.TABLE)) + ;
	padr(lcField, len(NEXTID.FIELD)), 'NEXTID', 'NEXTID')
	if empty(lcField) or type(lcAlias + '.' + lcField) = 'U'
		liKey = 0
	else
		lcMax = iif(type(lcAlias + '.' + lcField) = 'C', ;
			'val(' + lcField + ')', lcField)
		select max(&lcMax) from (lcAlias) into array laID
		liKey = iif(_tally > 0, laID[1], 0)
	endif empty(lcField) ...
	insert into NEXTID (TABLE, FIELD, KEY) values (lcAlias, lcField, liKey)
endif not seek(padr(lcAlias, ...

* If we can lock the record, increment the KEY value (rolling over to 1 if
* necessary) and assign it to luReturn.

if rlock('NEXTID')
	liKey = iif(NEXTID.KEY >= 2^32/2 - 1, 1, NEXTID.KEY + 1)
	replace KEY with liKey in NEXTID
	luReturn = iif(type(lcAlias + '.' + lcField) = 'C', ltrim(str(liKey)), ;
		liKey)
	unlock in NEXTID
endif rlock('NEXTID')

* Cleanup and return.

if not llUsed
	use in NEXTID
endif not llUsed
set reprocess to lnCurrReprocess
if lcCurrTalk = 'ON'
	set talk &lcCurrTalkWindow
	set talk on
endif lcCurrTalk = 'ON'
return luReturn
Précédent
Répondre
Fil
Voir

Click here to load this message in the networking platform