In Oracle Database, the standard way to generate a UUID is the SYS_GUID() function, which returns a 16-byte RAW value built from the host identifier and a timestamp. To turn that RAW into the familiar 8-4-4-4-12 hexadecimal string, wrap it in RAWTOHEX() and SUBSTR() to insert the dashes, or store it as-is if your column accepts RAW. Oracle 23c introduced a native UUID data type and a random_uuid() function that returns a properly formatted 36-character dashed string compatible with the RFC 4122 layout. None of Oracle's built-in generators produce a tagged version 4 UUID in the strict sense, because SYS_GUID labels itself only as a globally unique identifier rather than a versioned UUID, while random_uuid is a newer convenience function that does not guarantee the version and variant nibbles. For app-layer IDs, test fixtures, or any identifier created outside the database, you can mint RFC 4122 version 4 UUIDs in your browser with the UUID Generator tool and paste the result straight into SQL, application code, or seed scripts.

Oracle's Built-In UUID Functions at a Glance
Oracle ships three different mechanisms for producing a UUID inside the database, and they were not all available at once. SYS_GUID() has been around for decades and works in every supported release. The native UUID column type and the random_uuid() function arrived with Oracle Database 23c, where the database finally catches up with the storage and formatting conventions developers have used elsewhere for years. Each function returns a different data type and uses a different textual layout, so picking the right one depends on both your Oracle version and how the rest of your system plans to consume the value.
| Function | Available Since | Return Type | Default Text Form | Version Field |
|---|---|---|---|---|
| SYS_GUID() | Long-standing (pre-12c) | RAW(16) | 32 hex characters, no dashes | Not labeled |
| UUID column type | Oracle 23c | UUID (native 128-bit) | Dashed when cast to string | Not strictly RFC 4122 |
| random_uuid() | Oracle 23c | VARCHAR2(36) | 8-4-4-4-12 dashed string | RFC 4122–style output |
Using SYS_GUID() in a SQL Query
The most common Oracle pattern is to call SYS_GUID() directly inside an INSERT or DEFAULT clause and convert the RAW result with RAWTOHEX(). A bare SYS_GUID() call returns a 16-byte binary value that SQL*Plus prints as raw bytes, so you almost always wrap it before display:
SELECT RAWTOHEX(SYS_GUID()) AS uuid FROM DUAL;
That returns something like 7B8F4D2C9E1A4F6B8C0D3E5F7A9B1C2D, a 32-character hexadecimal string with no separators. If your application expects the dashed form used by RFC 4122 and by most other databases, you can reformat it with SUBSTR and concatenation:
SELECT LOWER(SUBSTR(hex,1,8) || '-' || SUBSTR(hex,9,4) || '-' || SUBSTR(hex,13,4) || '-' || SUBSTR(hex,17,4) || '-' || SUBSTR(hex,21,12)) AS uuid FROM (SELECT RAWTOHEX(SYS_GUID()) AS hex FROM DUAL);
Many teams skip the dashes entirely and store the 32-character hex form in a CHAR(32) column. That keeps indexes tight and avoids string gymnastics in the application layer, at the cost of breaking compatibility with systems that expect a dashed UUID. SYS_GUID() is built to never collide between machines, but it is not a uniformly random value the way an RFC 4122 v4 UUID is, which is why it does not advertise a version digit.
Oracle 23c Native UUID Column Type and random_uuid()
Oracle Database 23c introduces a real UUID data type, so you can declare a column without choosing between RAW, VARCHAR2, or CHAR. The column accepts values written in dashed form and stores them as a 128-bit binary internally, mirroring the way PostgreSQL has handled UUIDs for years. You can rely on the database to fill the column by using DEFAULT, which fires the same generation routine as the random_uuid() function:
CREATE TABLE orders (id UUID DEFAULT random_uuid() PRIMARY KEY, customer_id UUID, created_at TIMESTAMP);
The random_uuid() function returns a VARCHAR2(36) string laid out as 8-4-4-4-12, with hex digits chosen to match the appearance of an RFC 4122 identifier. The Oracle documentation describes it as returning "a randomly generated UUID, as a string of 36 characters," so for column defaults and ad hoc SELECT statements it is the most convenient option on 23c and later. On earlier releases the practical choice stays SYS_GUID() plus your own formatting, or you skip the database entirely.
Format Differences Between Oracle Output and RFC 4122
The biggest gotcha when you generate a UUID in Oracle is that none of the three options strictly produce an RFC 4122 version 4 value. SYS_GUID is built from system information that is not structured into the version and variant nibbles RFC 4122 reserves, and random_uuid() outputs a dashed string in the right shape but does not guarantee that the 13th hex digit is 4 and the 17th is one of 8, 9, a, or b. The practical effect is that an Oracle-generated identifier is almost always unique, and most cross-system code will treat it as a UUID, yet strict validators that inspect the version and variant nibbles per RFC 4122 may reject it.
| Aspect | SYS_GUID() | random_uuid() / UUID column | RFC 4122 v4 (UUID Generator) |
|---|---|---|---|
| Length | 32 hex chars | 36 chars with dashes | 36 chars with dashes |
| Randomness source | System-derived bits | Database RNG | Browser CSPRNG (Web Crypto) |
| 13th hex digit | Not fixed | Not fixed | Always 4 |
| 17th hex digit | Not fixed | Not fixed | 8, 9, a, or b |
| Usable bits | 122 (structured) | 122 | 122 pure random |
That is why many teams that need strictly compliant identifiers move generation outside the database. A value minted by an RFC 4122 v4 UUID generator in the browser guarantees the version and variant nibbles sit in the right slots, with 122 truly random bits supplied by the platform CSPRNG.
Generate UUIDs Outside the Database With the UUID Generator
When you need a UUID that meets RFC 4122 to the letter, or when you need IDs before the database is in the loop, the fastest path is a browser-based generator. The UUID Generator produces one or many version 4 UUIDs locally, using the Web Crypto API's getRandomValues for the random bits, so each value is statistically independent and unguessable. To mint identifiers for an Oracle project:
- Open the UUID Generator and enter how many values you need, up to 100 at a time.
- Toggle uppercase or remove hyphens if your Oracle column stores CHAR(32) hex or prefers a different casing.
- Click Generate, then copy a single UUID or use Copy all to grab every value in one pass.
- Paste the result into your INSERT statement, PL/SQL block, seed file, or application code.
Every UUID is produced in your own browser tab, and the tool never sends values to a server, which makes it safe for production identifiers and internal secrets alike. Because the random bits come from a CSPRNG, the values are collision-resistant enough to treat as globally unique without coordinating with the database, and they pass any RFC 4122 v4 validator you point at them.
Picking the Right UUID Source for Your Project
Choose SYS_GUID() on Oracle 12c through 19c when you want a database-side default and you are happy with a 32-character hex string or your own dashed formatting. On 23c and newer, prefer the native UUID column type with a random_uuid() default for the cleanest storage model and the simplest application code. Reach for the UUID Generator whenever the consumer lives outside Oracle, the value must satisfy a strict RFC 4122 validator, or you are seeding test data, generating API request IDs, or writing identifiers into client-side code. The two approaches are not mutually exclusive: many teams use random_uuid() inside Oracle for primary keys and a browser generator for everything that crosses the database boundary.
If you also generate identifiers in JavaScript, see the companion walkthrough on how to generate UUIDs in JavaScript for the equivalent browser-side and Node-side patterns.
If you're weighing options, VS Code Keyboard Shortcuts: Defaults Compared by Platform covers this in detail.