DQL vs VQL: What Changes for a Documentum Developer?
The syntax looks familiar. The data model does not.
If you already know Documentum Query Language, your first VQL query may feel surprisingly comfortable. Both languages give you familiar constructs: SELECT FROM WHERE ORDER BY. A simple query can look almost transferable.
Documentum:
select r_object_id, object_name
from dm_document
where object_name like 'SOP%'
order by r_modify_date desc
Vault:
select id, name__v
from documents
where name__v like 'SOP%'
order by version_modified_date__v desc
That similarity is useful. It is also where trouble starts.
VQL is intentionally SQL-like, and it retrieves fields from query targets such as documents, Vault objects, and users. A familiar query grammar does not mean that the Documentum object model has simply been renamed.
Mental model
DQL teaches you to query a repository object model. VQL teaches you to query Vault query targets and their fields, relationships, and document-version model.
Keep the SQL-like syntax. Rebuild the assumptions underneath it.
The first trap: FROM does not mean the same thing
In Documentum, a developer becomes very comfortable querying types directly:
select r_object_id, object_name
from dm_document
or:
select r_object_id, object_name
from custom_document
A custom document subtype is naturally something you can put in the FROM clause. That mental model does not carry cleanly into Vault.
For Vault documents, the query target is generally:
from documents
Document type is then part of the document metadata. For example:
select id, name__v
from documents
where toname(type__v) = 'sop__c'
The important shift is:
Documentum
custom_document
|
v
FROM type
Veeva Vault
documents
|
+-- type__v
+-- subtype__v
+-- classification__v
Use TONAME() when filtering document fields such as type so that the query uses the field’s API name rather than a potentially localized display label.
For Vault objects, things look more familiar again:
select id, name__v
from product__v
So FROM can refer to a Vault object such as product__v, but a Vault document type should not be mentally mapped to a Documentum custom object type. That distinction saves a lot of confusion later.
Documents and objects are separate query models
In Documentum, nearly everything starts to feel like an object somewhere in the repository hierarchy. You learn the family:
dm_object
|
dm_sysobject
|
dm_document
|
custom document types
and DQL works naturally with that inheritance model.
Vault makes a stronger conceptual distinction between documents and Vault objects. Documents are queried through FROM documents. Application data objects have their own query targets:
from product__v
from study__v
from custom_object__c
So one of the first questions when writing VQL should be: am I querying documents, or am I querying application data? That sounds basic, but for a Documentum developer it represents a meaningful change in the data model.
Version queries look similar — until you inspect the IDs
A Documentum developer already understands that from dm_document and from dm_document (all) have different version semantics. Vault has an idea that looks familiar:
select id, major_version_number__v, minor_version_number__v
from allversions documents
By default, FROM documents queries the latest document version. ALLVERSIONS explicitly includes all document versions. So it is tempting to map:
dm_document (all) <--> allversions documents
That is useful as a starting point. But now look at identity.
Documentum
Different versions have different r_object_id values. The version tree is tied together by i_chronicle_id.
i_chronicle_id (shared)
1.0 r_object_id (its own 09… id)
1.1 r_object_id (a different 09… id)
2.0 r_object_id (another 09… id)
Each version is a different 16-character id. Examples use the 09 type tag and x for the rest, because those digits include the docbase id. See r_object_id, i_chronicle_id, and versions.
Vault
Vault keeps the document id while versions are distinguished by version information. An ALLVERSIONS result can therefore look conceptually like:
id = 6 version = 1.0
id = 6 version = 1.1
id = 6 version = 2.0
The same document ID appears across versions while major_version_number__v and minor_version_number__v identify the individual versions.
This means r_object_id is not the Vault id. And i_chronicle_id is not simply another Vault field waiting to be discovered. The version identity model itself changed. For a Documentum developer, this is a much more important lesson than memorizing the spelling of ALLVERSIONS.
Fields: stop translating names and inspect metadata
Documentum developers learn to recognize system attributes almost by sight: r_object_id, r_modify_date, r_version_label, i_chronicle_id, i_folder_id, a_content_type.
Vault fields look very different: id, name__v, state__v, lifecycle__v, type__v, major_version_number__v, minor_version_number__v.
Custom fields and objects may use names ending in __c, while Vault-managed names commonly use other namespace suffixes. The important habit is not memorizing suffixes. It is: use API names as the source of truth.
VQL provides discovery commands that have no reason to be hidden behind a UI:
show targets
show fields
show relationships
These allow a developer to discover query targets, queryable fields, and relationships directly through VQL. Don’t guess the field. Inspect the query target.
WHERE feels familiar
Most basic filters translate mentally without much friction.
select r_object_id, object_name
from dm_document
where object_name like 'SOP%'
select id, name__v
from documents
where name__v like 'SOP%'
VQL supports familiar comparison operators such as = != < > <= >=, and logical/filter operators including AND, OR, BETWEEN, CONTAINS, and LIKE, subject to restrictions for particular fields and query targets.
That familiarity is real. But do not assume that every DQL expression has a syntax-level VQL translation. The fields and their data types decide what operations make sense.
FIND deserves its own mental slot
VQL has another important query mechanism: FIND.
select id, name__v
from documents
find ('insulin' scope name__v)
FIND is intended for search behavior rather than ordinary field comparison. It can search document or object fields, and document searches can also work with content scopes. It can be combined with a WHERE clause to search first and then narrow the result set.
A Documentum developer should therefore keep these ideas separate:
WHERE → structured field filtering
FIND → search
Do not reduce FIND mentally to another spelling of LIKE. It is not. For document search, VQL can also use ORDER BY RANK to sort FIND results by relevance.
Repeating attributes are not just “multi-value fields with a new name”
Repeating attributes are deeply embedded in Documentum. A DQL developer becomes familiar with constructs such as any r_version_label = 'CURRENT' and learns that selecting or joining repeating attributes can affect result-row behavior.
Vault also has fields capable of containing multiple values, but carrying the entire Documentum repeating-attribute model into VQL is a mistake.
VQL operators work according to the Vault field’s metadata and type. For example, CONTAINS can test a field against a set of values:
where some_field__c contains ('value1', 'value2')
But this should not be read as DQL ANY = VQL CONTAINS. The useful mapping is only conceptual: in Documentum, understand whether the attribute is repeating. In Vault, understand the field type and whether it is single- or multi-value. Then use the operators supported by that Vault field. Metadata matters more than syntax translation.
Relationships are metadata, not arbitrary SQL joins
DQL can make a Documentum developer comfortable with querying multiple repository types and constructing joins. VQL also supports relationship queries, but Vault relationships should be treated as part of the configured data model.
A related object’s field can be traversed using relationship notation such as:
select name__v, country__cr.name__v
from product__v
VQL also supports relationship subqueries for appropriate document and object relationships. The mental change is:
DQL instinct: What can I join?
VQL instinct: What relationship does Vault expose between these query targets?
Before building a complex query: SHOW RELATIONSHIPS. Inspect first. Guess second.
Limiting results is more explicit
Documentum developers may be used to DQL query hints and constructs such as RETURN_TOP. See ENABLE hints for large result sets. VQL exposes result controls directly as clauses: MAXROWS, SKIP, PAGESIZE, PAGEOFFSET.
select id, name__v
from documents
order by id
maxrows 100
MAXROWS limits the maximum number of results retrieved, while PAGESIZE controls how many results appear on a response page. SKIP and PAGEOFFSET affect where result retrieval or pagination begins.
One practical warning: current VQL guidance discourages deep manual pagination with PAGEOFFSET; newer versions warn on expensive usage and reject manual pagination beyond certain large offsets. So do not automatically convert every old batch-processing pattern into PAGEOFFSET += 1000 without thinking about the API behavior.
Dates look simpler, but the semantics still matter
A classic DQL query might use a Documentum date expression. In VQL, ordinary date filters use ISO-style values:
select id, name__v
from documents
where version_modified_date__v >= '2026-09-01T00:00:00.000Z'
Recent VQL versions also support relative date literals such as TODAY and other ranges. Don’t copy DQL DATE(...) expressions into VQL. Use the Vault field type and VQL date syntax.
Where the analogy breaks
- DQL and VQL are both SQL-like, but they query different worlds. The grammar creates familiarity. The underlying models create the differences.
- A Documentum type is not automatically a Vault query target. A custom Documentum document type can naturally appear after
FROM. A Vault document type normally remains a property of thedocumentsquery target. - Document version identity changed. Documentum gives each version its own
r_object_idand ties the version tree together withi_chronicle_id. Vault keeps the documentidand represents document versions separately. - Repeating attributes are not Vault multi-value fields. They solve similar categories of problems but belong to different storage and query models.
- DQL joins do not translate mechanically into VQL relationships. In Vault, discover and use the configured relationship model.
- VQL has search concepts that deserve separate treatment.
FIND,SCOPE, andORDER BY RANKare not simply alternate spellings ofWHERE,LIKE, andORDER BY.
A quick mental mapping
| Documentum / DQL | Veeva Vault / VQL | Watch out for |
|---|---|---|
dm_document | documents | Not the same object model |
Custom document type in FROM | documents + type filter | Vault document type is not normally the query target |
r_object_id | id | Version identity behaves differently |
i_chronicle_id | No direct equivalent | Vault document ID persists across versions |
(ALL) | ALLVERSIONS | Similar purpose, different identity model |
r_version_label | Major/minor version fields, state/status | Do not force a 1:1 mapping |
| Repeating attribute | Multi-value Vault field | Different field/query semantics |
| DQL field qualification | VQL WHERE | Familiar syntax, different fields |
| Full-text / search logic | FIND / SCOPE | Separate from ordinary filtering |
| Joins / relation logic | Vault relationships | Discover relationships first |
RETURN_TOP style patterns | MAXROWS | Pagination is separate |
| Repository schema knowledge | SHOW TARGETS / FIELDS / RELATIONSHIPS | Let Vault describe itself |
A better habit for a DQL developer
When writing VQL, resist the first question: how do I write this DQL in VQL? Instead ask: what was this DQL actually trying to retrieve?
Then identify:
- Is it a document or a Vault object?
- What is the query target?
- What are the actual API field names?
- Am I interested in the latest version or all versions?
- Is this a structured filter or a search?
- Is the related data exposed through a Vault relationship?
- How should the API result be paged?
Only then write the query. This produces better VQL than line-by-line translation.
The mental model to keep
The easiest parts of DQL knowledge to carry into Vault are the general query instincts: select only what you need, filter early, understand the data type, know which version you are querying, don’t trust a query until you understand its result shape. Those habits transfer perfectly. The repository-specific assumptions do not.
VQL looks close enough to DQL that an experienced Documentum developer can become productive quickly. But the goal is not to learn a new dialect of the same language. The goal is to recognize that the familiar syntax is sitting on top of a different content model. Once that clicks, VQL becomes much easier.