You could use a sequence with the CYCLE
option used as pointer in the table used as ring buffer. This creates a sequence object in the database:
CREATE SEQUENCE BufferPtr
START WITH 1
MINVALUE 1
MAXVALUE 100000
CYCLE;
Create the table differently to allow empty entries and to allow entering Ids
CREATE TABLE dbo.TabOfEvents (
[Id] INT NOT NULL,
[cta] NCHAR (10) NULL,
[code] NVARCHAR (MAX) NULL,
[date] DATETIME2 (7) NULL,
PRIMARY KEY CLUSTERED ([Id] ASC)
)
Then fill the table with 100000 empty records and Ids 1 .. 100000. We do this to know the number of records in advance and to save ourselves a query. I.e., we do not have to query the number of records with SELECT COUNT (*) FROM TabOfEvents
to know if we must make an insert or an update. The Sequence is used in the UPDATE command itself to determine which record we update. A new sequence number is generated each time and after the limit 100,000 is reached the sequence starts over at 1.
-- This creates 100000 empty records with an Id. The code is quite tricky and I won't explain
-- the details here. If you prefer, create a stored procedure with a FOR-loop or do it in an
-- external application (e.g. C# Console app). Performance is not important, since we are
-- doing it only once.
;WITH e1(n) AS
(
SELECT 1 FROM (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(0)) t(n)
)
INSERT INTO dbo.TabOfEvents (Id)
SELECT ROW_NUMBER() OVER (ORDER BY n10.n) AS n
FROM
e1 n10
CROSS JOIN e1 n100
CROSS JOIN e1 n1000
CROSS JOIN e1 n10000
CROSS JOIN e1 n100000
Now the table and the sequence are set up and you can update the records with
UPDATE TabOfEvents
SET cta = 'test', code = 'xxx', [date] = SYSDATETIME()
FROM
TabOfEvents
INNER JOIN
(SELECT
NEXT VALUE FOR BufferPtr AS Ptr
FROM (VALUES (1)) t(n)
) a
ON TabOfEvents.Id = a.Ptr;
You can see a test here (http://sqlfiddle.com/#!6/2679e/5/2) using only 4 records. Click Run SQL repeatedly and you will see how events are added in a cycle.
Note: My first attempt was to use UPDATE TabOfEvents
SET cta = 'test', code = 'xxx', [date] = SYSDATETIME() WHERE Id = NEXT VALUE FOR BufferPtr
, but SQL-Server refuses to query a sequence in the WHERE clause. Can my UPDATE statement be simplified?