SQLUSA
SQL 2008 GRAND SLAM
FREE TRIAL
CLICK HERE TO ORDER

SQL Server 2008 Best Practices
SQL Server 2005 Best Practices

How to generate a sequence?

Execute the following T-SQL scripts in Microsoft SQL Server Management Studio Query Editor to demonstrate sequence generation, stored procedure and user-defined function creation. The sproc and the functions use the CROSS JOIN operator to create a large number of combinations (Cartesian product). The sequence generation scripts can be used imbedded into other T-SQL code.

------------

-- SQL sequence generator script

------------

-- SQL recursive cte - Common Table Expression

-- SQL maxrecursion option - SQL integer sequence

WITH cteSequence ( SeqNo) as

(

      SELECT 1

      UNION ALL

      SELECT SeqNo + 1

      FROM cteSequence

      WHERE SeqNo < 1000000

)

SELECT TOP 100 * FROM cteSequence

OPTION ( MAXRECURSION 0)

GO

/* Partial results

 

SeqNo

1

2

3

4

5

6

7

*/

------------

-- SQL date sequence

WITH cteSequence ( SeqNo) as

(

      SELECT 0

      UNION ALL

      SELECT SeqNo + 1

      FROM cteSequence

      WHERE SeqNo < 100

)

SELECT [DATE]=DATEADD(day, SeqNo, '2012-01-01')

FROM cteSequence

OPTION ( MAXRECURSION 0)

GO

/* Partial results

 

DATE

2012-01-01 00:00:00.000

2012-01-02 00:00:00.000

2012-01-03 00:00:00.000

2012-01-04 00:00:00.000

*/

------------

------------

-- Sequence table for an application like Purchasing

------------

-- SQL Server sequence number (1, 2, 3, 4, ....) stored in a table for sharing

USE AdventureWorks2008;

GO

CREATE TABLE PurchaseOrderSequence (

  SeqID INT    IDENTITY ( 1 , 1 )    PRIMARY KEY )

GO

-- SQL insert default values

INSERT PurchaseOrderSequence  DEFAULT VALUES

 

SELECT * FROM   PurchaseOrderSequence

-- 1

INSERT PurchaseOrderSequence DEFAULT VALUES

INSERT PurchaseOrderSequence DEFAULT VALUES

INSERT PurchaseOrderSequence DEFAULT VALUES

INSERT PurchaseOrderSequence DEFAULT VALUES

INSERT PurchaseOrderSequence DEFAULT VALUES

INSERT PurchaseOrderSequence DEFAULT VALUES

INSERT PurchaseOrderSequence DEFAULT VALUES

INSERT PurchaseOrderSequence DEFAULT VALUES

INSERT PurchaseOrderSequence DEFAULT VALUES

INSERT PurchaseOrderSequence DEFAULT VALUES

SELECT MAX(SeqID) FROM PurchaseOrderSequence

-- 11

 

-- Cleanup

DROP TABLE PurchaseOrderSequence

GO
------------

 

-- SQL random sequence generator - range 1 : 9999

-- SQL cte - SQL newid() function

WITH cteSequence(SeqNo)

     AS (SELECT 1

         UNION ALL

         SELECT SeqNo + 1

         FROM   cteSequence

         WHERE  SeqNo < 10000)

SELECT   TOP 100 *

FROM     cteSequence

ORDER BY NEWID()

OPTION (MAXRECURSION 0)

GO

/* Partial results

 

SeqNo

116

8783

7169

292

6988

*/

------------

------------

-- SQL sequence generator stored procedure

-----------

use AdventureWorks;

go

 

create proc procSequence @Limit int

as

begin

select TOP (@Limit) ID = identity(int,1,1)

into #Seq

from sys.objects a

cross join sys.objects b

cross join sys.objects c

select * from #Seq

end

go

 

-- Number sequence of 100000

exec procSequence 100000

go

 

-- Checking generation upper limit

select ObjCount=COUNT(*),

       UpperLimit=POWER(COUNT(*),3)

from sys.objects

go

 

/*

ObjCount      UpperLimit

575           190,109,375

*/

 

-- Table-valued function sequence generator

create function fnSequence (@Limit int)

returns @Series table (SeqNo int)

as

begin

declare @Sequence table (SeqNo int identity(1,1), One int)

insert @Sequence (One)

select TOP (@Limit) 1

from sys.objects a

cross join sys.objects b

cross join sys.objects C

insert @Series select SeqNo from @Sequence

return

end

go

 

-- Number sequence of 1000

select * from fnSequence(1000) order by SeqNo

go

 

-- Date sequence of 100

select [Date]=DATEADD(day, SeqNo, getdate())

from fnSequence(100)

order by [Date]

go

 

-- Series up to 1000 with table-valued function

create function fnSeries (@Limit int)

returns @Series table (SeqNo int)

as

begin

declare @Digit table (Digit tinyint)

insert @digit values (0); insert @digit values (1);

insert @digit values (2); insert @digit values (3);

insert @digit values (4); insert @digit values (5);

insert @digit values (6); insert @digit values (7);

insert @digit values (8); insert @digit values (9);

insert @Series

select TOP (@Limit)

        [Number]=hundreds.Digit * 100 + tens.Digit * 10 + ones.Digit + 1

from @Digit ones

cross join @Digit tens

cross join @Digit hundreds

order by  [Number]

return

end

go

 

-- Squares of the first 99 numbers

select [Number]=SeqNo, [Square]=SeqNo*SeqNo

from fnSeries(99) order by SeqNo

go

------------

-- SQL sequence in a table column

------------

USE tempdb;

GO

CREATE TABLE ShortProductInfo (

ProductID int,

ProductName varchar(50),

ListPrice money,

Color varchar(16),

Sequence int identity(500, 2)

)

GO

 

INSERT ShortProductInfo ( ProductID, ProductName, ListPrice, Color)

SELECT ProductID, Name, ListPrice, Color

FROM AdventureWorks.Production.Product

WHERE Color is not null

GO

 

SELECT * FROM ShortProductInfo ORDER BY Sequence

GO

 

/* Partial results

 

ProductID   ProductName       ListPrice   Color       Sequence

317         LL Crankarm       0.00        Black       500

318         ML Crankarm       0.00        Black       502

319         HL Crankarm       0.00        Black       504

320         Chainring Bolts   0.00        Silver      506

321         Chainring Nut     0.00        Silver      508

322         Chainring         0.00        Black       510

*/
------------

------------

-- SQL sequence with permanent table

------------

-- SQL create table to "remember" the sequence position

USE AdventureWorks;

GO

CREATE TABLE POSequence (

      PONumber int identity(1,1) primary key

)

GO

 

-- SQL create procedure to get the next sequenctial value

CREATE PROCEDURE sprocGetNewPONumber

AS

BEGIN

SET NOCOUNT ON

      DECLARE @NextPO int

      INSERT POSequence DEFAULT VALUES

      SELECT @NextPO = SCOPE_IDENTITY()

      DELETE POSequence

RETURN @NextPO

END

GO

 

-- SQL next sequential number

DECLARE @PO int

EXEC @PO=sprocGetNewPONumber

SELECT @PO

GO 10

 

/* Results

1

2

3

4

5

6

7

8

9

10

*/

-- Cleanup

DROP TABLE POSequence

GO

------------

-- SQL sequence generation with table variable

-- SQL insert default values method

DECLARE @Sequence table (Sequence int identity(1,1))

DECLARE @i int = 0

WHILE ( @i < 500)

BEGIN

      INSERT @Sequence DEFAULT VALUES

      SET @i += 1

END

SELECT * FROM @Sequence

GO

/* Partial result

 

Sequence

1

2

3

4

5

6

7

8

*/

 

-- SQL GUID generate sequence

USE tempdb;

GO

CREATE TABLE testGUID (RowGUID uniqueidentifier DEFAULT NEWSEQUENTIALID())

GO

-- SQL generate 100 sequential GUID values

-- SQL insert default values

INSERT INTO testGUID DEFAULT VALUES

GO 100

 

SELECT *

FROM testGUID

GO

/* Partial results

 

RowGUID

A810B32A-66D8-DD11-8AF3-0013723AB734

A910B32A-66D8-DD11-8AF3-0013723AB734

AA10B32A-66D8-DD11-8AF3-0013723AB734

AB10B32A-66D8-DD11-8AF3-0013723AB734

AC10B32A-66D8-DD11-8AF3-0013723AB734

AD10B32A-66D8-DD11-8AF3-0013723AB734

*/

DROP TABLE testGUID

GO

 

------------

-- T-SQL make ID sequential - remap random ID to identity

------------

-- SQL remap ID to sequential ID

-- Change non-sequential ID to sequential number

USE tempdb;

SELECT *

INTO   SOD

FROM   AdventureWorks.Sales.SalesOrderDetail

GO

 

SELECT   TOP 5 *

FROM     SOD

ORDER BY SalesOrderID,

         SalesOrderDetailID

/* Partial results

 

SalesOrderID      SalesOrderDetailID

43659 1

43659 2

43659 3

43659 4

43659 5

 

 

*/

 

-- SQL generate identity sequence with mapping to ID with gaps
-- SQL identity gaps - set identity_insert sql - Gaps in SQL Server identity columns

;WITH cteDistinctSO AS

(

      SELECT DISTINCT SalesOrderID FROM SOD

)

SELECT [NewID]=Identity(int,1,1), SalesOrderID

INTO SequentialIDMapping

FROM cteDistinctSO

ORDER BY SalesOrderID ASC

GO

 

SELECT TOP 5 * FROM SequentialIDMapping

ORDER BY SalesOrderID

GO

/*

NewID SalesOrderID

1     43659

2     43660

3     43661

4     43662

5     43663

*/

 

 

UPDATE s

SET    s.SalesOrderID = i.[NewID]

FROM   SOD s

       INNER JOIN SequentialIDMapping i

         ON s.SalesOrderID = i.SalesOrderID

GO

 

SELECT   TOP 100 *

FROM     SOD

ORDER BY SalesOrderID,

         SalesOrderDetailID

GO

/* Partial results

 

SalesOrderID SalesOrderDetailID

SalesOrderID      SalesOrderDetailID

3     17

3     18

3     19

3     20

3     21

3     22

3     23

3     24

3     25

3     26

3     27

3     28

3     29

4     30

4     31

4     32

4     33

4     34

4     35

4     36

4     37

4     38

4     39

4     40

4     41

4     42

4     43

4     44

4     45

4     46

4     47

4     48

4     49

4     50

4     51

5     52

6     53

6     54

6     55

6     56

6     57

6     58

6     59

6     60

7     61

7     62

7     63

7     64

7     65

7     66

7     67

7     68

7     69

7     70

 

*/

 

-- Cleanup

DROP TABLE SOD

DROP TABLE SequentialIDMapping

GO

------------

 

The World Leader in SQL Server 2008 Training
The future is just a CLICK away. Your future!
 
SQLUSA.com Home Page

Copyright 2005-2010, SMI Corp. All Rights Reserved.

SQL Server 2008 is a program product of Microsoft Corporation.
SQL Server 2005 is a program product of Microsoft Corporation.
SQL Server 2000 is a program product of Microsoft Corporation.