Using IBM i? Need to create Excel, CSV, HTML, JSON, PDF, SPOOL reports? Learn more about the fastest and least expensive tool for the job: SQL iQuery.
D GENUUID PR extProc('_GENUUID')
D rtnUUID LikeDS(UUID_T)
D UUID_T DS Qualified
D bytesProv 10U 0 Inz(%size(UUID_T))
D bytesAvail 10U 0 Inz(0)
D reserved 8A Inz(*ALLX'00')
D UUID 16A
D myUUID DS LikeDS(UUID_T) Inz(*LIKEDS)
/free
getUUID( myUUID);
theUniqueValue = myUUID.uuid;
The 16-byte value is returned in the UUID subfield of th data structure and is always unique
Do you want an SQL or RPG solution? And give some examples of the strings you want generated.
Chris Ringer
A 7 character alpha numeric value. Which should not be repeated.
Thanks for not answering my 1st question...
One technique is to treat the 7A value as a base36 number. Convert the base36 7A value to a 64-bit integer (20I 0), add 1, then convert back to base36. I haven't had a need for this, so I don't have a working example for you, but they're easy enough to find. Search for "convert base36 to base10 rpgle" (or without the rpgle, if you like).
There was a recent article here: TechTip: Compacting a Large Number into a Small Space | RPG. It has routines (see the link for the .zip with the code) that do the conversion to and from base36. (I haven't looked at their code.)
One caution - you may not want to use their code out of the box. In base36, the sequence is 0..9A..Z, which is standard symbols for bases greater than 10. (An example closer to home would be base16, which is 0..9A..F.) If you use this code directly, your sequencing would be '0000001', ..., '0000009', '000000A', ..., '000000Z', '0000010', and so on. That is, in each base36 digit, 9 + 1 = A, and Z + 1 = 0 with a carry to the next higher digit. If you want your digits to increment from Z + 1 = 0, and 9 + 1 = A with carry, you just need to change the base36 "alphabet".
In any case, overflow occurrs at 36**8-1. With standard base36 alphabet, 'ZZZZZZZ' + 1 = '10000000', which is 8 digits. With alternate alphabet, A-Z0,9, max value would be '9999999' + 1 = 'BAAAAAAA'. Either way you'll want to check for the max value before you convert.
I wrote this many years ago. It's not free form but works fine. You would need to single thread it yourself and save the last value, which could both be done with a data area.
Chris Ringer
H ActGrp( *Caller )
H DftActGrp( *No )
H DatEdit( *ymd )
H DatFmt( *Iso )
H ExprOpts( *ResDecPos )
H ExtBinInt( *Yes )
H Indent( '|' )
H Option( *NoDebugIO : *SrcStmt )
H UsrPrf( *Owner )
*
F*--------------------------------------------------------------*
F*
F* ‚Program Name.....: UT123 (Increment a String)
F*
F* ‚De!--script--ive Name.: Will increment the incoming string by '1'.
F*
F* ‚Function.........: Will increment the incoming string depending
F* on the conversion table parameter.
F*
F* ‚Examples:........: Using Table "1" (A-Z 0-9)
F* > From: ABC123 To: ABC124
F* > From: AD9 To: AEA
F* > From: 999 To: AAAA
F* ‚ Using Table "2" (0-9 A-Z)
F* > From: ABC123 To: ABC124
F* > From: AD9 To: ADA
F* > From: 99Z To: 9A0
F* ‚Using Table "3" (A-Z)
F* > From: ABCDEF To: ABCDEG
F* > From: XRZ To: XSA
F* > From: ZZZ To: AAAA
F*
F* ‚Parameters.......:
F* a. Program Status: "1" = Use conversion table 1 (A..Z, 0..9)
F* Table 1 is the default.
F* "2" = Use conversion table 2 (0..9, A..Z)
F* "3" = Use conversion table 3 (A..Z)
F* b. "In" String : The string to convert.
F* Will be converted to upper case first!
F* c. "Out" String : The converted string, left justified.
F*
F*--------------------------------------------------------------*
F*
F* Modifications
F*
F* Date Mod# Who De!--script--ion
F* -------- ---- ---- ----------------------------------------
F*
D*--------------------------------------------------------------*
D* Work Field Definitions
D*--------------------------------------------------------------*
D W1Table1 c Const('ABCDEFGHIJKLMNOPQR+
D STUVWXYZ0123456789')
D W1Table2 c Const('0123456789ABCDEFGH+
D IJKLMNOPQRSTUVWXYZ')
D W1Table3 c Const('ABCDEFGHIJKLMNOPQR+
D STUVWXYZ')
*
D W1Lc c Const('abcdefghijklmnopqr+
D stuvwxyz')
D W1Uc c Const('ABCDEFGHIJKLMNOPQR+
D STUVWXYZ')
*
D W1VaryStr s 10a Varying
D W1Str s Like( PrmInStr )
D W1Pos s 3p 0
D W1Scan s Like( W1Pos )
D W1Char s 1a
D W1Min s 1a
D W1Max s 1a
D Done s Like( *inlr )
D W1Tbl s Like( PrmPgmSts )
*
D PrmPgmSts s 10a
D PrmInStr s 10a
D PrmOutStr s Like( PrmInStr )
*
C*--------------------------------------------------------------*
C* Parameters
C*--------------------------------------------------------------*
C *Entry Plist
C Parm PrmPgmSts
C Parm PrmInStr
C Parm PrmOutStr
*
C*--------------------------------------------------------------*
C* Mainline
C*--------------------------------------------------------------*
*..shutdown?
C If ( %Parms < 3 )
C Eval *Inlr = *On
C Return
C EndIf
*..set table
C If ( PrmPgmSts = '1' or
C PrmPgmSts = '2' or
C PrmPgmSts = '3' )
C Eval W1Tbl = PrmPgmSts
C Else
C Eval W1Tbl = '1'
C Endif
*
C Exsr $Odometer
C Eval PrmOutStr = %Trim(W1Str)
C Eval *Inlr = *On
C Return
C*--------------------------------------------------------------*
C* Control the incrementing of the string
C*--------------------------------------------------------------*
C $Odometer BegSr
*
*..right justify
C Eval W1VaryStr = %trim(PrmInStr)
C Move(p) W1VaryStr W1Str
C Eval W1Pos = %Len(PrmInStr)
*..min/max values
C Select
C When ( W1Tbl = '1' )
C Movel W1Table1 W1Min
C Move W1Table1 W1Max
C When ( W1Tbl = '2' )
C Movel W1Table2 W1Min
C Move W1Table2 W1Max
C When ( W1Tbl = '3' )
C Movel W1Table3 W1Min
C Move W1Table3 W1Max
C Endsl
*
*..convert to uppercase
C W1Lc:W1Uc Xlate W1Str W1Str
*
C Dow ( Done = *Off )
C Eval W1Char = %subst(W1Str:W1Pos:1)
*
C Select
C When ( W1Tbl = '1' )
C Eval W1Scan = %scan(W1Char:W1Table1)
C When ( W1Tbl = '2' )
C Eval W1Scan = %scan(W1Char:W1Table2)
C When ( W1Tbl = '3' )
C Eval W1Scan = %scan(W1Char:W1Table3)
C Endsl
*
C Exsr $IncChar
C Enddo
*
C EndSr
C*--------------------------------------------------------------*
C* Increment Character - if blank, next char is W1Min value.
C*--------------------------------------------------------------*
C $IncChar BegSr
*
*..at max, rollover
C If ( W1Char = W1Max )
C Eval %subst(W1Str:W1Pos:1) = W1Min
C Eval W1Pos = W1Pos - 1
C Eval Done = *Off
C Else
*..not max
C Eval W1Scan = W1Scan + 1
*
C Select
C When ( W1Tbl = '1' )
C Eval %subst(W1Str:W1Pos:1) =
C %subst(W1Table1:W1Scan:1)
C When ( W1Tbl = '2' )
C Eval %subst(W1Str:W1Pos:1) =
C %subst(W1Table2:W1Scan:1)
C When ( W1Tbl = '3' )
C Eval %subst(W1Str:W1Pos:1) =
C %subst(W1Table3:W1Scan:1)
C Endsl
*
C Eval Done = *On
C Endif
*
C EndSr