Documentum → Veeva Notes

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

A quick mental mapping

Documentum / DQL Veeva Vault / VQL Watch out for
dm_documentdocumentsNot the same object model
Custom document type in FROMdocuments + type filterVault document type is not normally the query target
r_object_ididVersion identity behaves differently
i_chronicle_idNo direct equivalentVault document ID persists across versions
(ALL)ALLVERSIONSSimilar purpose, different identity model
r_version_labelMajor/minor version fields, state/statusDo not force a 1:1 mapping
Repeating attributeMulti-value Vault fieldDifferent field/query semantics
DQL field qualificationVQL WHEREFamiliar syntax, different fields
Full-text / search logicFIND / SCOPESeparate from ordinary filtering
Joins / relation logicVault relationshipsDiscover relationships first
RETURN_TOP style patternsMAXROWSPagination is separate
Repository schema knowledgeSHOW TARGETS / FIELDS / RELATIONSHIPSLet 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:

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.