Skip to content
SimpleTools24

How to Generate a GUID in SQL Server (NEWID and NEWSEQUENTIALID)

By SimpleTools24Published 3 min read

In SQL Server, SELECT NEWID(); generates a new random GUID of type uniqueidentifier. To generate GUIDs automatically for new rows, use NEWID() or NEWSEQUENTIALID() as a column default; NEWSEQUENTIALID() produces values that increase on a given server, which reduces index fragmentation but can only be used in a DEFAULT constraint. Store GUIDs in uniqueidentifier columns (16 bytes) rather than as strings.

Generating a GUID With NEWID()

sql
SELECT NEWID();
-- 6F9619FF-8B86-D011-B42D-00C04FC964FF  (example format)

DECLARE @id uniqueidentifier = NEWID();
SELECT @id;

NEWID() returns a random, version 4 style GUID each time it's called, including once per row in a query:

sql
SELECT TOP (5) NEWID() AS id FROM sys.objects;  -- five different GUIDs

A side effect: ORDER BY NEWID() is a common (if slow on big tables) way to shuffle rows randomly.

Using GUIDs as Column Defaults

sql
CREATE TABLE dbo.Orders (
    OrderId   uniqueidentifier NOT NULL
              CONSTRAINT DF_Orders_OrderId DEFAULT NEWSEQUENTIALID(),
    CreatedAt datetime2 NOT NULL DEFAULT SYSUTCDATETIME(),
    CONSTRAINT PK_Orders PRIMARY KEY (OrderId)
);

INSERT INTO dbo.Orders DEFAULT VALUES;

NEWID() vs NEWSEQUENTIALID()

NEWID() and NEWSEQUENTIALID() compared
NEWID()NEWSEQUENTIALID()
ValuesRandomIncreasing on the same server (until restart)
Where usableAnywhere: SELECT, variables, defaultsOnly in a DEFAULT constraint
Index fragmentationHigh as a clustered keyLow
GuessabilityHard to guessNext values can be predicted
Ordering after restartNot applicableMay start from a lower range

Microsoft's documentation notes that NEWSEQUENTIALID() values can be guessed, so don't use them where unpredictability matters. GUID as a primary key discusses the fragmentation trade-off in depth.

Getting the Generated Value Back

Because the default fires on insert, use OUTPUT to see it:

sql
INSERT INTO dbo.Orders (CreatedAt)
OUTPUT inserted.OrderId
VALUES (SYSUTCDATETIME());

Converting Strings to GUIDs

sql
SELECT CAST('3f2b8c1e-9d4a-4f6e-8b1a-2c7d5e9f0a13' AS uniqueidentifier);
SELECT TRY_CONVERT(uniqueidentifier, '{3F2B8C1E-9D4A-4F6E-8B1A-2C7D5E9F0A13}');
SELECT TRY_CONVERT(uniqueidentifier, 'not-a-guid');  -- NULL

SQL Server accepts hyphenated values with or without braces. TRY_CONVERT returns NULL instead of raising an error, which is useful when cleaning imported data. Strings without hyphens need reformatting first. For a broader list of input problems, see why a UUID is invalid.

SQL Server's Unusual GUID Sort Order

uniqueidentifier values don't sort in the order you'd expect from reading the text. SQL Server compares the last group of six bytes first, then works backwards through the other groups. Two consequences:

  • A version 7 GUID generated by your application, which is time-ordered as text, does not sort chronologically in a SQL Server uniqueidentifier column.
  • NEWSEQUENTIALID() is designed around SQL Server's comparison order, which is why it does produce ordered inserts.

If you need application-generated, time-ordered keys in SQL Server, check how your library lays out the bytes, or keep a separate creation-time column for ordering.

Generating Many GUIDs for Test Data

sql
SELECT TOP (1000) NEWID() AS id
FROM sys.all_objects a CROSS JOIN sys.all_objects b;

That works inside the database. If you need GUIDs outside it, for a seed script, a JSON fixture or a config file, the GUID generator creates up to 1,000 at a time, uppercase or lowercase, with or without braces, ready to paste. To check values you've been given, the UUID validator confirms they're well-formed and shows their version.

Storing GUIDs From Applications

When your application generates IDs (for example with Guid.NewGuid() in C#) rather than SQL Server, pass them as typed parameters:

csharp
command.Parameters.Add("@id", SqlDbType.UniqueIdentifier).Value = Guid.NewGuid();

Passing GUIDs as strings works but forces conversion and can hide formatting errors. Typed parameters also avoid SQL injection and let SQL Server use indexes efficiently.

Indexing Considerations

  • A random NEWID() primary key that's also the clustered index causes page splits as the table grows. Options: use NEWSEQUENTIALID(), make the GUID a non-clustered primary key with a separate clustered key, or use an integer key internally.
  • Leave headroom for page splits by reviewing the index fill factor on GUID-keyed tables that receive many inserts.
  • Monitor fragmentation with sys.dm_db_index_physical_stats and rebuild or reorganise indexes as part of regular maintenance.

GUID as a primary key weighs these options in more detail.

Frequently Asked Questions

What data type stores a GUID in SQL Server?

uniqueidentifier, which uses 16 bytes.

Can I use NEWSEQUENTIALID() in a SELECT?

No. It's only allowed in a DEFAULT constraint on a uniqueidentifier column.

Is NEWID() unique across servers?

GUIDs from NEWID() are random enough that collisions are not a practical concern.

How do I generate a GUID in C# for SQL Server?

Use Guid.NewGuid(); see how to generate a GUID in C#.

Summary

NEWID() gives random GUIDs anywhere; NEWSEQUENTIALID() gives ordered ones only as a default. Store them as uniqueidentifier, convert strings with TRY_CONVERT, and remember SQL Server's unusual sort order.

Sources