Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Uniq ID number for fields in table in single and network
Message
From
06/11/2001 03:39:32
Cetin Basoz
Engineerica Inc.
Izmir, Turkey
 
 
To
06/11/2001 02:35:05
General information
Forum:
Visual FoxPro
Category:
Coding, syntax & commands
Miscellaneous
Thread ID:
00577811
Message ID:
00577817
Views:
29
>Hi to all,
>
>I have one free table which has one field with value which should automatic rise up from 1 to endless (999999) like uniq identifier of each records (like Autonumber in Access) and in order to solve this I put this code in Valid Events of cmdAdd commandbutton (from buttonset1 group):
>LOCAL br
>if this.parent.addmode=.f. then
>wait wind 'Saved...' at 20,10 nowait
>DIMENSION maks(1)
> IF RECCOUNT()=1 then && was just 1
> br=1
> ELSE
> SELE MAX(n_rok) FROM nrok INTO ARRAY maks
> br=maks+1
> ENDIF
>repla nrok.n_rok with br
>=tableupdate(.t.)
>endif
>
>if this.parent.addmode=.t. then
>wait wind 'In mod for input' at 20,10 nowait
>endif
>thisform.refresh
>*------
>I have fear that in multiuser environment could happen that both user get same value for their new records or that could be duplicate possible.
>Is there any better and for sure solution?
>Thanks in advance
>Elvir

Elvir,
In solution.app there is a sample (not sure of name NewId or NextId). Here is my modified version using that approach :

* Every PK field in DBC has NewId(<UniqueTableName>) as default value
* NewId is a stored procedure
* There is an ids table to store id numbers
* Ids table structure (TableName c(30), CurId i)
* There is an index on upper(tablename)
FUNCTION NewID
	LPARAMETERS tcTableName
	LOCAL lcTableName, lnOldArea, lcOldReprocess
	lnOldArea = SELECT()
	lnOldReprocess = SET('REPROCESS')
	* Uppercase Alias name
	lcTableName = upper(iif(parameters() = 0, alias(), tcTableName))
	* Lock reprocess - try once
	SET REPROCESS TO 1
	IF !USED("IDS")
		USE ids IN 0
	ENDIF
	* If no entry yet create and return 1
	IF !SEEK(lcTableName, "Ids", "tablename")
		INSERT into ids (TableName, CurId) values (lcTableName,1)
		SELECT (lnOldArea)
		SET REPROCESS TO lnOldReprocess
		RETURN ids.CurId
	ENDIF
	* Lock, increment id, unlock, return CurId value
	DO while !RLOCK('ids')
		* Delay before next lock trial
		lnStart = seconds()
		DO while seconds()-lnStart < 0.01
		ENDDO
	ENDDO
	* Increment
	REPLACE ids.CurId WITH ids.CurId + 1 in 'ids'
	UNLOCK in 'ids'
	SELECT (lnOldArea)
	SET REPROCESS TO lnOldReprocess
	RETURN ids.CurId
ENDFUNC
PS: If you download FoxyClasses samples (link from signature) then in data directory check importtest.dbc. It has this exact function with most of the tables using in their default value.
Also check Craig Benson's web site (don't know the address but you could find following a message from him). There is an id generator routine there too AFAIK.
Cetin
Çetin Basöz

The way to Go
Flutter - For mobile, web and desktop.
World's most advanced open source relational database.
.Net for foxheads - Blog (main)
FoxSharp - Blog (mirror)
Welcome to FoxyClasses

LinqPad - C#,VB,F#,SQL,eSQL ... scratchpad
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform