In a Key-Sequenced Data Set (KSDS), the primary key is the field that identifies each record and determines the order in which records are stored. A fundamental rule of KSDS is that the primary key must be unique: no two records can have the same key value. VSAM enforces this at insert time—if you try to add a record whose key already exists, the insert fails. When you update a record with REWRITE, you cannot change the key. Understanding unique keys helps you design record layouts, choose key fields, and handle duplicate-key errors in your programs. This page explains why keys must be unique, what happens when you attempt a duplicate, how to design for uniqueness, and how this differs from alternate indexes.
The KSDS index is built so that each key value maps to exactly one record. When you do a random read by key, VSAM uses the index to find the one data control interval and record that contain that key. If two records had the same key, the index could not point to both; the structure of the index assumes one record per key. So uniqueness is not optional—it is required by the way KSDS is implemented. The index entries (sequence set and index set) assume a one-to-one relationship between key values and records. That is why every insert is checked: if the key already exists, the insert is rejected. Similarly, when you update a record, the key in the record cannot be changed, because the index would then be inconsistent (the old key would still point to the record, and the new key would not be in the index).
| Rule | Detail |
|---|---|
| One key value per record | Each record has exactly one primary key value. That value must not appear as the key of any other record in the file. |
| Insert fails on duplicate | If you WRITE a new record and its key already exists, VSAM rejects the write and returns a duplicate-key condition. |
| Update cannot change key | When you REWRITE a record, the key bytes must be unchanged. You cannot change the primary key on update; that would require delete + insert. |
| Index enforces uniqueness | The index component is built so that each key value maps to at most one record. Duplicate keys would break that one-to-one mapping. |
When your program issues a WRITE (or equivalent) to add a new record to a KSDS, VSAM checks whether the key value already exists. If it does, the WRITE fails. VSAM does not overwrite the existing record, append the new record, or merge the data. It returns a condition indicating duplicate key (the exact code depends on the interface: file status in COBOL, return code in other languages). The new record is not written. Your program must handle this condition: for example, log an error, skip the record, or try a different key (e.g. add a sequence number). There is no built-in “replace if exists” or “ignore duplicate” for the primary key at the VSAM level; the application is responsible for ensuring uniqueness or handling the duplicate-key return.
When you choose the primary key for a KSDS, you must pick a field (or combination of fields) that is guaranteed unique for every record. Common choices include: a system-generated ID (e.g. sequence number, UUID), a business identifier that is defined as unique (customer number, order number, account number), or a composite of several fields that together are unique (e.g. order number + line number, or last name + first name + date + sequence). Do not use a field that can repeat—for example, last name alone is not unique—unless you extend it. If the natural key can have duplicates (e.g. multiple orders per customer), use a unique surrogate key (e.g. order ID) as the primary key and keep the non-unique field (e.g. customer ID) in the record or in an alternate index if you need to access by it.
When you update an existing record with REWRITE (or equivalent), you are replacing the record in place. The key bytes in the record must not change. If you changed the key, the index would still point to the record under the old key, and the new key would not be in the index—so the record would become “unfindable” by key and the index would be inconsistent. So VSAM does not allow changing the primary key on update. If you need to “change” a key, the only way is to delete the old record and insert a new one with the new key (and the rest of the data). Some high-level interfaces may provide a “key change” operation that does exactly that (delete + insert) under the covers, but at the VSAM level the key is fixed for the life of the record.
The primary key of the base KSDS is always unique. Alternate indexes are different: they allow you to define an alternate key that can be unique or non-unique. When you define an alternate index with UNIQUEKEY, each alternate key value can appear at most once (similar to the primary key). When you define it with NONUNIQUEKEY, the same alternate key value can appear in multiple records (e.g. all orders for the same customer ID). So “duplicate keys” in the sense of multiple records with the same value are allowed only for alternate keys when NONUNIQUEKEY is specified, not for the primary key.
Your program should check the return code or file status after each WRITE to a KSDS. If the status indicates duplicate key, you can: (1) skip the record and continue, (2) log the duplicate and abort, (3) try to generate a new key (e.g. add a sequence number) and retry, or (4) read the existing record and update it instead of inserting (if that matches your business logic). In COBOL, the file status for duplicate key is often '22' or a similar value depending on the dialect. In batch jobs that load from a sequential file, a common approach is to sort or scan the input for duplicates and remove them before writing to the KSDS, or to use a key that includes a sequence number so that each record gets a unique key even when the business key repeats.
123456*> Example: check for duplicate key after WRITE WRITE RECORD-OUT IF FILE-STATUS = '22' DISPLAY 'Duplicate key: ' REC-KEY *> Handle: skip, log, or retry with new key END-IF
Think of the key like a name on a locker. Each locker can have only one name, and no two lockers can have the same name. If you try to add a second locker with the same name, the system says “that name is already used.” When you change what’s inside the locker, you don’t change the name on it. So you have to pick a name (key) that is different for every locker (record).
1. Can two KSDS records have the same primary key?
2. What happens when you insert a record with a key that already exists?
3. Can you change the primary key when you REWRITE a record?