<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Oracle 26ai Archives - Philipp Salvisberg&#039;s Blog</title>
	<atom:link href="https://www.salvis.com/blog/tag/oracle-26ai/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.salvis.com/blog/tag/oracle-26ai/</link>
	<description>Database-centric development</description>
	<lastBuildDate>Tue, 31 Mar 2026 06:36:18 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://www.salvis.com/blog/wp-content/uploads/2014/04/favicon.png</url>
	<title>Oracle 26ai Archives - Philipp Salvisberg&#039;s Blog</title>
	<link>https://www.salvis.com/blog/tag/oracle-26ai/</link>
	<width>32</width>
	<height>32</height>
</image> 
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/>
<atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/>
<atom:link rel="hub" href="https://websubhub.com/hub"/>
<atom:link rel="self" href="https://www.salvis.com/blog/tag/oracle-26ai/feed/"/>
	<item>
		<title>Using SQL Assertions to Enforce Temporal Data Integrity</title>
		<link>https://www.salvis.com/blog/2026/03/09/using-sql-assertions-to-enforce-temporal-data-integrity/</link>
					<comments>https://www.salvis.com/blog/2026/03/09/using-sql-assertions-to-enforce-temporal-data-integrity/#respond</comments>
		
		<dc:creator><![CDATA[Philipp Salvisberg]]></dc:creator>
		<pubDate>Mon, 09 Mar 2026 14:45:31 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle 26ai]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Assertions]]></category>
		<category><![CDATA[Temporal Database]]></category>
		<category><![CDATA[Valid Time]]></category>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=16264</guid>

					<description><![CDATA[<p>Introduction More than twelve years ago, I described the multi-temporal features of Oracle Database in this blog post. In the conclusion, I wrote that I missed a temporal DML API, temporal integrity constraints, temporal joins, and temporal aggregations. These features are still missing today. However, in the latest version of Oracle AI<span class="excerpt-hellip"> […]</span></p>
<p>The post <a href="https://www.salvis.com/blog/2026/03/09/using-sql-assertions-to-enforce-temporal-data-integrity/">Using SQL Assertions to Enforce Temporal Data Integrity</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading" id="introduction">Introduction</h2>



<p>More than twelve years ago, I described the multi-temporal features of Oracle Database in this <a href="https://www.salvis.com/blog/2014/01/04/multi-temporal-database-features-in-oracle-12c/" type="post" id="1009" target="_blank" rel="noreferrer noopener">blog post</a>. In the conclusion, I wrote that I missed a temporal DML API, temporal integrity constraints, temporal joins, and temporal aggregations. These features are still missing today.</p>



<p>However, in the latest version of Oracle AI Database (23.26.1), SQL assertions make it possible to define temporal integrity constraints manually. In this post, I demonstrate how.</p>



<h2 class="wp-block-heading" id="data-model">Data Model</h2>



<p>There are various ways to model temporal data. In this post, I use the well-known non-temporal DEPT-EMP model as a basis and add a history table for each non-temporal table with a valid-time <a href="https://docs.oracle.com/en/database/oracle/oracle-database/26/sqlrf/CREATE-TABLE.html#GUID-F9CE0CC3-13AE-4744-A43C-EAC7A71AAAB6__CJADHJHB" target="_blank" rel="noreferrer noopener">period</a> named <code>vt</code> using the column <code>vt_start</code> for the beginning of the period and <code>vt_end</code> for the end of the period. Please note that Oracle Database uses half-open intervals for temporal periods and <code>NULL</code> for <code>-∞</code> and <code>+∞</code>.</p>



<p>Non-temporal tables store the most recent version of the data, which is kept in their history tables. This simplifies access to the latest version and provides the expected performance for non-temporal data. The disadvantage is that the API must maintain redundant data. Note that the latest version is not necessarily the current version. The current version is the one whose valid-time period contains the current date and time.</p>



<p>This model versions all columns of the base table, potentially resulting in more rows in the history tables than necessary. Furthermore, the model does not support soft deletes. In other words, there is no <code>is_deleted</code> flag. This makes managing data integrity easier. No need to keep reference and structure data just because some deleted rows still reference it. In any case, this is sufficient for this blog post.</p>



<figure class="wp-block-image size-full"><a href="https://www.salvis.com/blog/wp-content/uploads/2026/03/dept-emp.svg"><img decoding="async" src="https://www.salvis.com/blog/wp-content/uploads/2026/03/dept-emp.svg" alt="" class="wp-image-16270"/></a></figure>



<h2 class="wp-block-heading" id="setup">Setup</h2>



<p>For the examples in this blog post, I used Oracle AI Database 26ai Enterprise Edition Release 23.26.1.0.0.</p>



<p>Connected as&nbsp;<code>SYS</code>,&nbsp;I ran the following script to create the user&nbsp;<code>DEMO</code>&nbsp;with the necessary privileges.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">1) DEMO user</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>create user demo identified by demo
   default tablespace users
   temporary tablespace temp
   quota unlimited on users;
   
grant create session to demo;
grant create table to demo;
grant create sequence to demo;
grant create assertion to demo;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">user</span><span style="color: #D4D4D4"> demo identified by demo</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">default</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">tablespace</span><span style="color: #D4D4D4"> users</span></span>
<span class="line"><span style="color: #D4D4D4">   temporary </span><span style="color: #569CD6">tablespace</span><span style="color: #D4D4D4"> temp</span></span>
<span class="line"><span style="color: #D4D4D4">   quota unlimited </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> users;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span></span>
<span class="line"><span style="color: #569CD6">grant</span><span style="color: #D4D4D4"> create session to demo;</span></span>
<span class="line"><span style="color: #569CD6">grant</span><span style="color: #D4D4D4"> create </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> to demo;</span></span>
<span class="line"><span style="color: #569CD6">grant</span><span style="color: #D4D4D4"> create </span><span style="color: #569CD6">sequence</span><span style="color: #D4D4D4"> to demo;</span></span>
<span class="line"><span style="color: #569CD6">grant</span><span style="color: #D4D4D4"> create assertion to demo;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>User DEMO created.


Grant succeeded.


Grant succeeded.


Grant succeeded.


Grant succeeded.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">User DEMO created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Grant succeeded.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Grant succeeded.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Grant succeeded.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Grant succeeded.</span></span></code></pre></div>



<p>Connected as&nbsp;<code>DEMO</code>,&nbsp;I ran the following script to implement the data model as outlined in the previous chapter with initial data.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">2) Install model with data</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>create table dept (
   deptno      number(2, 0)      not null,
   dname       varchar2(14 char) not null,
   loc         varchar2(13 char) not null,
   constraint dept_pk primary key (deptno) deferrable initially immediate
);

create table dept_ht (
   hist_id     integer generated always as identity not null,
   vt_start    date              null,
   vt_end      date              null,
   deptno      number(2, 0)      not null,
   dname       varchar2(14 char) not null,
   loc         varchar2(13 char) not null,
   period for vt (vt_start, vt_end),
   constraint dept_ht_pk primary key (hist_id),
   constraint dept_ht_uk unique (deptno, vt_start) deferrable initially immediate,
   constraint dept_ht_dept_fk foreign key (deptno) references dept deferrable initially immediate,
   constraint dept_ht_vt_ck check (vt_start is null or vt_end is null or vt_start &lt; vt_end) deferrable initially immediate
);

create index dept_ht_dept_fk_i on dept_ht (deptno);

create table emp (
   empno       number(4, 0)      not null,
   ename       varchar2(10 char) not null,
   job         varchar2(9 char)  not null,
   mgr         number(4, 0),
   hiredate    date              not null,
   sal         number(7, 2)      not null,
   comm        number(7, 2),
   deptno      number(2, 0)      not null,
   constraint emp_pk primary key (empno) deferrable initially immediate,
   constraint emp_emp_fk foreign key (mgr) references emp deferrable initially immediate,
   constraint emp_dept_fk foreign key (deptno) references dept deferrable initially immediate
);

create index emp_dept_fk_i on emp(deptno);
create index emp_emp_fk_i on emp(mgr);

create table emp_ht (
   hist_id     integer generated always as identity not null,
   vt_start    date              null,
   vt_end      date              null,
   empno       number(4, 0)      not null,
   ename       varchar2(10 char) not null,
   job         varchar2(9 char)  not null,
   mgr         number(4, 0)      null,
   hiredate    date              not null,
   sal         number(7, 2)      not null,
   comm        number(7, 2)      null,
   deptno      number(2, 0)      not null,
   period for vt (vt_start, vt_end),
   constraint emp_ht_pk primary key (hist_id),
   constraint emp_ht_uk unique (empno, vt_start) deferrable initially immediate,
   constraint emp_ht_emp_empno_fk foreign key (empno) references emp deferrable initially immediate,
   constraint emp_ht_emp_mgr_fk foreign key (mgr) references emp deferrable initially immediate,
   constraint emp_ht_dept_fk foreign key (deptno) references dept deferrable initially immediate,
   constraint emp_ht_vt_ck check (vt_start is null or vt_end is null or vt_start &lt; vt_end) deferrable initially immediate
);

create index emp_ht_emp_fk on emp_ht (deptno);
create index emp_ht_dept_fk on emp_ht (mgr);

insert into dept (deptno, dname, loc)
values (10, 'ACCOUNTING', 'NEW YORK'),
       (20, 'RESEARCH',   'DALLAS'),
       (30, 'SALES',      'CHICAGO'),
       (40, 'OPERATIONS', 'BOSTON');

insert into dept_ht (deptno, dname, loc)
select deptno, dname, loc
  from dept;

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7566, 'JONES',  'MANAGER',   7839, date '1981-04-02', 2975, null, 20),
       (7698, 'BLAKE',  'MANAGER',   7839, date '1981-05-01', 2850, null, 30),
       (7782, 'CLARK',  'MANAGER',   7839, date '1981-06-09', 2450, null, 10),
       (7788, 'SCOTT',  'ANALYST',   7566, date '1987-04-19', 3000, null, 20),
       (7902, 'FORD',   'ANALYST',   7566, date '1981-12-03', 3000, null, 20),
       (7499, 'ALLEN',  'SALESMAN',  7698, date '1981-02-20', 1600,  300, 30),
       (7521, 'WARD',   'SALESMAN',  7698, date '1981-02-22', 1250,  500, 30),
       (7654, 'MARTIN', 'SALESMAN',  7698, date '1981-09-28', 1250, 1400, 30),
       (7844, 'TURNER', 'SALESMAN',  7698, date '1981-09-08', 1500,    0, 30),
       (7900, 'JAMES',  'CLERK',     7698, date '1981-12-03',  950, null, 30),
       (7934, 'MILLER', 'CLERK',     7782, date '1982-01-23', 1300, null, 10),
       (7369, 'SMITH',  'CLERK',     7902, date '1980-12-17',  800, null, 20),
       (7839, 'KING',   'PRESIDENT', null, date '1981-11-17', 5000, null, 10),
       (7876, 'ADAMS',  'CLERK',     7788, date '1987-05-23', 1100, null, 20);

insert into emp_ht (empno, ename, job, mgr, hiredate, sal, comm, deptno)
select empno, ename, job, mgr, hiredate, sal, comm, deptno
  from emp;

commit;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> dept (</span></span>
<span class="line"><span style="color: #D4D4D4">   deptno      </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   dname       </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">14</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   loc         </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">13</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> dept_pk </span><span style="color: #569CD6">primary key</span><span style="color: #D4D4D4"> (deptno) deferrable initially immediate</span></span>
<span class="line"><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> dept_ht (</span></span>
<span class="line"><span style="color: #D4D4D4">   hist_id     </span><span style="color: #569CD6">integer</span><span style="color: #D4D4D4"> generated always </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> identity </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   vt_start    </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4">              </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   vt_end      </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4">              </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   deptno      </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   dname       </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">14</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   loc         </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">13</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   period </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> vt (vt_start, vt_end),</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> dept_ht_pk </span><span style="color: #569CD6">primary key</span><span style="color: #D4D4D4"> (hist_id),</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> dept_ht_uk </span><span style="color: #569CD6">unique</span><span style="color: #D4D4D4"> (deptno, vt_start) deferrable initially immediate,</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> dept_ht_dept_fk </span><span style="color: #569CD6">foreign key</span><span style="color: #D4D4D4"> (deptno) </span><span style="color: #569CD6">references</span><span style="color: #D4D4D4"> dept deferrable initially immediate,</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> dept_ht_vt_ck </span><span style="color: #569CD6">check</span><span style="color: #D4D4D4"> (vt_start </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> vt_end </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> vt_start &lt; vt_end) deferrable initially immediate</span></span>
<span class="line"><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> index dept_ht_dept_fk_i </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> dept_ht (deptno);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> emp (</span></span>
<span class="line"><span style="color: #D4D4D4">   empno       </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   ename       </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   job         </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">9</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">)  </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   mgr         </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">   hiredate    </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4">              </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   sal         </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">7</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   comm        </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">7</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">   deptno      </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_pk </span><span style="color: #569CD6">primary key</span><span style="color: #D4D4D4"> (empno) deferrable initially immediate,</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_emp_fk </span><span style="color: #569CD6">foreign key</span><span style="color: #D4D4D4"> (mgr) </span><span style="color: #569CD6">references</span><span style="color: #D4D4D4"> emp deferrable initially immediate,</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_dept_fk </span><span style="color: #569CD6">foreign key</span><span style="color: #D4D4D4"> (deptno) </span><span style="color: #569CD6">references</span><span style="color: #D4D4D4"> dept deferrable initially immediate</span></span>
<span class="line"><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> index emp_dept_fk_i </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> emp(deptno);</span></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> index emp_emp_fk_i </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> emp(mgr);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> emp_ht (</span></span>
<span class="line"><span style="color: #D4D4D4">   hist_id     </span><span style="color: #569CD6">integer</span><span style="color: #D4D4D4"> generated always </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> identity </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   vt_start    </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4">              </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   vt_end      </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4">              </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   empno       </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   ename       </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   job         </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">9</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">)  </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   mgr         </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   hiredate    </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4">              </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   sal         </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">7</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   comm        </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">7</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   deptno      </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   period </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> vt (vt_start, vt_end),</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_ht_pk </span><span style="color: #569CD6">primary key</span><span style="color: #D4D4D4"> (hist_id),</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_ht_uk </span><span style="color: #569CD6">unique</span><span style="color: #D4D4D4"> (empno, vt_start) deferrable initially immediate,</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_ht_emp_empno_fk </span><span style="color: #569CD6">foreign key</span><span style="color: #D4D4D4"> (empno) </span><span style="color: #569CD6">references</span><span style="color: #D4D4D4"> emp deferrable initially immediate,</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_ht_emp_mgr_fk </span><span style="color: #569CD6">foreign key</span><span style="color: #D4D4D4"> (mgr) </span><span style="color: #569CD6">references</span><span style="color: #D4D4D4"> emp deferrable initially immediate,</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_ht_dept_fk </span><span style="color: #569CD6">foreign key</span><span style="color: #D4D4D4"> (deptno) </span><span style="color: #569CD6">references</span><span style="color: #D4D4D4"> dept deferrable initially immediate,</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_ht_vt_ck </span><span style="color: #569CD6">check</span><span style="color: #D4D4D4"> (vt_start </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> vt_end </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> vt_start &lt; vt_end) deferrable initially immediate</span></span>
<span class="line"><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> index emp_ht_emp_fk </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> emp_ht (deptno);</span></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> index emp_ht_dept_fk </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> emp_ht (mgr);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> dept (deptno, dname, loc)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ACCOUNTING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;NEW YORK&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;RESEARCH&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;DALLAS&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SALES&#39;</span><span style="color: #D4D4D4">,      </span><span style="color: #CE9178">&#39;CHICAGO&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">40</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;OPERATIONS&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;BOSTON&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> dept_ht (deptno, dname, loc)</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> deptno, dname, loc</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">7566</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;JONES&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;MANAGER&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-04-02&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2975</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;BLAKE&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;MANAGER&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-05-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2850</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7782</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;CLARK&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;MANAGER&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-06-09&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2450</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7788</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SCOTT&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;ANALYST&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7566</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1987-04-19&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">3000</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7902</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;FORD&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;ANALYST&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7566</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-12-03&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">3000</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7499</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ALLEN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-02-20&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1600</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">300</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7521</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;WARD&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-02-22&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1250</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">500</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7654</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;MARTIN&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-09-28&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1250</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1400</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7844</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;TURNER&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-09-08&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1500</span><span style="color: #D4D4D4">,    </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7900</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;JAMES&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-12-03&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">950</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7934</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;MILLER&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7782</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1982-01-23&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1300</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7369</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SMITH&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7902</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1980-12-17&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">800</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;PRESIDENT&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">5000</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7876</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ADAMS&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7788</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1987-05-23&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1100</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> emp_ht (empno, ename, job, mgr, hiredate, sal, comm, deptno)</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> empno, ename, job, mgr, hiredate, sal, comm, deptno</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">commit</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Table DEPT created.


Table DEPT_HT created.


Index DEPT_HT_DEPT_FK_I created.


Table EMP created.


Index EMP_DEPT_FK_I created.


Index EMP_EMP_FK_I created.


Table EMP_HT created.


Index EMP_HT_EMP_FK created.


Index EMP_HT_DEPT_FK created.


4 rows inserted.


4 rows inserted.


14 rows inserted.


14 rows inserted.


Commit complete.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Table DEPT created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Table DEPT_HT created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Index DEPT_HT_DEPT_FK_I created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Table EMP created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Index EMP_DEPT_FK_I created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Index EMP_EMP_FK_I created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Table EMP_HT created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Index EMP_HT_EMP_FK created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Index EMP_HT_DEPT_FK created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">4 rows inserted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">4 rows inserted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">14 rows inserted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">14 rows inserted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Commit complete.</span></span></code></pre></div>



<h2 class="wp-block-heading" id="prohibit-overlapping-periods">Prohibit Overlapping Periods</h2>



<p>Chris Saxon explains in this <a href="https://blogs.oracle.com/sql/how-to-stop-overlapping-date-ranges-in-oracle-ai-database" type="link" id="https://blogs.oracle.com/sql/how-to-stop-overlapping-date-ranges-in-oracle-ai-database" target="_blank" rel="noreferrer noopener">blog post</a> how to prevent overlapping time ranges with SQL assertions. We use a similar approach here for <code>dept_ht</code>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">3) Create assertion: no overlapping in dept_ht for vt period</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>create assertion if not exists no_overlapping_dept_ht_vt_period_as
check (
   not exists (
      select 'a department version (d1)'
        from dept_ht d1
       where exists (
              select 'an overlapping department version (d2)'
                from dept_ht d2
               where d2.deptno = d1.deptno
                 and d2.hist_id != d1.hist_id
                 and (d1.vt_start is null or d2.vt_end is null or d1.vt_start &lt; d2.vt_end)
                 and (d2.vt_start is null or d1.vt_end is null or d2.vt_start &lt; d1.vt_end)
             )
   )
) deferrable initially immediate;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> assertion </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> no_overlapping_dept_ht_vt_period_as</span></span>
<span class="line"><span style="color: #569CD6">check</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;a department version (d1)&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept_ht d1</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">              </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;an overlapping department version (d2)&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept_ht d2</span></span>
<span class="line"><span style="color: #D4D4D4">               </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> d2.deptno = d1.deptno</span></span>
<span class="line"><span style="color: #D4D4D4">                 </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> d2.hist_id != d1.hist_id</span></span>
<span class="line"><span style="color: #D4D4D4">                 </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> (d1.vt_start </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> d2.vt_end </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> d1.vt_start &lt; d2.vt_end)</span></span>
<span class="line"><span style="color: #D4D4D4">                 </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> (d2.vt_start </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> d1.vt_end </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> d2.vt_start &lt; d1.vt_end)</span></span>
<span class="line"><span style="color: #D4D4D4">             )</span></span>
<span class="line"><span style="color: #D4D4D4">   )</span></span>
<span class="line"><span style="color: #D4D4D4">) deferrable initially immediate;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Assertion NO_OVERLAPPING_DEPT_HT_VT_PERIOD_AS created.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Assertion NO_OVERLAPPING_DEPT_HT_VT_PERIOD_AS created.</span></span></code></pre></div>



<p>Let&#8217;s test the assertion. We defer all constraints to make the example easier to implement and read.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">4) Overlapping test</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>set constraints all deferred;
delete from dept_ht where deptno = 10;
insert into dept_ht (deptno, dname, loc, vt_start, vt_end)
values (10, 'ACCOUNTING', 'NEW_YORK',   null,              date '2026-04-01'),
       (10, 'ACCOUNTING', 'WINTERTHUR', date '2026-03-01', null             );
commit;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> constraints </span><span style="color: #569CD6">all</span><span style="color: #D4D4D4"> deferred;</span></span>
<span class="line"><span style="color: #569CD6">delete</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept_ht </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> deptno = </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> dept_ht (deptno, dname, loc, vt_start, vt_end)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ACCOUNTING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;NEW_YORK&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,              </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2026-04-01&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ACCOUNTING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;WINTERTHUR&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2026-03-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">             );</span></span>
<span class="line cbp-line-highlight"><span style="color: #DCDCAA">commit</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Constraints ALL succeeded.


1 row deleted.


2 rows inserted.


Error starting at line : 6 in command -
commit
Error report -
ORA-02091: transaction rolled back
ORA-08601: SQL assertion (DEMO.NO_OVERLAPPING_DEPT_HT_VT_PERIOD_AS) violated.

https://docs.oracle.com/error-help/db/ora-02091/
02091. 00000 -  "transaction rolled back"
*Cause:    Also see error 2092. If the transaction is aborted at a remote
           site then you will only see 2091; if aborted at host then you will
           see 2092 and 2091.
*Action:   Add rollback segment and retry the transaction.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Constraints ALL succeeded.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">1 row deleted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">2 rows inserted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Error starting at line : 6 in command -</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">commit</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Error report -</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">ORA-02091: transaction rolled back</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">ORA-08601: SQL assertion (DEMO.NO_OVERLAPPING_DEPT_HT_VT_PERIOD_AS) violated.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">https://docs.oracle.com/error-help/db/ora-02091/</span></span>
<span class="line"><span style="color: #D4D4D4">02091. 00000 -  &quot;transaction rolled back&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">*Cause:    Also see error 2092. If the transaction is aborted at a remote</span></span>
<span class="line"><span style="color: #D4D4D4">           site then you will only see 2091; if aborted at host then you will</span></span>
<span class="line"><span style="color: #D4D4D4">           see 2092 and 2091.</span></span>
<span class="line"><span style="color: #D4D4D4">*Action:   Add rollback segment and retry the transaction.</span></span></code></pre></div>



<p>The test fails at line 6, at the <code>commit</code> statement, exactly as expected.</p>



<p>Let&#8217;s insert two adjacent (gapless) periods.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">5) Non-overlapping test</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>set constraints all deferred;
delete from dept_ht where deptno = 10;
insert into dept_ht (deptno, dname, loc, vt_start, vt_end)
values (10, 'ACCOUNTING', 'NEW_YORK',   null,              date '2026-04-01'),
       (10, 'ACCOUNTING', 'WINTERTHUR', date '2026-04-01', null             );
commit;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> constraints </span><span style="color: #569CD6">all</span><span style="color: #D4D4D4"> deferred;</span></span>
<span class="line"><span style="color: #569CD6">delete</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept_ht </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> deptno = </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> dept_ht (deptno, dname, loc, vt_start, vt_end)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ACCOUNTING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;NEW_YORK&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,              </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2026-04-01&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ACCOUNTING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;WINTERTHUR&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2026-04-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">             );</span></span>
<span class="line cbp-line-highlight"><span style="color: #DCDCAA">commit</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Constraints ALL succeeded.


1 row deleted.


2 rows inserted.


Commit complete.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Constraints ALL succeeded.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">1 row deleted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">2 rows inserted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Commit complete.</span></span></code></pre></div>



<p>The test succeeds. So far so good.</p>



<p>However, this change leaves the redundant current-state copy in <code>dept</code> out of sync. After any change to <code>dept_ht</code>, the API should execute a statement like the following within the same transaction:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">6) Updating redundancy in DEPT from DEPT_HT</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>update dept d
   set d.dname = ht.dname,
       d.loc   = ht.loc
  from (
          select deptno, dname, loc
            from dept_ht
           where deptno = 10
           order by vt_start desc nulls first
           fetch first 1 row only
       ) ht
 where d.deptno = ht.deptno;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> dept d</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> d.dname = ht.dname,</span></span>
<span class="line"><span style="color: #D4D4D4">       d.loc   = ht.loc</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">          </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> deptno, dname, loc</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept_ht</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> deptno = </span><span style="color: #B5CEA8">10</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">order by</span><span style="color: #D4D4D4"> vt_start </span><span style="color: #569CD6">desc</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">nulls first</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">fetch</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">first</span><span style="color: #D4D4D4"> </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">row</span><span style="color: #D4D4D4"> only</span></span>
<span class="line"><span style="color: #D4D4D4">       ) ht</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> d.deptno = ht.deptno;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>1 row updated.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">1 row updated.</span></span></code></pre></div>



<p>Of course, we would need a similar SQL assertion for the period in <code>emp_ht</code>. However, this is not essential for this blog post. Therefore, we will skip it.</p>



<h2 class="wp-block-heading" id="temporal-foreign-keys">Temporal Foreign Keys</h2>



<p>Let’s now look at another typical problem in temporal data models: Temporal foreign keys.  We have two temporal foreign keys in our model:</p>



<ul class="wp-block-list">
<li><code>emp_ht_emp_mgr_fk</code></li>



<li><code>emp_ht_dept_fk</code></li>
</ul>



<p>Although the foreign key technically references a non-temporal table, the business rule is temporal: the referenced entity must be valid throughout the relevant period of the referencing row.</p>



<p>In this example, that means a manager must exist for the entire validity period of the employee version.</p>



<p>Sounds complicated? Let&#8217;s look at an example based on <code>emp_ht_emp_mgr_fk</code>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">7) Inconsistent emp_ht_emp_mgr_fk</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>update emp_ht
   set vt_start = hiredate;

select e.vt_start, e.vt_end, e.empno, e.ename, e.mgr, m.ename as mgr_name, m.hiredate as mgr_hiredate,
       e.mgr is not null and hm.empno is null as is_inconsistent
 from emp_ht e
 left join emp m
   on m.empno = e.mgr
 left join emp_ht hm
   on hm.empno = e.mgr
      and (hm.vt_start is null or (e.vt_start is not null and hm.vt_start &lt;= e.vt_start))
      and (hm.vt_end is null or e.vt_start is null or hm.vt_end > e.vt_start)
order by e.empno;

rollback;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> emp_ht</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> vt_start = hiredate;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> e.vt_start, e.vt_end, e.empno, e.ename, e.mgr, m.ename </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> mgr_name, m.hiredate </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> mgr_hiredate,</span></span>
<span class="line"><span style="color: #D4D4D4">       e.mgr </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> hm.empno </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_inconsistent</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp_ht e</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">left join</span><span style="color: #D4D4D4"> emp m</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> m.empno = e.mgr</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">left join</span><span style="color: #D4D4D4"> emp_ht hm</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> hm.empno = e.mgr</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> (hm.vt_start </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> (e.vt_start </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> hm.vt_start &lt;= e.vt_start))</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> (hm.vt_end </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> e.vt_start </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> hm.vt_end &gt; e.vt_start)</span></span>
<span class="line"><span style="color: #569CD6">order by</span><span style="color: #D4D4D4"> e.empno;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">rollback</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>14 rows updated.


VT_START   VT_END          EMPNO ENAME             MGR MGR_NAME   MGR_HIREDATE IS_INCONSISTENT
---------- ---------- ---------- ---------- ---------- ---------- ------------ ---------------
1980-12-17                  7369 SMITH            7902 FORD       1981-12-03   true           
1981-02-20                  7499 ALLEN            7698 BLAKE      1981-05-01   true           
1981-02-22                  7521 WARD             7698 BLAKE      1981-05-01   true           
1981-04-02                  7566 JONES            7839 KING       1981-11-17   true           
1981-09-28                  7654 MARTIN           7698 BLAKE      1981-05-01   false          
1981-05-01                  7698 BLAKE            7839 KING       1981-11-17   true           
1981-06-09                  7782 CLARK            7839 KING       1981-11-17   true           
1987-04-19                  7788 SCOTT            7566 JONES      1981-04-02   false          
1981-11-17                  7839 KING                                          false          
1981-09-08                  7844 TURNER           7698 BLAKE      1981-05-01   false          
1987-05-23                  7876 ADAMS            7788 SCOTT      1987-04-19   false          
1981-12-03                  7900 JAMES            7698 BLAKE      1981-05-01   false          
1981-12-03                  7902 FORD             7566 JONES      1981-04-02   false          
1982-01-23                  7934 MILLER           7782 CLARK      1981-06-09   false          

14 rows selected. 


Rollback complete.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">14 rows updated.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">VT_START   VT_END          EMPNO ENAME             MGR MGR_NAME   MGR_HIREDATE IS_INCONSISTENT</span></span>
<span class="line"><span style="color: #D4D4D4">---------- ---------- ---------- ---------- ---------- ---------- ------------ ---------------</span></span>
<span class="line"><span style="color: #D4D4D4">1980-12-17                  7369 SMITH            7902 FORD       1981-12-03   true           </span></span>
<span class="line"><span style="color: #D4D4D4">1981-02-20                  7499 ALLEN            7698 BLAKE      1981-05-01   true           </span></span>
<span class="line"><span style="color: #D4D4D4">1981-02-22                  7521 WARD             7698 BLAKE      1981-05-01   true           </span></span>
<span class="line"><span style="color: #D4D4D4">1981-04-02                  7566 JONES            7839 KING       1981-11-17   true           </span></span>
<span class="line"><span style="color: #D4D4D4">1981-09-28                  7654 MARTIN           7698 BLAKE      1981-05-01   false          </span></span>
<span class="line"><span style="color: #D4D4D4">1981-05-01                  7698 BLAKE            7839 KING       1981-11-17   true           </span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">1981-06-09                  7782 CLARK            7839 KING       1981-11-17   true           </span></span>
<span class="line"><span style="color: #D4D4D4">1987-04-19                  7788 SCOTT            7566 JONES      1981-04-02   false          </span></span>
<span class="line"><span style="color: #D4D4D4">1981-11-17                  7839 KING                                          false          </span></span>
<span class="line"><span style="color: #D4D4D4">1981-09-08                  7844 TURNER           7698 BLAKE      1981-05-01   false          </span></span>
<span class="line"><span style="color: #D4D4D4">1987-05-23                  7876 ADAMS            7788 SCOTT      1987-04-19   false          </span></span>
<span class="line"><span style="color: #D4D4D4">1981-12-03                  7900 JAMES            7698 BLAKE      1981-05-01   false          </span></span>
<span class="line"><span style="color: #D4D4D4">1981-12-03                  7902 FORD             7566 JONES      1981-04-02   false          </span></span>
<span class="line"><span style="color: #D4D4D4">1982-01-23                  7934 MILLER           7782 CLARK      1981-06-09   false          </span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">14 rows selected. </span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Rollback complete.</span></span></code></pre></div>



<p>First, we set the start of the valid period for all employees according to their hire date.</p>



<p>Then, we queried the employees and their managers at the start of their valid time period. Employees without a manager at that time are marked with <code>true</code> in the result column <code>is_inconsistent</code>.</p>



<p>CLARK, for example, was hired on 9 June 1981. His manager, KING, was hired on 17 November 1981. Consequently, CLARK had no assigned manager between 9 June 1981 and 17 November 1981. This is an invalid temporal foreign key. To resolve this issue, we must either assign CLARK a manager for this period or amend KING&#8217;s valid time period, which would likely require adjusting his hire date as well.</p>



<h2 class="wp-block-heading" id="valid-manager-at-the-start-of-a-period">Valid Manager At the Start of a Period</h2>



<p>Let&#8217;s implement the check in the previous query as an SQL assertion.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">8) Create assertion: cover_vt_start_in_emp_ht_emp_mgr_fk_as</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>create assertion if not exists cover_vt_start_in_emp_ht_emp_mgr_fk_as
check (
   not exists (
      select 'an employee version (e)'
        from emp_ht e
       where e.mgr is not null
         and not exists (
                select 'a manager version (m) covering e.vt_start'
                  from emp_ht m
                 where m.empno = e.mgr
                   and (m.vt_start is null or (e.vt_start is not null and m.vt_start &lt;= e.vt_start))
                   and (m.vt_end is null or e.vt_start is null or m.vt_end > e.vt_start)
             )
   )
) deferrable initially immediate;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> assertion </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> cover_vt_start_in_emp_ht_emp_mgr_fk_as</span></span>
<span class="line"><span style="color: #569CD6">check</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;an employee version (e)&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp_ht e</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> e.mgr </span><span style="color: #569CD6">is not null</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;a manager version (m) covering e.vt_start&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp_ht m</span></span>
<span class="line"><span style="color: #D4D4D4">                 </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> m.empno = e.mgr</span></span>
<span class="line"><span style="color: #D4D4D4">                   </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> (m.vt_start </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> (e.vt_start </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> m.vt_start &lt;= e.vt_start))</span></span>
<span class="line"><span style="color: #D4D4D4">                   </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> (m.vt_end </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> e.vt_start </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> m.vt_end &gt; e.vt_start)</span></span>
<span class="line"><span style="color: #D4D4D4">             )</span></span>
<span class="line"><span style="color: #D4D4D4">   )</span></span>
<span class="line"><span style="color: #D4D4D4">) deferrable initially immediate;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Assertion COVER_VT_START_IN_EMP_HT_EMP_MGR_FK_AS created.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Assertion COVER_VT_START_IN_EMP_HT_EMP_MGR_FK_AS created.</span></span></code></pre></div>



<p>Let&#8217;s try to create a gap in manager coverage by setting the <code>vt_start</code> to a non-null value for a manager.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">9) Test gap in manager coverage (vt_start)</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>update emp_ht
   set vt_start = hiredate
 where ename = 'KING';</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> emp_ht</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> vt_start = hiredate</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Error starting at line : 1 in command -
update emp_ht
   set vt_start = hiredate
 where ename = 'KING'
Error report -
ORA-08601: SQL assertion (DEMO.COVER_VT_START_IN_EMP_HT_EMP_MGR_FK_AS) violated.

https://docs.oracle.com/error-help/db/ora-08601/</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Error starting at line : 1 in command -</span></span>
<span class="line"><span style="color: #D4D4D4">update emp_ht</span></span>
<span class="line"><span style="color: #D4D4D4">   set vt_start = hiredate</span></span>
<span class="line"><span style="color: #D4D4D4"> where ename = &#39;KING&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">Error report -</span></span>
<span class="line"><span style="color: #D4D4D4">ORA-08601: SQL assertion (DEMO.COVER_VT_START_IN_EMP_HT_EMP_MGR_FK_AS) violated.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">https://docs.oracle.com/error-help/db/ora-08601/</span></span></code></pre></div>



<p>Good. The update fails because JONES, BLAKE and CLARK would have no manager assigned at the beginning of their valid time period. </p>



<p>Now let&#8217;s try to set <code>vt_start</code> for an employee who is not a manager.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">10) Test no gap in manager coverage (vt_start)</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>update emp_ht
   set vt_start = hiredate
 where ename = 'ADAMS';
rollback;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> emp_ht</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> vt_start = hiredate</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;ADAMS&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #DCDCAA">rollback</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>1 row updated.


Rollback complete.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">1 row updated.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Rollback complete.</span></span></code></pre></div>



<p>The update succeeded because ADAMS is not a manager and, therefore, no gap in manager coverage was created.</p>



<h2 class="wp-block-heading" id="valid-manager-at-the-end-of-a-period">Valid Manager At the End of a Period</h2>



<p>The previous SQL assertion ensures that manager coverage exists at the start of a period. However, to guarantee temporal data integrity for the entire period, we need an additional SQL assertion.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">11) Create assertion: cover_vt_end_in_emp_ht_emp_mgr_fk_as</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>create assertion if not exists cover_vt_end_in_emp_ht_emp_mgr_fk_as
check (
   not exists (
      select 'an employee version (e)'
        from emp_ht e
       where e.mgr is not null
         and exists (
                select 'a manager version (m) ending before e.vt_end'
                  from emp_ht m
                 where m.empno = e.mgr
                   and m.vt_end is not null
                   and (e.vt_start is null or m.vt_end > e.vt_start)
                   and (e.vt_end is null or m.vt_end &lt; e.vt_end)
                   and not exists (
                          select 'a manager version (m2) covering the m.vt_end'
                            from emp_ht m2
                           where m2.empno = e.mgr
                             and m2.hist_id != m.hist_id
                             and (m2.vt_start is null or m2.vt_start &lt;= m.vt_end)
                             and (m2.vt_end is null or m2.vt_end > m.vt_end)
                       )
             )
   )
) deferrable initially immediate;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> assertion </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> cover_vt_end_in_emp_ht_emp_mgr_fk_as</span></span>
<span class="line"><span style="color: #569CD6">check</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;an employee version (e)&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp_ht e</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> e.mgr </span><span style="color: #569CD6">is not null</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">                </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;a manager version (m) ending before e.vt_end&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp_ht m</span></span>
<span class="line"><span style="color: #D4D4D4">                 </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> m.empno = e.mgr</span></span>
<span class="line"><span style="color: #D4D4D4">                   </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> m.vt_end </span><span style="color: #569CD6">is not null</span></span>
<span class="line"><span style="color: #D4D4D4">                   </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> (e.vt_start </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> m.vt_end &gt; e.vt_start)</span></span>
<span class="line"><span style="color: #D4D4D4">                   </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> (e.vt_end </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> m.vt_end &lt; e.vt_end)</span></span>
<span class="line"><span style="color: #D4D4D4">                   </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">                          </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;a manager version (m2) covering the m.vt_end&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                            </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp_ht m2</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> m2.empno = e.mgr</span></span>
<span class="line"><span style="color: #D4D4D4">                             </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> m2.hist_id != m.hist_id</span></span>
<span class="line"><span style="color: #D4D4D4">                             </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> (m2.vt_start </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> m2.vt_start &lt;= m.vt_end)</span></span>
<span class="line"><span style="color: #D4D4D4">                             </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> (m2.vt_end </span><span style="color: #569CD6">is null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> m2.vt_end &gt; m.vt_end)</span></span>
<span class="line"><span style="color: #D4D4D4">                       )</span></span>
<span class="line"><span style="color: #D4D4D4">             )</span></span>
<span class="line"><span style="color: #D4D4D4">   )</span></span>
<span class="line"><span style="color: #D4D4D4">) deferrable initially immediate;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Assertion COVER_VT_END_IN_EMP_HT_EMP_MGR_FK_AS created.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Assertion COVER_VT_END_IN_EMP_HT_EMP_MGR_FK_AS created.</span></span></code></pre></div>



<p>Let&#8217;s try now to set the <code>vt_end</code> to a non-null value of a manager.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">12) Test gap in manager coverage (vt_end)</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>update emp_ht
   set vt_end = date '2100-01-01'
 where ename = 'KING';</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> emp_ht</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> vt_end = </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2100-01-01&#39;</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Error starting at line : 1 in command -
update emp_ht
   set vt_end = date '2100-01-01'
 where ename = 'KING'
Error at Command Line : 1 Column : 8
Error report -
SQL Error: ORA-08601: SQL assertion (DEMO.COVER_VT_END_IN_EMP_HT_EMP_MGR_FK_AS) violated.

https://docs.oracle.com/error-help/db/ora-08601/</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Error starting at line : 1 in command -</span></span>
<span class="line"><span style="color: #D4D4D4">update emp_ht</span></span>
<span class="line"><span style="color: #D4D4D4">   set vt_end = date &#39;2100-01-01&#39;</span></span>
<span class="line"><span style="color: #D4D4D4"> where ename = &#39;KING&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">Error at Command Line : 1 Column : 8</span></span>
<span class="line"><span style="color: #D4D4D4">Error report -</span></span>
<span class="line"><span style="color: #D4D4D4">SQL Error: ORA-08601: SQL assertion (DEMO.COVER_VT_END_IN_EMP_HT_EMP_MGR_FK_AS) violated.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">https://docs.oracle.com/error-help/db/ora-08601/</span></span></code></pre></div>



<p>Good. The update failed because JONES, BLAKE and CLARK would have had no manager from 1 January 2100 until the end of time.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">13) Test no gap in manager coverage (vt_end)</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>update emp_ht
   set vt_end = date '2100-01-01'
  where ename = 'ADAMS';
rollback;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> emp_ht</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> vt_end = </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2100-01-01&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;ADAMS&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #DCDCAA">rollback</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>1 row updated.


Rollback complete.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">1 row updated.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Rollback complete.</span></span></code></pre></div>



<p>The update succeeded because ADAMS is not a manager and, therefore, no gap in manager coverage was created.</p>



<p>Well, those were just simple test cases. What would happen if we left a one-day gap between versions of the history? Would this be detected?</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">14) Test gap in manager coverage of multiple versions</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>set constraints all deferred;
delete from emp_ht where ename = 'KING';
insert into emp_ht (vt_start, vt_end, empno, ename, job, hiredate, sal, deptno)
values (null,              date '1981-11-17', 7839, 'KING', 'PRESIDENT', date '1981-11-17', 2000, 10),
       (date '1981-11-17', date '2100-01-01', 7839, 'KING', 'PRESIDENT', date '1981-11-17', 4500, 10),
       (date '2100-01-02', date '2200-01-01', 7839, 'KING', 'PRESIDENT', date '1981-11-17', 4600, 10),
       (date '2200-01-01', null             , 7839, 'KING', 'PRESIDENT', date '1981-11-17', 5000, 10);
commit;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> constraints </span><span style="color: #569CD6">all</span><span style="color: #D4D4D4"> deferred;</span></span>
<span class="line"><span style="color: #569CD6">delete</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp_ht </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> emp_ht (vt_start, vt_end, empno, ename, job, hiredate, sal, deptno)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,              </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;PRESIDENT&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2000</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2100-01-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;PRESIDENT&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">4500</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">       (</span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2100-01-02&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2200-01-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;PRESIDENT&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">4600</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2200-01-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">             , </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;PRESIDENT&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">5000</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">);</span></span>
<span class="line cbp-line-highlight"><span style="color: #DCDCAA">commit</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Constraints ALL succeeded.


1 row deleted.


4 rows inserted.


Error starting at line : 8 in command -
commit
Error report -
ORA-02091: transaction rolled back
ORA-08601: SQL assertion (DEMO.COVER_VT_END_IN_EMP_HT_EMP_MGR_FK_AS) violated.

https://docs.oracle.com/error-help/db/ora-02091/
02091. 00000 -  "transaction rolled back"
*Cause:    Also see error 2092. If the transaction is aborted at a remote
           site then you will only see 2091; if aborted at host then you will
           see 2092 and 2091.
*Action:   Add rollback segment and retry the transaction.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Constraints ALL succeeded.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">1 row deleted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">4 rows inserted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Error starting at line : 8 in command -</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">commit</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Error report -</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">ORA-02091: transaction rolled back</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">ORA-08601: SQL assertion (DEMO.COVER_VT_END_IN_EMP_HT_EMP_MGR_FK_AS) violated.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">https://docs.oracle.com/error-help/db/ora-02091/</span></span>
<span class="line"><span style="color: #D4D4D4">02091. 00000 -  &quot;transaction rolled back&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">*Cause:    Also see error 2092. If the transaction is aborted at a remote</span></span>
<span class="line"><span style="color: #D4D4D4">           site then you will only see 2091; if aborted at host then you will</span></span>
<span class="line"><span style="color: #D4D4D4">           see 2092 and 2091.</span></span>
<span class="line"><span style="color: #D4D4D4">*Action:   Add rollback segment and retry the transaction.</span></span></code></pre></div>



<p>Yes! The commit statement failed because no version covered 1 January 2100.</p>



<p>When we fix the date on line 6, the transaction should succeed. Let&#8217;s try that.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">15) Test no gap in manager coverage of multiple versions</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>set constraints all deferred;
delete from emp_ht where ename = 'KING';
insert into emp_ht (vt_start, vt_end, empno, ename, job, hiredate, sal, deptno)
values (null,              date '1981-11-17', 7839, 'KING', 'PRESIDENT', date '1981-11-17', 2000, 10),
       (date '1981-11-17', date '2100-01-01', 7839, 'KING', 'PRESIDENT', date '1981-11-17', 4500, 10),
       (date '2100-01-01', date '2200-01-01', 7839, 'KING', 'PRESIDENT', date '1981-11-17', 4600, 10),
       (date '2200-01-01', null             , 7839, 'KING', 'PRESIDENT', date '1981-11-17', 5000, 10);
commit;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> constraints </span><span style="color: #569CD6">all</span><span style="color: #D4D4D4"> deferred;</span></span>
<span class="line"><span style="color: #569CD6">delete</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp_ht </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> emp_ht (vt_start, vt_end, empno, ename, job, hiredate, sal, deptno)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,              </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;PRESIDENT&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2000</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2100-01-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;PRESIDENT&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">4500</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">       (</span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2100-01-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2200-01-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;PRESIDENT&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">4600</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2200-01-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">             , </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;PRESIDENT&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">5000</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #DCDCAA">commit</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Constraints ALL succeeded.


1 row deleted.


4 rows inserted.


Commit complete.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Constraints ALL succeeded.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">1 row deleted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">4 rows inserted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Commit complete.</span></span></code></pre></div>



<p>Perfect. This works.</p>



<p>We have successfully enforced temporal referential integrity for the manager relationship using SQL assertions.</p>



<h2 class="wp-block-heading" id="summary">Summary</h2>



<p>In this blog post, we created the SQL assertion <a href="#prohibit-overlapping-periods" type="internal" id="#prohibit-overlapping-periods" rel="nofollow">no_overlapping_dept_ht_vt_period_as</a> to ensure validity periods in the table <code>dept_ht</code> do not overlap.</p>



<p>We enforced temporal referential data integrity for the foreign key <code>emp_ht_emp_mgr_fk</code> using the SQL assertions <a href="#valid-manager-at-the-start-of-a-period" type="internal" id="#valid-manager-at-the-start-of-a-period" rel="nofollow">cover_vt_start_in_emp_ht_emp_mgr_fk_as</a> and <a href="#valid-manager-at-the-end-of-a-period" type="internal" id="#valid-manager-at-the-end-of-a-period" rel="nofollow">cover_vt_end_in_emp_ht_emp_mgr_fk_as</a>. This means that an employee always has a valid manager assigned throughout their validity period. Any gaps in manager coverage are detected correctly.</p>



<p>Adapting these SQL assertions for use in templates for temporal API generators should not be too difficult. All necessary information is in the Oracle data dictionary. With some additional metadata, we can generate additional SQL assertions for related, optional topics such as:</p>



<ul class="wp-block-list">
<li>Enforce adjacent periods (no gaps)</li>



<li>Disallow adjacent periods with the same business values (enforce merge of periods)</li>



<li>Disallow different business keys across periods (enforce business key updates on all versions)</li>



<li>Disallow new versions for changes to non-versioned columns only (enforce update of all versions instead)</li>
</ul>



<p>Although SQL assertions make it easier to enforce the integrity of temporal data, the use of temporal tables measurably increases complexity. Therefore, only use temporal tables if you really need to. Document which columns require temporal handling and explain why. </p>



<p>In any case, the integration of SQL assertions into Oracle AI Database makes the use of temporal tables much easier.</p>
<p>The post <a href="https://www.salvis.com/blog/2026/03/09/using-sql-assertions-to-enforce-temporal-data-integrity/">Using SQL Assertions to Enforce Temporal Data Integrity</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.salvis.com/blog/2026/03/09/using-sql-assertions-to-enforce-temporal-data-integrity/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Enforcing Acyclic Hierarchies With SQL Assertions</title>
		<link>https://www.salvis.com/blog/2026/02/23/enforcing-acyclic-hierarchies-with-sql-assertions/</link>
					<comments>https://www.salvis.com/blog/2026/02/23/enforcing-acyclic-hierarchies-with-sql-assertions/#respond</comments>
		
		<dc:creator><![CDATA[Philipp Salvisberg]]></dc:creator>
		<pubDate>Mon, 23 Feb 2026 16:24:15 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle 26ai]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Assertions]]></category>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=15957</guid>

					<description><![CDATA[<p>Introduction Referential integrity constraints have been available since version 7 of the Oracle Database. While these constraints ensure that referenced rows exist, they cannot express more complex integrity rules that span multiple rows or tables. Check constraints are similarly limited, as they can only validate conditions on the columns of a single<span class="excerpt-hellip"> […]</span></p>
<p>The post <a href="https://www.salvis.com/blog/2026/02/23/enforcing-acyclic-hierarchies-with-sql-assertions/">Enforcing Acyclic Hierarchies With SQL Assertions</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p></p>
</blockquote>



<h2 class="wp-block-heading" id="introduction">Introduction</h2>



<p>Referential integrity constraints have been available since version 7 of the Oracle Database. While these constraints ensure that referenced rows exist, they cannot express more complex integrity rules that span multiple rows or tables. Check constraints are similarly limited, as they can only validate conditions on the columns of a single row.</p>



<p>The latest version of the Oracle AI Database (23.26.1) introduced SQL Assertions, enabling us to define cross-row and cross-table checks declaratively.</p>



<p>SQL Assertions support a wide range of use cases where data must satisfy global consistency rules. One particularly interesting example is ensuring that hierarchical structures remain free of cycles.</p>



<p>In this blog post, I will demonstrate how SQL Assertions can detect and prevent cycles in hierarchical data structures.</p>



<h2 class="wp-block-heading" id="setup">Setup</h2>



<p>For the examples in this blog post, I used an Oracle AI Database 26ai Enterprise Edition Release 23.26.1.0.0.</p>



<p>Connected as <code>SYS</code> I ran the following script to create the user <code>DEMO</code> with the necessary privileges.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">1) DEMO user</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>create user demo identified by demo
   default tablespace users
   temporary tablespace temp
   quota unlimited on users;

grant create session, create table, create assertion to demo;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">user</span><span style="color: #D4D4D4"> demo identified by demo</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">default</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">tablespace</span><span style="color: #D4D4D4"> users</span></span>
<span class="line"><span style="color: #D4D4D4">   temporary </span><span style="color: #569CD6">tablespace</span><span style="color: #D4D4D4"> temp</span></span>
<span class="line"><span style="color: #D4D4D4">   quota unlimited </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> users;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">grant</span><span style="color: #D4D4D4"> create session, create </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4">, create assertion to demo;</span></span></code></pre></div>



<p>Connected as <code>DEMO</code> I ran the following script to create the famous tables <code>DEPT</code> and <code>EMP</code> with initial data:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">2) Install DEPT/EMP example</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>create table dept (
   deptno number(2, 0)      not null constraint dept_pk primary key,
   dname  varchar2(14 char) not null,
   loc    varchar2(13 char) not null
);

create table emp (
   empno    number(4, 0)      not null  constraint emp_pk primary key,
   ename    varchar2(10 char) not null,
   job      varchar2(9 char)  not null,
   mgr      number(4, 0)                constraint emp_mgr_fk references emp,
   hiredate date              not null,
   sal      number(7, 2)      not null,
   comm     number(7, 2),
   deptno   number(2, 0)      not null  constraint emp_deptno_fk references dept
);

create index emp_deptno_fk_i on emp(deptno);
create index emp_mgr_fk_i on emp(mgr);

insert into dept (deptno, dname, loc)
values (10, 'ACCOUNTING', 'NEW YORK'),
       (20, 'RESEARCH',   'DALLAS'),
       (30, 'SALES',      'CHICAGO'),
       (40, 'OPERATIONS', 'BOSTON');

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7566, 'JONES',  'MANAGER',   7839, date '1981-04-02', 2975, null, 20),
       (7698, 'BLAKE',  'MANAGER',   7839, date '1981-05-01', 2850, null, 30),
       (7782, 'CLARK',  'MANAGER',   7839, date '1981-06-09', 2450, null, 10),
       (7788, 'SCOTT',  'ANALYST',   7566, date '1987-04-19', 3000, null, 20),
       (7902, 'FORD',   'ANALYST',   7566, date '1981-12-03', 3000, null, 20),
       (7499, 'ALLEN',  'SALESMAN',  7698, date '1981-02-20', 1600,  300, 30),
       (7521, 'WARD',   'SALESMAN',  7698, date '1981-02-22', 1250,  500, 30),
       (7654, 'MARTIN', 'SALESMAN',  7698, date '1981-09-28', 1250, 1400, 30),
       (7844, 'TURNER', 'SALESMAN',  7698, date '1981-09-08', 1500,    0, 30),
       (7900, 'JAMES',  'CLERK',     7698, date '1981-12-03',  950, null, 30),
       (7934, 'MILLER', 'CLERK',     7782, date '1982-01-23', 1300, null, 10),
       (7369, 'SMITH',  'CLERK',     7902, date '1980-12-17',  800, null, 20),
       (7839, 'KING',   'PRESIDENT', null, date '1981-11-17', 5000, null, 10),
       (7876, 'ADAMS',  'CLERK',     7788, date '1987-05-23', 1100, null, 20);
commit;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> dept (</span></span>
<span class="line"><span style="color: #D4D4D4">   deptno </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> dept_pk </span><span style="color: #569CD6">primary key</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   dname  </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">14</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   loc    </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">13</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span></span>
<span class="line"><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> emp (</span></span>
<span class="line"><span style="color: #D4D4D4">   empno    </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_pk </span><span style="color: #569CD6">primary key</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   ename    </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   job      </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">9</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">)  </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   mgr      </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)                </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_mgr_fk </span><span style="color: #569CD6">references</span><span style="color: #D4D4D4"> emp,</span></span>
<span class="line"><span style="color: #D4D4D4">   hiredate </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4">              </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   sal      </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">7</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   comm     </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">7</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">   deptno   </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_deptno_fk </span><span style="color: #569CD6">references</span><span style="color: #D4D4D4"> dept</span></span>
<span class="line"><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> index emp_deptno_fk_i </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> emp(deptno);</span></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> index emp_mgr_fk_i </span><span style="color: #569CD6">on</span><span style="color: #D4D4D4"> emp(mgr);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> dept (deptno, dname, loc)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ACCOUNTING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;NEW YORK&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;RESEARCH&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;DALLAS&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SALES&#39;</span><span style="color: #D4D4D4">,      </span><span style="color: #CE9178">&#39;CHICAGO&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">40</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;OPERATIONS&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;BOSTON&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">7566</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;JONES&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;MANAGER&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-04-02&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2975</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;BLAKE&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;MANAGER&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-05-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2850</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7782</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;CLARK&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;MANAGER&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-06-09&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2450</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7788</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SCOTT&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;ANALYST&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7566</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1987-04-19&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">3000</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7902</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;FORD&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;ANALYST&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7566</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-12-03&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">3000</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7499</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ALLEN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-02-20&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1600</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">300</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7521</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;WARD&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-02-22&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1250</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">500</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7654</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;MARTIN&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-09-28&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1250</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1400</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7844</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;TURNER&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-09-08&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1500</span><span style="color: #D4D4D4">,    </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7900</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;JAMES&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-12-03&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">950</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7934</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;MILLER&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7782</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1982-01-23&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1300</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7369</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SMITH&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7902</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1980-12-17&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">800</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;PRESIDENT&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">5000</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7876</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ADAMS&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7788</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1987-05-23&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1100</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #DCDCAA">commit</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<h2 class="wp-block-heading" id="hierarchical-sql-query">Hierarchical SQL Query</h2>



<p>Let&#8217;s look at the acyclic data first.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">3) Hierarchical Query</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>column ename format a15
 select lpad(' ', 2 * (level - 1)) || ename as ename,
        empno,
        mgr
   from emp
connect by prior empno = mgr
  start with ename = 'KING';</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> ename format a15</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">lpad</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39; &#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> * (</span><span style="color: #569CD6">level</span><span style="color: #D4D4D4"> - </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">)) || ename </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> ename,</span></span>
<span class="line"><span style="color: #D4D4D4">        empno,</span></span>
<span class="line"><span style="color: #D4D4D4">        mgr</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp</span></span>
<span class="line"><span style="color: #569CD6">connect by prior</span><span style="color: #D4D4D4"> empno = mgr</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">start with</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>ENAME                EMPNO        MGR
--------------- ---------- ----------
KING                  7839           
  JONES               7566       7839
    SCOTT             7788       7566
      ADAMS           7876       7788
    FORD              7902       7566
      SMITH           7369       7902
  BLAKE               7698       7839
    ALLEN             7499       7698
    WARD              7521       7698
    MARTIN            7654       7698
    TURNER            7844       7698
    JAMES             7900       7698
  CLARK               7782       7839
    MILLER            7934       7782

14 rows selected. </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">ENAME                EMPNO        MGR</span></span>
<span class="line"><span style="color: #D4D4D4">--------------- ---------- ----------</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">KING                  7839           </span></span>
<span class="line"><span style="color: #D4D4D4">  JONES               7566       7839</span></span>
<span class="line"><span style="color: #D4D4D4">    SCOTT             7788       7566</span></span>
<span class="line"><span style="color: #D4D4D4">      ADAMS           7876       7788</span></span>
<span class="line"><span style="color: #D4D4D4">    FORD              7902       7566</span></span>
<span class="line"><span style="color: #D4D4D4">      SMITH           7369       7902</span></span>
<span class="line"><span style="color: #D4D4D4">  BLAKE               7698       7839</span></span>
<span class="line"><span style="color: #D4D4D4">    ALLEN             7499       7698</span></span>
<span class="line"><span style="color: #D4D4D4">    WARD              7521       7698</span></span>
<span class="line"><span style="color: #D4D4D4">    MARTIN            7654       7698</span></span>
<span class="line"><span style="color: #D4D4D4">    TURNER            7844       7698</span></span>
<span class="line"><span style="color: #D4D4D4">    JAMES             7900       7698</span></span>
<span class="line"><span style="color: #D4D4D4">  CLARK               7782       7839</span></span>
<span class="line"><span style="color: #D4D4D4">    MILLER            7934       7782</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">14 rows selected. </span></span></code></pre></div>



<h2 class="wp-block-heading" id="detecting-cycles-via-sql-query">Detecting Cycles Via SQL Query</h2>



<p>We see that <code>KING</code> is the only employee without a manager. With the next update, we create a cycle by making <code>SCOTT</code> the manager of <code>KING</code>:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">4) Create Cycle</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>update emp 
   set mgr = 7788 
 where empno = 7839;
commit;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> emp </span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> mgr = </span><span style="color: #B5CEA8">7788</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> empno = </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #DCDCAA">commit</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<p>When we now re-run the previous query, we get an <code>ORA-01436: CONNECT BY loop in user data</code> error.</p>



<p>Of course, we can work around it by adding a <code>NOCYCLE</code> parameter to produce a result:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">5) NOCYCLE Hierarchical Query</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly> select lpad(' ', 2 * (level - 1)) || ename as ename,
        empno,
        mgr
   from emp
connect by nocycle prior empno = mgr
  start with ename = 'KING'; </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">lpad</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&#39; &#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4"> * (</span><span style="color: #569CD6">level</span><span style="color: #D4D4D4"> - </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">)) || ename </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> ename,</span></span>
<span class="line"><span style="color: #D4D4D4">        empno,</span></span>
<span class="line"><span style="color: #D4D4D4">        mgr</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp</span></span>
<span class="line cbp-line-highlight"><span style="color: #569CD6">connect by nocycle prior</span><span style="color: #D4D4D4"> empno = mgr</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">start with</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">; </span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>ENAME                EMPNO        MGR
--------------- ---------- ----------
KING                  7839       7788
  JONES               7566       7839
    SCOTT             7788       7566
      ADAMS           7876       7788
    FORD              7902       7566
      SMITH           7369       7902
  BLAKE               7698       7839
    ALLEN             7499       7698
    WARD              7521       7698
    MARTIN            7654       7698
    TURNER            7844       7698
    JAMES             7900       7698
  CLARK               7782       7839
    MILLER            7934       7782

14 rows selected. </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">ENAME                EMPNO        MGR</span></span>
<span class="line"><span style="color: #D4D4D4">--------------- ---------- ----------</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">KING                  7839       7788</span></span>
<span class="line"><span style="color: #D4D4D4">  JONES               7566       7839</span></span>
<span class="line"><span style="color: #D4D4D4">    SCOTT             7788       7566</span></span>
<span class="line"><span style="color: #D4D4D4">      ADAMS           7876       7788</span></span>
<span class="line"><span style="color: #D4D4D4">    FORD              7902       7566</span></span>
<span class="line"><span style="color: #D4D4D4">      SMITH           7369       7902</span></span>
<span class="line"><span style="color: #D4D4D4">  BLAKE               7698       7839</span></span>
<span class="line"><span style="color: #D4D4D4">    ALLEN             7499       7698</span></span>
<span class="line"><span style="color: #D4D4D4">    WARD              7521       7698</span></span>
<span class="line"><span style="color: #D4D4D4">    MARTIN            7654       7698</span></span>
<span class="line"><span style="color: #D4D4D4">    TURNER            7844       7698</span></span>
<span class="line"><span style="color: #D4D4D4">    JAMES             7900       7698</span></span>
<span class="line"><span style="color: #D4D4D4">  CLARK               7782       7839</span></span>
<span class="line"><span style="color: #D4D4D4">    MILLER            7934       7782</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">14 rows selected. </span></span></code></pre></div>



<p>However, I want a query that shows the reason for the cycle, rather than ignoring it. Something like this:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">6) Detecting Cycles</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>column ename_path format a20
select *
  from (
          select e.ename,
                 e.empno,
                 e.mgr,
                 connect_by_iscycle as is_cycle,
                 sys_connect_by_path(e.ename, '/') as ename_path
            from emp e
         connect by nocycle prior e.empno = e.mgr
           start with e.mgr is not null
       )
 where is_cycle = 1;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> ename_path format a20</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> *</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">          </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> e.ename,</span></span>
<span class="line"><span style="color: #D4D4D4">                 e.empno,</span></span>
<span class="line"><span style="color: #D4D4D4">                 e.mgr,</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                 connect_by_iscycle </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_cycle,</span></span>
<span class="line"><span style="color: #D4D4D4">                 </span><span style="color: #DCDCAA">sys_connect_by_path</span><span style="color: #D4D4D4">(e.ename, </span><span style="color: #CE9178">&#39;/&#39;</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> ename_path</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp e</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">connect by nocycle prior</span><span style="color: #D4D4D4"> e.empno = e.mgr</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">start with</span><span style="color: #D4D4D4"> e.mgr </span><span style="color: #569CD6">is not null</span></span>
<span class="line"><span style="color: #D4D4D4">       )</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> is_cycle = </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>ENAME                EMPNO        MGR   IS_CYCLE ENAME_PATH          
--------------- ---------- ---------- ---------- --------------------
JONES                 7566       7839          1 /SCOTT/KING/JONES   
SCOTT                 7788       7566          1 /KING/JONES/SCOTT   
KING                  7839       7788          1 /JONES/SCOTT/KING </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">ENAME                EMPNO        MGR   IS_CYCLE ENAME_PATH          </span></span>
<span class="line"><span style="color: #D4D4D4">--------------- ---------- ---------- ---------- --------------------</span></span>
<span class="line"><span style="color: #D4D4D4">JONES                 7566       7839          1 /SCOTT/KING/JONES   </span></span>
<span class="line"><span style="color: #D4D4D4">SCOTT                 7788       7566          1 /KING/JONES/SCOTT   </span></span>
<span class="line"><span style="color: #D4D4D4">KING                  7839       7788          1 /JONES/SCOTT/KING </span></span></code></pre></div>



<h2 class="wp-block-heading" id="sql-assertion-using-connect-by">SQL Assertion Using Connect By</h2>



<p>According to the <a href="https://docs.oracle.com/en/database/oracle/oracle-database/26/sqlrf/create-assertion.html#GUID-9FB74CAA-0CAD-4FE6-B873-1B3877CB8AB9__GUID-70274BBE-EE5C-4471-B88A-A35DE7A9F9B1" type="link" id="https://docs.oracle.com/en/database/oracle/oracle-database/26/sqlrf/create-assertion.html#GUID-9FB74CAA-0CAD-4FE6-B873-1B3877CB8AB9__GUID-70274BBE-EE5C-4471-B88A-A35DE7A9F9B1" target="_blank" rel="noreferrer noopener">CREATE ASSERTION</a> syntax diagram, we should be able to use the previous query within the SQL Assertion as follows:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">7) Create assertion with CONNECT_BY</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>create assertion if not exists emp_mgr_fk_no_cycle_as
   check (
      not exists (
         select 'cycle detected'
           from (
                   select connect_by_iscycle as is_cycle
                     from emp e
                  connect by nocycle prior e.empno = e.mgr
                    start with e.mgr is not null
                )
          where is_cycle = 1
      )
   );</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> assertion </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> emp_mgr_fk_no_cycle_as</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">check</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;cycle detected&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">                   </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> connect_by_iscycle </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_cycle</span></span>
<span class="line"><span style="color: #D4D4D4">                     </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp e</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #569CD6">connect by nocycle prior</span><span style="color: #D4D4D4"> e.empno = e.mgr</span></span>
<span class="line"><span style="color: #D4D4D4">                    </span><span style="color: #569CD6">start with</span><span style="color: #D4D4D4"> e.mgr </span><span style="color: #569CD6">is not null</span></span>
<span class="line"><span style="color: #D4D4D4">                )</span></span>
<span class="line"><span style="color: #D4D4D4">          </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> is_cycle = </span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #D4D4D4">      )</span></span>
<span class="line"><span style="color: #D4D4D4">   );</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>ORA-08689: CREATE ASSERTION failed
ORA-08677: Certain SQL functions are not supported.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">ORA-08689: CREATE ASSERTION failed</span></span>
<span class="line"><span style="color: #D4D4D4">ORA-08677: Certain SQL functions are not supported.</span></span></code></pre></div>



<p>Unfortunately, this does not work. We get a generic error. The documentation for <a href="https://docs.oracle.com/en/error-help/db/ora-08677/?r=26ai" target="_blank" rel="noreferrer noopener">ORA-08677: Certain SQL functions are not supported.</a> does not reveal the culprit either. However, there is a rather long list of limitations listed at the end of <a href="https://docs.oracle.com/en/database/oracle/oracle-database/26/sqlrf/create-assertion.html#GUID-9FB74CAA-0CAD-4FE6-B873-1B3877CB8AB9__GUID-26F60086-F19C-446E-B979-352CD0E8D50D" type="link" id="https://docs.oracle.com/en/database/oracle/oracle-database/26/sqlrf/create-assertion.html#GUID-9FB74CAA-0CAD-4FE6-B873-1B3877CB8AB9__GUID-26F60086-F19C-446E-B979-352CD0E8D50D" target="_blank" rel="noreferrer noopener">this section</a> for the CREATE ASSERTION statement in the SQL Language Reference.</p>



<p>After some experimentation, I have concluded that as of version 23.26.1, hierarchical queries are not supported in SQL assertions and that this limitation is not explicitly documented. <em>(Updated on 2026-03-30: The SQL Language Reference now lists &#8220;Hierarchical queries&#8221; as a feature that cannot be used with assertions.) </em></p>



<h2 class="wp-block-heading" id="sql-assertion-using-joins">SQL Assertion Using Joins</h2>



<p>It would be useful to be able to use hierarchical queries to identify cycles within hierarchies. </p>



<p>However, we can tighten up the business requirements. From</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>&#8220;Cycles are not allowed for the <code>emp_mgr_fk</code> relationship.&#8221; </p>
</blockquote>



<p>to </p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>&#8220;The number of levels in the <code>emp_mgr_fk</code> relationship is limited to 5.&#8221;</p>
</blockquote>



<p>Now we can rewrite the <code>CREATE ASSERTION</code> statement like this:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">8) Create assertion with joins</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>create assertion if not exists emp_mgr_fk_no_cycle_as
   check (
      not exists (
         select '6 Levels detected, cycle assumed'
           from emp e1, emp e2, emp e3, emp e4, emp e5, emp e6
          where e1.mgr is not null and e1.mgr = e2.empno
            and e2.mgr is not null and e2.mgr = e3.empno
            and e3.mgr is not null and e3.mgr = e4.empno
            and e4.mgr is not null and e4.mgr = e5.empno
            and e5.mgr is not null and e5.mgr = e6.empno
      )
   );</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> assertion </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> emp_mgr_fk_no_cycle_as</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">check</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;6 Levels detected, cycle assumed&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp e1, emp e2, emp e3, emp e4, emp e5, emp e6</span></span>
<span class="line"><span style="color: #D4D4D4">          </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> e1.mgr </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e1.mgr = e2.empno</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e2.mgr </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e2.mgr = e3.empno</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e3.mgr </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e3.mgr = e4.empno</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e4.mgr </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e4.mgr = e5.empno</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e5.mgr </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e5.mgr = e6.empno</span></span>
<span class="line"><span style="color: #D4D4D4">      )</span></span>
<span class="line"><span style="color: #D4D4D4">   );</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>ORA-08689: CREATE ASSERTION failed
ORA-08601: SQL assertion (DEMO.EMP_MGR_FK_NO_CYCLE_AS) violated.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">ORA-08689: CREATE ASSERTION failed</span></span>
<span class="line"><span style="color: #D4D4D4">ORA-08601: SQL assertion (DEMO.EMP_MGR_FK_NO_CYCLE_AS) violated.</span></span></code></pre></div>



<p>This error is expected since we have a cycle in our data. Let&#8217;s fix that.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">9) Remove Cycle</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>update emp 
   set mgr = null 
 where ename = 'KING';
commit;</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> emp </span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> mgr = </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #DCDCAA">commit</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<p>Let&#8217;s try to create the SQL Assertion again.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">10) Create assertion with joins (try again)</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>create assertion if not exists emp_mgr_fk_no_cycle_as
   check (
      not exists (
         select '6 Levels detected, cycle assumed'
           from emp e1, emp e2, emp e3, emp e4, emp e5, emp e6
          where e1.mgr is not null and e1.mgr = e2.empno
            and e2.mgr is not null and e2.mgr = e3.empno
            and e3.mgr is not null and e3.mgr = e4.empno
            and e4.mgr is not null and e4.mgr = e5.empno
            and e5.mgr is not null and e5.mgr = e6.empno
      )
   );</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> assertion </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> emp_mgr_fk_no_cycle_as</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">check</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;6 Levels detected, cycle assumed&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">           </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp e1, emp e2, emp e3, emp e4, emp e5, emp e6</span></span>
<span class="line"><span style="color: #D4D4D4">          </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> e1.mgr </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e1.mgr = e2.empno</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e2.mgr </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e2.mgr = e3.empno</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e3.mgr </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e3.mgr = e4.empno</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e4.mgr </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e4.mgr = e5.empno</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e5.mgr </span><span style="color: #569CD6">is not null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">and</span><span style="color: #D4D4D4"> e5.mgr = e6.empno</span></span>
<span class="line"><span style="color: #D4D4D4">      )</span></span>
<span class="line"><span style="color: #D4D4D4">   );</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>Assertion EMP_MGR_FK_NO_CYCLE_AS created.</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Assertion EMP_MGR_FK_NO_CYCLE_AS created.</span></span></code></pre></div>



<p>Success! </p>



<p>This approach enforces acyclic hierarchies and additionally limits the number of hierarchical levels to 5.</p>



<p>For real-life applications, you may wish to increase the number of levels to more than 5. In any case, you should be able to decide on a suitable maximum number of levels. The number of joins will match the number of levels. The code for that is boring but not too complicated.</p>



<h2 class="wp-block-heading" id="test-cases">Test Cases</h2>



<p>Let&#8217;s run some tests to verify if the SQL Assertion behaves as expected.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">11) Test cases</span><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>set echo on
-- fails (cycle)
update emp
   set mgr = (select empno from emp where ename = 'SCOTT')
 where ename = 'KING';

-- fails (cycle)
update emp
   set mgr = (select empno from emp where ename = 'SMITH')
 where ename = 'JONES';

-- succeeds
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (1000, 'LEVEL5', 'TESTER', (select empno from emp where ename = 'ADAMS'), date '2026-02-01', 1000, null, 10);

-- fails (6 levels, no cycle)
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (1001, 'LEVEL6', 'TESTER', (select empno from emp where ename = 'LEVEL5'), date '2026-02-01', 1100, null, 20);</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> echo </span><span style="color: #569CD6">on</span></span>
<span class="line"><span style="color: #6A9955">-- fails (cycle)</span></span>
<span class="line"><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> emp</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> mgr = (</span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> empno </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;SCOTT&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- fails (cycle)</span></span>
<span class="line"><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> emp</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> mgr = (</span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> empno </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;SMITH&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;JONES&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- succeeds</span></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">1000</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;LEVEL5&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;TESTER&#39;</span><span style="color: #D4D4D4">, (</span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> empno </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;ADAMS&#39;</span><span style="color: #D4D4D4">), </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2026-02-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1000</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- fails (6 levels, no cycle)</span></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">1001</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;LEVEL6&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;TESTER&#39;</span><span style="color: #D4D4D4">, (</span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> empno </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> ename = </span><span style="color: #CE9178">&#39;LEVEL5&#39;</span><span style="color: #D4D4D4">), </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;2026-02-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1100</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">);</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>SQL> -- fails (cycle)
SQL> update emp
  2  	set mgr = (select empno from emp where ename = 'SCOTT')
  3   where ename = 'KING';
update emp
*
ERROR at line 1:
ORA-08601: SQL assertion (DEMO.EMP_MGR_FK_NO_CYCLE_AS) violated.
Help: https://docs.oracle.com/error-help/db/ora-08601/


SQL> 
SQL> -- fails (cycle)
SQL> update emp
  2  	set mgr = (select empno from emp where ename = 'SMITH')
  3   where ename = 'JONES';
update emp
       *
ERROR at line 1:
ORA-08601: SQL assertion (DEMO.EMP_MGR_FK_NO_CYCLE_AS) violated.
Help: https://docs.oracle.com/error-help/db/ora-08601/


SQL> 
SQL> -- succeeds
SQL> insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
  2  values (1000, 'LEVEL5', 'TESTER', (select empno from emp where ename = 'ADAMS'), date '2026-02-01', 1000, null, 10);

1 row created.

SQL> 
SQL> -- fails (6 levels, no cycle)
SQL> insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
  2  values (1001, 'LEVEL6', 'TESTER', (select empno from emp where ename = 'LEVEL5'), date '2026-02-01', 1100, null, 20);
insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
            *
ERROR at line 1:
ORA-08601: SQL assertion (DEMO.EMP_MGR_FK_NO_CYCLE_AS) violated.
Help: https://docs.oracle.com/error-help/db/ora-08601/</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">SQL&gt; -- fails (cycle)</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; update emp</span></span>
<span class="line"><span style="color: #D4D4D4">  2  	set mgr = (select empno from emp where ename = &#39;SCOTT&#39;)</span></span>
<span class="line"><span style="color: #D4D4D4">  3   where ename = &#39;KING&#39;;</span></span>
<span class="line"><span style="color: #D4D4D4">update emp</span></span>
<span class="line"><span style="color: #D4D4D4">*</span></span>
<span class="line"><span style="color: #D4D4D4">ERROR at line 1:</span></span>
<span class="line"><span style="color: #D4D4D4">ORA-08601: SQL assertion (DEMO.EMP_MGR_FK_NO_CYCLE_AS) violated.</span></span>
<span class="line"><span style="color: #D4D4D4">Help: https://docs.oracle.com/error-help/db/ora-08601/</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; </span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; -- fails (cycle)</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; update emp</span></span>
<span class="line"><span style="color: #D4D4D4">  2  	set mgr = (select empno from emp where ename = &#39;SMITH&#39;)</span></span>
<span class="line"><span style="color: #D4D4D4">  3   where ename = &#39;JONES&#39;;</span></span>
<span class="line"><span style="color: #D4D4D4">update emp</span></span>
<span class="line"><span style="color: #D4D4D4">       *</span></span>
<span class="line"><span style="color: #D4D4D4">ERROR at line 1:</span></span>
<span class="line"><span style="color: #D4D4D4">ORA-08601: SQL assertion (DEMO.EMP_MGR_FK_NO_CYCLE_AS) violated.</span></span>
<span class="line"><span style="color: #D4D4D4">Help: https://docs.oracle.com/error-help/db/ora-08601/</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; </span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; -- succeeds</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)</span></span>
<span class="line"><span style="color: #D4D4D4">  2  values (1000, &#39;LEVEL5&#39;, &#39;TESTER&#39;, (select empno from emp where ename = &#39;ADAMS&#39;), date &#39;2026-02-01&#39;, 1000, null, 10);</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">1 row created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; </span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; -- fails (6 levels, no cycle)</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)</span></span>
<span class="line"><span style="color: #D4D4D4">  2  values (1001, &#39;LEVEL6&#39;, &#39;TESTER&#39;, (select empno from emp where ename = &#39;LEVEL5&#39;), date &#39;2026-02-01&#39;, 1100, null, 20);</span></span>
<span class="line"><span style="color: #D4D4D4">insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)</span></span>
<span class="line"><span style="color: #D4D4D4">            *</span></span>
<span class="line"><span style="color: #D4D4D4">ERROR at line 1:</span></span>
<span class="line"><span style="color: #D4D4D4">ORA-08601: SQL assertion (DEMO.EMP_MGR_FK_NO_CYCLE_AS) violated.</span></span>
<span class="line"><span style="color: #D4D4D4">Help: https://docs.oracle.com/error-help/db/ora-08601/</span></span></code></pre></div>



<h2 class="wp-block-heading" id="conclusion">Conclusion</h2>



<p>SQL Assertions allow us to implement integrity rules that were previously difficult to enforce when taking factors such as concurrency and performance into account. They allow us to perform consistency checks in the database layer instead of relying on application logic.</p>



<p>Although the inability to use hierarchical queries within SQL Assertions is a significant limitation, the join-based approach presented in this post can effectively prevent hierarchical cycles and ensure consistency through a purely declarative solution. For most real-life data models, limiting the depth of the hierarchy should be a feasible workaround.</p>



<p>SQL Assertions close one of the last major gaps toward Codd’s principle of integrity independence (Rule 10 of <a href="https://en.wikipedia.org/wiki/Codd%27s_12_rules" type="link" id="https://en.wikipedia.org/wiki/Codd%27s_12_rules" target="_blank" rel="noreferrer noopener">Codd&#8217;s 12 rules</a>), making declarative data integrity in the Oracle AI Database nearly complete.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p><em>Updated on 2026-03-30: The SQL Language Reference now lists &#8220;Hierarchical queries&#8221; as a feature that cannot be used with assertions. </em></p>



<p></p>
<p>The post <a href="https://www.salvis.com/blog/2026/02/23/enforcing-acyclic-hierarchies-with-sql-assertions/">Enforcing Acyclic Hierarchies With SQL Assertions</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.salvis.com/blog/2026/02/23/enforcing-acyclic-hierarchies-with-sql-assertions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Avoid Implicit Type Conversion in JSON Access</title>
		<link>https://www.salvis.com/blog/2025/01/28/avoid-implicit-type-conversion-in-json-access/</link>
		
		<dc:creator><![CDATA[Philipp Salvisberg]]></dc:creator>
		<pubDate>Tue, 28 Jan 2025 16:38:55 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Oracle 26ai]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=13804</guid>

					<description><![CDATA[<p>Introduction Before comparing two values, the Oracle Database automatically ensures that both values have the same data type. It converts one of the values to match the data type of the other value. The SQL Language Reference manual describes when and how implicit data conversions happen. However, Oracle recommends that you convert<span class="excerpt-hellip"> […]</span></p>
<p>The post <a href="https://www.salvis.com/blog/2025/01/28/avoid-implicit-type-conversion-in-json-access/">Avoid Implicit Type Conversion in JSON Access</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Introduction</h2>



<p>Before comparing two values, the Oracle Database automatically ensures that both values have the same data type. It converts one of the values to match the data type of the other value. The <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/Data-Type-Comparison-Rules.html#GUID-6DB331B5-0F34-4215-9A20-16AEA9D7FF4B">SQL Language Reference manual</a> describes when and how implicit data conversions happen. However, Oracle recommends that you convert data types explicitly. This ensures consistent results and better performance.</p>



<p>I am using JSON relational duality views in my current project. During development, I have stumbled across some implicit data conversions that I was unaware of and that are causing poor performance. I will use a simplified example to show you what I mean.</p>



<ol class="wp-block-list">
<li><a href="#setup">Setup</a></li>



<li><a href="#json-relational-duality-view">JSON-relational Duality View</a></li>



<li><a href="#json-data-types">JSON Data Types</a></li>



<li><a href="#explicit-conversion">Explicit Conversion</a></li>



<li><a href="#json-collection-view">JSON Collection View</a></li>



<li><a href="#conclusion">Conclusion</a></li>
</ol>



<h2 class="wp-block-heading" id="setup">1. Setup</h2>



<p>I&#8217;ve tested this example with an Oracle Database 23.6 and 23.7. </p>



<p>In a schema of your choice you can run the following setup script:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">1) Setup table dept and emp</span><span role="button" tabindex="0" data-code="drop table if exists emp;
drop table if exists dept;

create table dept (
   deptno number(2, 0)      not null constraint dept_pk primary key,
   dname  varchar2(14 char) not null,
   loc    varchar2(13 char) not null
);

create table emp (
   empno    number(4, 0)      not null  constraint emp_pk primary key,
   ename    varchar2(10 char) not null,
   job      varchar2(9 char)  not null,
   mgr      number(4, 0)                constraint emp_mgr_fk references emp,
   hiredate date              not null,
   sal      number(7, 2)      not null,
   comm     number(7, 2),
   deptno   number(2, 0)      not null  constraint emp_deptno_fk references dept
);

insert into dept (deptno, dname, loc)
values (10, 'ACCOUNTING', 'NEW YORK'),
       (20, 'RESEARCH',   'DALLAS'),
       (30, 'SALES',      'CHICAGO'),
       (40, 'OPERATIONS', 'BOSTON');

insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7566, 'JONES',  'MANAGER',   7839, date '1981-04-02', 2975, null, 20),
       (7698, 'BLAKE',  'MANAGER',   7839, date '1981-05-01', 2850, null, 30),
       (7782, 'CLARK',  'MANAGER',   7839, date '1981-06-09', 2450, null, 10),
       (7788, 'SCOTT',  'ANALYST',   7566, date '1987-04-19', 3000, null, 20),
       (7902, 'FORD',   'ANALYST',   7566, date '1981-12-03', 3000, null, 20),
       (7499, 'ALLEN',  'SALESMAN',  7698, date '1981-02-20', 1600,  300, 30),
       (7521, 'WARD',   'SALESMAN',  7698, date '1981-02-22', 1250,  500, 30),
       (7654, 'MARTIN', 'SALESMAN',  7698, date '1981-09-28', 1250, 1400, 30),
       (7844, 'TURNER', 'SALESMAN',  7698, date '1981-09-08', 1500,    0, 30),
       (7900, 'JAMES',  'CLERK',     7698, date '1981-12-03',  950, null, 30),
       (7934, 'MILLER', 'CLERK',     7782, date '1982-01-23', 1300, null, 10),
       (7369, 'SMITH',  'CLERK',     7902, date '1980-12-17',  800, null, 20),
       (7839, 'KING',   'PRESIDENT', null, date '1981-11-17', 5000, null, 10),
       (7876, 'ADAMS',  'CLERK',     7788, date '1987-05-23', 1100, null, 20);

begin
   dbms_stats.gather_table_stats(user, 'dept');
   dbms_stats.gather_table_stats(user, 'emp');
end;
/

alter session set nls_date_format = 'YYYY-MM-DD';
column deptno format a6
column dname format a10
column loc format a9
column empid format a8
column empno format a5
column ename format a6
column mgr format a4
column sal format a4
column comm format a4

select * from dept;
select * from emp;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">drop</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> emp;</span></span>
<span class="line"><span style="color: #569CD6">drop</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">exists</span><span style="color: #D4D4D4"> dept;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> dept (</span></span>
<span class="line"><span style="color: #D4D4D4">   deptno </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> dept_pk </span><span style="color: #569CD6">primary key</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   dname  </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">14</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   loc    </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">13</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span></span>
<span class="line"><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">create</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">table</span><span style="color: #D4D4D4"> emp (</span></span>
<span class="line"><span style="color: #D4D4D4">   empno    </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_pk </span><span style="color: #569CD6">primary key</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   ename    </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   job      </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">9</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">char</span><span style="color: #D4D4D4">)  </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   mgr      </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)                </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_mgr_fk </span><span style="color: #569CD6">references</span><span style="color: #D4D4D4"> emp,</span></span>
<span class="line"><span style="color: #D4D4D4">   hiredate </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4">              </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   sal      </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">7</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">   comm     </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">7</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">   deptno   </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">)      </span><span style="color: #569CD6">not</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">constraint</span><span style="color: #D4D4D4"> emp_deptno_fk </span><span style="color: #569CD6">references</span><span style="color: #D4D4D4"> dept</span></span>
<span class="line"><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> dept (deptno, dname, loc)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ACCOUNTING&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;NEW YORK&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;RESEARCH&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;DALLAS&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SALES&#39;</span><span style="color: #D4D4D4">,      </span><span style="color: #CE9178">&#39;CHICAGO&#39;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">40</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;OPERATIONS&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;BOSTON&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">into</span><span style="color: #D4D4D4"> emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)</span></span>
<span class="line"><span style="color: #569CD6">values</span><span style="color: #D4D4D4"> (</span><span style="color: #B5CEA8">7566</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;JONES&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;MANAGER&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-04-02&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2975</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;BLAKE&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;MANAGER&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-05-01&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2850</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7782</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;CLARK&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;MANAGER&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-06-09&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">2450</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7788</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SCOTT&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;ANALYST&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7566</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1987-04-19&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">3000</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7902</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;FORD&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;ANALYST&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #B5CEA8">7566</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-12-03&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">3000</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7499</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ALLEN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-02-20&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1600</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">300</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7521</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;WARD&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-02-22&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1250</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">500</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7654</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;MARTIN&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-09-28&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1250</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1400</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7844</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;TURNER&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SALESMAN&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-09-08&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1500</span><span style="color: #D4D4D4">,    </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7900</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;JAMES&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7698</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-12-03&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">950</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">30</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7934</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;MILLER&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7782</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1982-01-23&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1300</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7369</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;SMITH&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7902</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1980-12-17&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #B5CEA8">800</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7839</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;KING&#39;</span><span style="color: #D4D4D4">,   </span><span style="color: #CE9178">&#39;PRESIDENT&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1981-11-17&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">5000</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">       (</span><span style="color: #B5CEA8">7876</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;ADAMS&#39;</span><span style="color: #D4D4D4">,  </span><span style="color: #CE9178">&#39;CLERK&#39;</span><span style="color: #D4D4D4">,     </span><span style="color: #B5CEA8">7788</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;1987-05-23&#39;</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">1100</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #B5CEA8">20</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">begin</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #DCDCAA">dbms_stats.</span><span style="color: #4EC9B0">gather_table_stats</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">user</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;dept&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #DCDCAA">dbms_stats.</span><span style="color: #4EC9B0">gather_table_stats</span><span style="color: #D4D4D4">(</span><span style="color: #DCDCAA">user</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;emp&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #569CD6">end</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">alter session</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> nls_date_format = </span><span style="color: #CE9178">&#39;YYYY-MM-DD&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> deptno format a6</span></span>
<span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> dname format a10</span></span>
<span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> loc format a9</span></span>
<span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> empid format a8</span></span>
<span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> empno format a5</span></span>
<span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> ename format a6</span></span>
<span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> mgr format a4</span></span>
<span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> sal format a4</span></span>
<span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> comm format a4</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept;</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> * </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> emp;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="Table EMP dropped.


Table DEPT dropped.


Table DEPT created.


Table EMP created.


4 rows inserted.


14 rows inserted.


PL/SQL procedure successfully completed.


Session altered.


DEPTNO DNAME      LOC      
------ ---------- ---------
    10 ACCOUNTING NEW YORK 
    20 RESEARCH   DALLAS   
    30 SALES      CHICAGO  
    40 OPERATIONS BOSTON   


EMPNO ENAME  JOB        MGR HIREDATE    SAL COMM DEPTNO
----- ------ --------- ---- ---------- ---- ---- ------
 7566 JONES  MANAGER   7839 1981-04-02 2975          20
 7698 BLAKE  MANAGER   7839 1981-05-01 2850          30
 7782 CLARK  MANAGER   7839 1981-06-09 2450          10
 7788 SCOTT  ANALYST   7566 1987-04-19 3000          20
 7902 FORD   ANALYST   7566 1981-12-03 3000          20
 7499 ALLEN  SALESMAN  7698 1981-02-20 1600  300     30
 7521 WARD   SALESMAN  7698 1981-02-22 1250  500     30
 7654 MARTIN SALESMAN  7698 1981-09-28 1250 1400     30
 7844 TURNER SALESMAN  7698 1981-09-08 1500    0     30
 7900 JAMES  CLERK     7698 1981-12-03  950          30
 7934 MILLER CLERK     7782 1982-01-23 1300          10
 7369 SMITH  CLERK     7902 1980-12-17  800          20
 7839 KING   PRESIDENT      1981-11-17 5000          10
 7876 ADAMS  CLERK     7788 1987-05-23 1100          20

14 rows selected. " style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Table EMP dropped.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Table DEPT dropped.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Table DEPT created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Table EMP created.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">4 rows inserted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">14 rows inserted.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">PL/SQL procedure successfully completed.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Session altered.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">DEPTNO DNAME      LOC      </span></span>
<span class="line"><span style="color: #D4D4D4">------ ---------- ---------</span></span>
<span class="line"><span style="color: #D4D4D4">    10 ACCOUNTING NEW YORK </span></span>
<span class="line"><span style="color: #D4D4D4">    20 RESEARCH   DALLAS   </span></span>
<span class="line"><span style="color: #D4D4D4">    30 SALES      CHICAGO  </span></span>
<span class="line"><span style="color: #D4D4D4">    40 OPERATIONS BOSTON   </span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">EMPNO ENAME  JOB        MGR HIREDATE    SAL COMM DEPTNO</span></span>
<span class="line"><span style="color: #D4D4D4">----- ------ --------- ---- ---------- ---- ---- ------</span></span>
<span class="line"><span style="color: #D4D4D4"> 7566 JONES  MANAGER   7839 1981-04-02 2975          20</span></span>
<span class="line"><span style="color: #D4D4D4"> 7698 BLAKE  MANAGER   7839 1981-05-01 2850          30</span></span>
<span class="line"><span style="color: #D4D4D4"> 7782 CLARK  MANAGER   7839 1981-06-09 2450          10</span></span>
<span class="line"><span style="color: #D4D4D4"> 7788 SCOTT  ANALYST   7566 1987-04-19 3000          20</span></span>
<span class="line"><span style="color: #D4D4D4"> 7902 FORD   ANALYST   7566 1981-12-03 3000          20</span></span>
<span class="line"><span style="color: #D4D4D4"> 7499 ALLEN  SALESMAN  7698 1981-02-20 1600  300     30</span></span>
<span class="line"><span style="color: #D4D4D4"> 7521 WARD   SALESMAN  7698 1981-02-22 1250  500     30</span></span>
<span class="line"><span style="color: #D4D4D4"> 7654 MARTIN SALESMAN  7698 1981-09-28 1250 1400     30</span></span>
<span class="line"><span style="color: #D4D4D4"> 7844 TURNER SALESMAN  7698 1981-09-08 1500    0     30</span></span>
<span class="line"><span style="color: #D4D4D4"> 7900 JAMES  CLERK     7698 1981-12-03  950          30</span></span>
<span class="line"><span style="color: #D4D4D4"> 7934 MILLER CLERK     7782 1982-01-23 1300          10</span></span>
<span class="line"><span style="color: #D4D4D4"> 7369 SMITH  CLERK     7902 1980-12-17  800          20</span></span>
<span class="line"><span style="color: #D4D4D4"> 7839 KING   PRESIDENT      1981-11-17 5000          10</span></span>
<span class="line"><span style="color: #D4D4D4"> 7876 ADAMS  CLERK     7788 1987-05-23 1100          20</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">14 rows selected. </span></span></code></pre></div>



<p>The model has primary and foreign keys which are required for the duality views. However, the constraints do not need to be enabled.</p>



<h2 class="wp-block-heading" id="json-relational-duality-view">2. JSON-relational Duality View</h2>



<p>Now let&#8217;s create an updateable duality view for the model we created earlier.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">2) Create duality view dept_dv</span><span role="button" tabindex="0" data-code="create or replace json duality view dept_dv as
dept @insert @update @delete
{
   _id: deptno
   dname
   loc
   emps: emp @insert @update @delete
      {
         empno
         ename
         job
         emp @unnest @link(from: [mgr])
            {
               mgr    : empno @nocheck
               mgrname: ename @nocheck
            }
         hiredate
         sal
         comm
      }
};" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create or replace</span><span style="color: #D4D4D4"> json duality </span><span style="color: #569CD6">view</span><span style="color: #D4D4D4"> dept_dv </span><span style="color: #569CD6">as</span></span>
<span class="line"><span style="color: #D4D4D4">dept @</span><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> @</span><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> @</span><span style="color: #569CD6">delete</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">   _id: deptno</span></span>
<span class="line"><span style="color: #D4D4D4">   dname</span></span>
<span class="line"><span style="color: #D4D4D4">   loc</span></span>
<span class="line"><span style="color: #D4D4D4">   emps: emp @</span><span style="color: #569CD6">insert</span><span style="color: #D4D4D4"> @</span><span style="color: #569CD6">update</span><span style="color: #D4D4D4"> @</span><span style="color: #569CD6">delete</span></span>
<span class="line"><span style="color: #D4D4D4">      {</span></span>
<span class="line"><span style="color: #D4D4D4">         empno</span></span>
<span class="line"><span style="color: #D4D4D4">         ename</span></span>
<span class="line"><span style="color: #D4D4D4">         job</span></span>
<span class="line"><span style="color: #D4D4D4">         emp @unnest @link(</span><span style="color: #569CD6">from</span><span style="color: #D4D4D4">: [mgr])</span></span>
<span class="line"><span style="color: #D4D4D4">            {</span></span>
<span class="line"><span style="color: #D4D4D4">               mgr    : empno @nocheck</span></span>
<span class="line"><span style="color: #D4D4D4">               mgrname: ename @nocheck</span></span>
<span class="line"><span style="color: #D4D4D4">            }</span></span>
<span class="line"><span style="color: #D4D4D4">         hiredate</span></span>
<span class="line"><span style="color: #D4D4D4">         sal</span></span>
<span class="line"><span style="color: #D4D4D4">         comm</span></span>
<span class="line"><span style="color: #D4D4D4">      }</span></span>
<span class="line"><span style="color: #D4D4D4">};</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="Json duality view DEPT_DV created." style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Json duality view DEPT_DV created.</span></span></code></pre></div>



<p>We can query the department <code>10</code> as follows:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">3) Query deptno 10 in dept_dv</span><span role="button" tabindex="0" data-code="column json_data format a50
alter session disable parallel query;
set pagesize 1000

select json_serialize(dv.data returning varchar2 pretty) as json_data
  from dept_dv dv
 where dv.data.&quot;_id&quot; = 10;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> json_data format a50</span></span>
<span class="line"><span style="color: #DCDCAA">alter session</span><span style="color: #D4D4D4"> disable parallel query;</span></span>
<span class="line"><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> pagesize </span><span style="color: #B5CEA8">1000</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> json_serialize(dv.data </span><span style="color: #569CD6">returning</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4"> pretty) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> json_data</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept_dv dv</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> dv.data.</span><span style="color: #CE9178">&quot;_id&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="Session altered.


JSON_DATA
--------------------------------------------------
{
  &quot;_id&quot; : 10,
  &quot;_metadata&quot; :
  {
    &quot;etag&quot; : &quot;E0146035FE26EE16D4968A21E6350D81&quot;,
    &quot;asof&quot; : &quot;00002604AFC8A4BC&quot;
  },
  &quot;dname&quot; : &quot;ACCOUNTING&quot;,
  &quot;loc&quot; : &quot;NEW YORK&quot;,
  &quot;emps&quot; :
  [
    {
      &quot;empno&quot; : 7782,
      &quot;ename&quot; : &quot;CLARK&quot;,
      &quot;job&quot; : &quot;MANAGER&quot;,
      &quot;mgr&quot; : 7839,
      &quot;mgrname&quot; : &quot;KING&quot;,
      &quot;hiredate&quot; : &quot;1981-06-09T00:00:00&quot;,
      &quot;sal&quot; : 2450,
      &quot;comm&quot; : null
    },
    {
      &quot;empno&quot; : 7839,
      &quot;ename&quot; : &quot;KING&quot;,
      &quot;job&quot; : &quot;PRESIDENT&quot;,
      &quot;hiredate&quot; : &quot;1981-11-17T00:00:00&quot;,
      &quot;sal&quot; : 5000,
      &quot;comm&quot; : null
    },
    {
      &quot;empno&quot; : 7934,
      &quot;ename&quot; : &quot;MILLER&quot;,
      &quot;job&quot; : &quot;CLERK&quot;,
      &quot;mgr&quot; : 7782,
      &quot;mgrname&quot; : &quot;CLARK&quot;,
      &quot;hiredate&quot; : &quot;1982-01-23T00:00:00&quot;,
      &quot;sal&quot; : 1300,
      &quot;comm&quot; : null
    }
  ]
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Session altered.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">JSON_DATA</span></span>
<span class="line"><span style="color: #D4D4D4">--------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;_id&quot; : 10,</span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;_metadata&quot; :</span></span>
<span class="line"><span style="color: #D4D4D4">  {</span></span>
<span class="line"><span style="color: #D4D4D4">    &quot;etag&quot; : &quot;E0146035FE26EE16D4968A21E6350D81&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">    &quot;asof&quot; : &quot;00002604AFC8A4BC&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  },</span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;dname&quot; : &quot;ACCOUNTING&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;loc&quot; : &quot;NEW YORK&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;emps&quot; :</span></span>
<span class="line"><span style="color: #D4D4D4">  [</span></span>
<span class="line"><span style="color: #D4D4D4">    {</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;empno&quot; : 7782,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;ename&quot; : &quot;CLARK&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;job&quot; : &quot;MANAGER&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;mgr&quot; : 7839,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;mgrname&quot; : &quot;KING&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;hiredate&quot; : &quot;1981-06-09T00:00:00&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;sal&quot; : 2450,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;comm&quot; : null</span></span>
<span class="line"><span style="color: #D4D4D4">    },</span></span>
<span class="line"><span style="color: #D4D4D4">    {</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;empno&quot; : 7839,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;ename&quot; : &quot;KING&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;job&quot; : &quot;PRESIDENT&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;hiredate&quot; : &quot;1981-11-17T00:00:00&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;sal&quot; : 5000,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;comm&quot; : null</span></span>
<span class="line"><span style="color: #D4D4D4">    },</span></span>
<span class="line"><span style="color: #D4D4D4">    {</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;empno&quot; : 7934,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;ename&quot; : &quot;MILLER&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;job&quot; : &quot;CLERK&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;mgr&quot; : 7782,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;mgrname&quot; : &quot;CLARK&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;hiredate&quot; : &quot;1982-01-23T00:00:00&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;sal&quot; : 1300,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;comm&quot; : null</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">  ]</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p>The where clause in line 7 contains an implicit conversion. It&#8217;s not that obvious and the execution plan does not help to spot it either.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">4) Execution plan</span><span role="button" tabindex="0" data-code="PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
SQL_ID  8nns7xgu0v6vu, child number 4
-------------------------------------
select json_serialize(dv.data returning varchar2 pretty) as json_data   
from dept_dv dv  where dv.data.&quot;_id&quot; = 10
 
Plan hash value: 2166484641
 
---------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |       |       |     7 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP     |     1 |    10 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | EMP_PK  |     1 |       |     0   (0)|          |
|   3 |  SORT GROUP BY              |         |     1 |    38 |            |          |
|*  4 |   TABLE ACCESS FULL         | EMP     |     5 |   190 |     3   (0)| 00:00:01 |
|   5 |  TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    20 |     1   (0)| 00:00:01 |
|*  6 |   INDEX UNIQUE SCAN         | DEPT_PK |     1 |       |     0   (0)|          |
---------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access(&quot;OUTER_ALIAS2&quot;.&quot;EMPNO&quot;=:B1)
   4 - filter(&quot;OUTER_ALIAS1&quot;.&quot;DEPTNO&quot;=:B1)
   6 - access(&quot;DEPTNO&quot;=10)" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">PLAN_TABLE_OUTPUT</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">SQL_ID  8nns7xgu0v6vu, child number 4</span></span>
<span class="line"><span style="color: #D4D4D4">-------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">select json_serialize(dv.data returning varchar2 pretty) as json_data   </span></span>
<span class="line"><span style="color: #D4D4D4">from dept_dv dv  where dv.data.&quot;_id&quot; = 10</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Plan hash value: 2166484641</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">|   0 | SELECT STATEMENT            |         |       |       |     7 (100)|          |</span></span>
<span class="line"><span style="color: #D4D4D4">|   1 |  TABLE ACCESS BY INDEX ROWID| EMP     |     1 |    10 |     1   (0)| 00:00:01 |</span></span>
<span class="line"><span style="color: #D4D4D4">|*  2 |   INDEX UNIQUE SCAN         | EMP_PK  |     1 |       |     0   (0)|          |</span></span>
<span class="line"><span style="color: #D4D4D4">|   3 |  SORT GROUP BY              |         |     1 |    38 |            |          |</span></span>
<span class="line"><span style="color: #D4D4D4">|*  4 |   TABLE ACCESS FULL         | EMP     |     5 |   190 |     3   (0)| 00:00:01 |</span></span>
<span class="line"><span style="color: #D4D4D4">|   5 |  TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    20 |     1   (0)| 00:00:01 |</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">|*  6 |   INDEX UNIQUE SCAN         | DEPT_PK |     1 |       |     0   (0)|          |</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Predicate Information (identified by operation id):</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   2 - access(&quot;OUTER_ALIAS2&quot;.&quot;EMPNO&quot;=:B1)</span></span>
<span class="line"><span style="color: #D4D4D4">   4 - filter(&quot;OUTER_ALIAS1&quot;.&quot;DEPTNO&quot;=:B1)</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">   6 - access(&quot;DEPTNO&quot;=10)</span></span></code></pre></div>



<p>The highlighted lines show that a unique index scan has been performed for deptno <code>10</code>. This looks good. So where does the implicit conversion take place?</p>



<h2 class="wp-block-heading" id="json-data-types">3. JSON Data Types</h2>



<p>The condition <code>dv.data."_id" = 10</code> in the where clause compares a JSON data type with a numeric data type. As a result, the Oracle Database needs to convert one of the values. It decided to convert the JSON to a numeric value. That&#8217;s what we see in the execution plan.</p>



<p>Really? Can we prove this claim? Yes, with the following statement.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(2 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">5) Determine JSON data type</span><span role="button" tabindex="0" data-code="select is_json_condition, value
  from (
          select deptno is json as is_json,
                 deptno is json(value) as is_json_value,
                 deptno is json(array) as is_json_array,
                 deptno is json(object) as is_json_object,
                 deptno is json(scalar) as is_json_scalar,
                 deptno is json(scalar number) as is_json_scalar_number,
                 deptno is json(scalar string) as is_json_scalar_string,
                 deptno is json(scalar binary_double) as is_json_scalar_binary_double,
                 deptno is json(scalar binary_float) as is_json_scalar_binary_float,
                 deptno is json(scalar date) as is_json_scalar_date,
                 deptno is json(scalar timestamp) as is_json_scalar_timestamp,
                 deptno is json(scalar timestamp with time zone) as is_json_scalar_timestamp_with_time_zone,
                 deptno is json(scalar null) as is_json_scalar_null,
                 deptno is json(scalar boolean) as is_json_scalar_boolean,
                 deptno is json(scalar binary) as is_json_scalar_binary,
                 deptno is json(scalar interval year to month) as is_json_scalar_interval_year_to_month,
                 deptno is json(scalar interval day to second) as is_json_scalar_interval_day_to_second
            from (select dv.data.&quot;_id&quot; as deptno from dept_dv dv where rownum = 1)
       ) src unpivot (
          value for is_json_condition in (
             is_json,
             is_json_value,
             is_json_array,
             is_json_object,
             is_json_scalar,
             is_json_scalar_number,
             is_json_scalar_string,
             is_json_scalar_binary_double,
             is_json_scalar_binary_float,
             is_json_scalar_date,
             is_json_scalar_timestamp,
             is_json_scalar_timestamp_with_time_zone,
             is_json_scalar_null,
             is_json_scalar_boolean,
             is_json_scalar_binary,
             is_json_scalar_interval_year_to_month,
             is_json_scalar_interval_day_to_second
          )
       );" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> is_json_condition, value</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">          </span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(value) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_value,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(array) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_array,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(object) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_object,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar </span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_number,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar string) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_string,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar </span><span style="color: #569CD6">binary_double</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_binary_double,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar </span><span style="color: #569CD6">binary_float</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_binary_float,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar </span><span style="color: #569CD6">date</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_date,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar </span><span style="color: #569CD6">timestamp</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_timestamp,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar </span><span style="color: #569CD6">timestamp with time zone</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_timestamp_with_time_zone,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_null,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar </span><span style="color: #569CD6">boolean</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_boolean,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar binary) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_binary,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar interval year to month) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_interval_year_to_month,</span></span>
<span class="line"><span style="color: #D4D4D4">                 deptno </span><span style="color: #569CD6">is</span><span style="color: #D4D4D4"> json(scalar interval day to second) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> is_json_scalar_interval_day_to_second</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">            </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> (</span><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> dv.data.</span><span style="color: #CE9178">&quot;_id&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> deptno </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept_dv dv </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">rownum</span><span style="color: #D4D4D4"> = </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">       ) src </span><span style="color: #569CD6">unpivot</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">          value </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> is_json_condition </span><span style="color: #569CD6">in</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_value,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_array,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_object,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_number,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_string,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_binary_double,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_binary_float,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_date,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_timestamp,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_timestamp_with_time_zone,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_null,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_boolean,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_binary,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_interval_year_to_month,</span></span>
<span class="line"><span style="color: #D4D4D4">             is_json_scalar_interval_day_to_second</span></span>
<span class="line"><span style="color: #D4D4D4">          )</span></span>
<span class="line"><span style="color: #D4D4D4">       );</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="IS_JSON_CONDITION                       VALUE
--------------------------------------- -----
IS_JSON                                 true 
IS_JSON_VALUE                           true 
IS_JSON_ARRAY                           false
IS_JSON_OBJECT                          false
IS_JSON_SCALAR                          true 
IS_JSON_SCALAR_NUMBER                   true 
IS_JSON_SCALAR_STRING                   false
IS_JSON_SCALAR_BINARY_DOUBLE            false
IS_JSON_SCALAR_BINARY_FLOAT             false
IS_JSON_SCALAR_DATE                     false
IS_JSON_SCALAR_TIMESTAMP                false
IS_JSON_SCALAR_TIMESTAMP_WITH_TIME_ZONE false
IS_JSON_SCALAR_NULL                     false
IS_JSON_SCALAR_BOOLEAN                  false
IS_JSON_SCALAR_BINARY                   false
IS_JSON_SCALAR_INTERVAL_YEAR_TO_MONTH   false
IS_JSON_SCALAR_INTERVAL_DAY_TO_SECOND   false

17 rows selected. " style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">IS_JSON_CONDITION                       VALUE</span></span>
<span class="line"><span style="color: #D4D4D4">--------------------------------------- -----</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">IS_JSON                                 true </span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">IS_JSON_VALUE                           true </span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_ARRAY                           false</span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_OBJECT                          false</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">IS_JSON_SCALAR                          true </span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">IS_JSON_SCALAR_NUMBER                   true </span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_SCALAR_STRING                   false</span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_SCALAR_BINARY_DOUBLE            false</span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_SCALAR_BINARY_FLOAT             false</span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_SCALAR_DATE                     false</span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_SCALAR_TIMESTAMP                false</span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_SCALAR_TIMESTAMP_WITH_TIME_ZONE false</span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_SCALAR_NULL                     false</span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_SCALAR_BOOLEAN                  false</span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_SCALAR_BINARY                   false</span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_SCALAR_INTERVAL_YEAR_TO_MONTH   false</span></span>
<span class="line"><span style="color: #D4D4D4">IS_JSON_SCALAR_INTERVAL_DAY_TO_SECOND   false</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">17 rows selected. </span></span></code></pre></div>



<p>In line 20 we query <code>dv.data."_id"</code> and use the <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/SQL-JSON-Conditions.html#GUID-99B9493D-2929-4A09-BA39-A56F8E7319DA">IS JSON condition</a> to determine the data type. The most granular type is JSON scalar number. </p>



<h2 class="wp-block-heading" id="explicit-conversion">4. Explicit Conversion</h2>



<p>So, we know now, that we need to convert a JSON scalar number to a number. And how do we do that? &#8211; By using a <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/sql-json-path-expression-item-methods.html#GUID-8656CAB9-C293-4A99-BB62-F38F3CFC4C13__TABLE_U23_R3C_DSB">SQL/JSON path expression method</a>, as in the next example.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">7) Query deptno 10 in dept_dv with explicit type conversion</span><span role="button" tabindex="0" data-code="select json_serialize(dv.data returning varchar2 pretty) as json_data
  from dept_dv dv
 where dv.data.&quot;_id&quot;.number() = 10;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> json_serialize(dv.data </span><span style="color: #569CD6">returning</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4"> pretty) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> json_data</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept_dv dv</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> dv.data.</span><span style="color: #CE9178">&quot;_id&quot;</span><span style="color: #D4D4D4">.</span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">() = </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<p>We used the <code>.number()</code> method in this example. The execution plan for this query looks now like this:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">8) Execution plan querying dept_dv with explicit type conversion</span><span role="button" tabindex="0" data-code="PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
SQL_ID  4rjg8g02bph16, child number 2
-------------------------------------
select json_serialize(dv.data returning varchar2 pretty) as json_data   
from dept_dv dv  where dv.data.&quot;_id&quot;.number() = 10
 
Plan hash value: 2166484641
 
---------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |       |       |     7 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP     |     1 |    10 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | EMP_PK  |     1 |       |     0   (0)|          |
|   3 |  SORT GROUP BY              |         |     1 |    38 |            |          |
|*  4 |   TABLE ACCESS FULL         | EMP     |     5 |   190 |     3   (0)| 00:00:01 |
|   5 |  TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    20 |     1   (0)| 00:00:01 |
|*  6 |   INDEX UNIQUE SCAN         | DEPT_PK |     1 |       |     0   (0)|          |
---------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access(&quot;OUTER_ALIAS2&quot;.&quot;EMPNO&quot;=:B1)
   4 - filter(&quot;OUTER_ALIAS1&quot;.&quot;DEPTNO&quot;=:B1)
   6 - access(&quot;DEPTNO&quot;=10)" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">PLAN_TABLE_OUTPUT</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">SQL_ID  4rjg8g02bph16, child number 2</span></span>
<span class="line"><span style="color: #D4D4D4">-------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">select json_serialize(dv.data returning varchar2 pretty) as json_data   </span></span>
<span class="line"><span style="color: #D4D4D4">from dept_dv dv  where dv.data.&quot;_id&quot;.number() = 10</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Plan hash value: 2166484641</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">|   0 | SELECT STATEMENT            |         |       |       |     7 (100)|          |</span></span>
<span class="line"><span style="color: #D4D4D4">|   1 |  TABLE ACCESS BY INDEX ROWID| EMP     |     1 |    10 |     1   (0)| 00:00:01 |</span></span>
<span class="line"><span style="color: #D4D4D4">|*  2 |   INDEX UNIQUE SCAN         | EMP_PK  |     1 |       |     0   (0)|          |</span></span>
<span class="line"><span style="color: #D4D4D4">|   3 |  SORT GROUP BY              |         |     1 |    38 |            |          |</span></span>
<span class="line"><span style="color: #D4D4D4">|*  4 |   TABLE ACCESS FULL         | EMP     |     5 |   190 |     3   (0)| 00:00:01 |</span></span>
<span class="line"><span style="color: #D4D4D4">|   5 |  TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    20 |     1   (0)| 00:00:01 |</span></span>
<span class="line"><span style="color: #D4D4D4">|*  6 |   INDEX UNIQUE SCAN         | DEPT_PK |     1 |       |     0   (0)|          |</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Predicate Information (identified by operation id):</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   2 - access(&quot;OUTER_ALIAS2&quot;.&quot;EMPNO&quot;=:B1)</span></span>
<span class="line"><span style="color: #D4D4D4">   4 - filter(&quot;OUTER_ALIAS1&quot;.&quot;DEPTNO&quot;=:B1)</span></span>
<span class="line"><span style="color: #D4D4D4">   6 - access(&quot;DEPTNO&quot;=10)</span></span></code></pre></div>



<p>The plan looks the same as without calling the <code>.number()</code> method, but in this case, we did not rely on implicit type conversion.</p>



<p>We&#8217;ve proven, that a <code>.number()</code> call does not make things worse. But are there cases where such an explicit type conversion results in a better execution plan?</p>



<h2 class="wp-block-heading" id="json-collection-view">5. JSON Collection View</h2>



<p>Let&#8217;s say we need a view that filters the data in the duality view. For example, for security purposes. One way to achieve this is to create a JSON collection view. From a consumer point of view, such a view behaves 100% the same as a duality view. The only difference is that it is read-only and allows the full SQL grammar to define such a view.</p>



<p>Here&#8217;s an example.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">9) Create JSON collection view dept_cv</span><span role="button" tabindex="0" data-code="create or replace json collection view dept_cv as
select dv.data
  from dept_dv dv
 where dv.data.&quot;_id&quot;.number() = 10 or dv.data.loc.string() = 'DALLAS';" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">create or replace</span><span style="color: #D4D4D4"> json collection </span><span style="color: #569CD6">view</span><span style="color: #D4D4D4"> dept_cv </span><span style="color: #569CD6">as</span></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> dv.data</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept_dv dv</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> dv.data.</span><span style="color: #CE9178">&quot;_id&quot;</span><span style="color: #D4D4D4">.</span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">() = </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">or</span><span style="color: #D4D4D4"> dv.data.loc.string() = </span><span style="color: #CE9178">&#39;DALLAS&#39;</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="Json collection view DEPT_CV created." style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Json collection view DEPT_CV created.</span></span></code></pre></div>



<p>Now, let&#8217;s run a query with implicit type conversion.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">10) Query deptno 10 in dept_cv</span><span role="button" tabindex="0" data-code="column json_data format a50
alter session disable parallel query;
set pagesize 1000

select json_serialize(cv.data returning varchar2 pretty) as json_data
  from dept_cv cv
 where cv.data.&quot;_id&quot; = 10;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">column</span><span style="color: #D4D4D4"> json_data format a50</span></span>
<span class="line"><span style="color: #DCDCAA">alter session</span><span style="color: #D4D4D4"> disable parallel query;</span></span>
<span class="line"><span style="color: #569CD6">set</span><span style="color: #D4D4D4"> pagesize </span><span style="color: #B5CEA8">1000</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> json_serialize(cv.data </span><span style="color: #569CD6">returning</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4"> pretty) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> json_data</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept_cv cv</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> cv.data.</span><span style="color: #CE9178">&quot;_id&quot;</span><span style="color: #D4D4D4"> = </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="Session altered.


JSON_DATA
--------------------------------------------------
{
  &quot;_id&quot; : 10,
  &quot;_metadata&quot; :
  {
    &quot;etag&quot; : &quot;E0146035FE26EE16D4968A21E6350D81&quot;,
    &quot;asof&quot; : &quot;00002604B0C08AAE&quot;
  },
  &quot;dname&quot; : &quot;ACCOUNTING&quot;,
  &quot;loc&quot; : &quot;NEW YORK&quot;,
  &quot;emps&quot; :
  [
    {
      &quot;empno&quot; : 7782,
      &quot;ename&quot; : &quot;CLARK&quot;,
      &quot;job&quot; : &quot;MANAGER&quot;,
      &quot;mgr&quot; : 7839,
      &quot;mgrname&quot; : &quot;KING&quot;,
      &quot;hiredate&quot; : &quot;1981-06-09T00:00:00&quot;,
      &quot;sal&quot; : 2450,
      &quot;comm&quot; : null
    },
    {
      &quot;empno&quot; : 7839,
      &quot;ename&quot; : &quot;KING&quot;,
      &quot;job&quot; : &quot;PRESIDENT&quot;,
      &quot;hiredate&quot; : &quot;1981-11-17T00:00:00&quot;,
      &quot;sal&quot; : 5000,
      &quot;comm&quot; : null
    },
    {
      &quot;empno&quot; : 7934,
      &quot;ename&quot; : &quot;MILLER&quot;,
      &quot;job&quot; : &quot;CLERK&quot;,
      &quot;mgr&quot; : 7782,
      &quot;mgrname&quot; : &quot;CLARK&quot;,
      &quot;hiredate&quot; : &quot;1982-01-23T00:00:00&quot;,
      &quot;sal&quot; : 1300,
      &quot;comm&quot; : null
    }
  ]
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">Session altered.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">JSON_DATA</span></span>
<span class="line"><span style="color: #D4D4D4">--------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;_id&quot; : 10,</span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;_metadata&quot; :</span></span>
<span class="line"><span style="color: #D4D4D4">  {</span></span>
<span class="line"><span style="color: #D4D4D4">    &quot;etag&quot; : &quot;E0146035FE26EE16D4968A21E6350D81&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">    &quot;asof&quot; : &quot;00002604B0C08AAE&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  },</span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;dname&quot; : &quot;ACCOUNTING&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;loc&quot; : &quot;NEW YORK&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;emps&quot; :</span></span>
<span class="line"><span style="color: #D4D4D4">  [</span></span>
<span class="line"><span style="color: #D4D4D4">    {</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;empno&quot; : 7782,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;ename&quot; : &quot;CLARK&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;job&quot; : &quot;MANAGER&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;mgr&quot; : 7839,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;mgrname&quot; : &quot;KING&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;hiredate&quot; : &quot;1981-06-09T00:00:00&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;sal&quot; : 2450,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;comm&quot; : null</span></span>
<span class="line"><span style="color: #D4D4D4">    },</span></span>
<span class="line"><span style="color: #D4D4D4">    {</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;empno&quot; : 7839,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;ename&quot; : &quot;KING&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;job&quot; : &quot;PRESIDENT&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;hiredate&quot; : &quot;1981-11-17T00:00:00&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;sal&quot; : 5000,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;comm&quot; : null</span></span>
<span class="line"><span style="color: #D4D4D4">    },</span></span>
<span class="line"><span style="color: #D4D4D4">    {</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;empno&quot; : 7934,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;ename&quot; : &quot;MILLER&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;job&quot; : &quot;CLERK&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;mgr&quot; : 7782,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;mgrname&quot; : &quot;CLARK&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;hiredate&quot; : &quot;1982-01-23T00:00:00&quot;,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;sal&quot; : 1300,</span></span>
<span class="line"><span style="color: #D4D4D4">      &quot;comm&quot; : null</span></span>
<span class="line"><span style="color: #D4D4D4">    }</span></span>
<span class="line"><span style="color: #D4D4D4">  ]</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p>The execution plan of the query above looks like this:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">11) Execution plan querying dept_cv with implicit type conversion</span><span role="button" tabindex="0" data-code="PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------
SQL_ID  gkhradvxjrwfq, child number 4
-------------------------------------
select json_serialize(cv.data returning varchar2 pretty) as json_data   
from dept_cv cv  where cv.data.&quot;_id&quot; = 10
 
Plan hash value: 1318549807
 
--------------------------------------------------------------------------------------
| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |        |       |       |     9 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    10 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | EMP_PK |     1 |       |     0   (0)|          |
|   3 |  SORT GROUP BY              |        |     1 |    38 |            |          |
|*  4 |   TABLE ACCESS FULL         | EMP    |     5 |   190 |     3   (0)| 00:00:01 |
|*  5 |  TABLE ACCESS FULL          | DEPT   |     1 |    20 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access(&quot;OUTER_ALIAS2&quot;.&quot;EMPNO&quot;=:B1)
   4 - filter(&quot;OUTER_ALIAS1&quot;.&quot;DEPTNO&quot;=:B1)
   5 - filter(((&quot;DEPTNO&quot;=10 OR &quot;LOC&quot;='DALLAS') AND 
              JSON_VALUE(JSON_SCALAR(&quot;DEPTNO&quot; JSON NULL ON NULL ) FORMAT OSON , '$' 
              RETURNING NUMBER NULL ON ERROR TYPE(STRICT) )=10))
 
SQL Analysis Report (identified by operation id/Query Block Name/Object Alias):
-------------------------------------------------------------------------------
 
   5 -  SEL$95C0DFA4 / &quot;OUTER_ALIAS0&quot;@&quot;SEL$3&quot;
           -  The following columns have predicates which preclude their 
              use as keys in index range scan. Consider rewriting the 
              predicates.
                &quot;DEPTNO&quot;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">PLAN_TABLE_OUTPUT</span></span>
<span class="line"><span style="color: #D4D4D4">--------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">SQL_ID  gkhradvxjrwfq, child number 4</span></span>
<span class="line"><span style="color: #D4D4D4">-------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">select json_serialize(cv.data returning varchar2 pretty) as json_data   </span></span>
<span class="line"><span style="color: #D4D4D4">from dept_cv cv  where cv.data.&quot;_id&quot; = 10</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Plan hash value: 1318549807</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">--------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">| Id  | Operation                   | Name   | Rows  | Bytes | Cost (%CPU)| Time     |</span></span>
<span class="line"><span style="color: #D4D4D4">--------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">|   0 | SELECT STATEMENT            |        |       |       |     9 (100)|          |</span></span>
<span class="line"><span style="color: #D4D4D4">|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |     1 |    10 |     1   (0)| 00:00:01 |</span></span>
<span class="line"><span style="color: #D4D4D4">|*  2 |   INDEX UNIQUE SCAN         | EMP_PK |     1 |       |     0   (0)|          |</span></span>
<span class="line"><span style="color: #D4D4D4">|   3 |  SORT GROUP BY              |        |     1 |    38 |            |          |</span></span>
<span class="line"><span style="color: #D4D4D4">|*  4 |   TABLE ACCESS FULL         | EMP    |     5 |   190 |     3   (0)| 00:00:01 |</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">|*  5 |  TABLE ACCESS FULL          | DEPT   |     1 |    20 |     3   (0)| 00:00:01 |</span></span>
<span class="line"><span style="color: #D4D4D4">--------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Predicate Information (identified by operation id):</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   2 - access(&quot;OUTER_ALIAS2&quot;.&quot;EMPNO&quot;=:B1)</span></span>
<span class="line"><span style="color: #D4D4D4">   4 - filter(&quot;OUTER_ALIAS1&quot;.&quot;DEPTNO&quot;=:B1)</span></span>
<span class="line"><span style="color: #D4D4D4">   5 - filter(((&quot;DEPTNO&quot;=10 OR &quot;LOC&quot;=&#39;DALLAS&#39;) AND </span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">              JSON_VALUE(JSON_SCALAR(&quot;DEPTNO&quot; JSON NULL ON NULL ) FORMAT OSON , &#39;$&#39; </span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">              RETURNING NUMBER NULL ON ERROR TYPE(STRICT) )=10))</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">SQL Analysis Report (identified by operation id/Query Block Name/Object Alias):</span></span>
<span class="line"><span style="color: #D4D4D4">-------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">   5 -  SEL$95C0DFA4 / &quot;OUTER_ALIAS0&quot;@&quot;SEL$3&quot;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">           -  The following columns have predicates which preclude their </span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">              use as keys in index range scan. Consider rewriting the </span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">              predicates.</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                &quot;DEPTNO&quot;</span></span></code></pre></div>



<p>The SQL analysis report at the bottom is interesting. It clearly states that no index range scan was used and that we should rewrite the query to avoid implicit type conversion.</p>



<p>Let&#8217;s do that.</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#D4D4D4;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">12) Query deptno 10 in dept_cv with explicit type conversion</span><span role="button" tabindex="0" data-code="select json_serialize(cv.data returning varchar2 pretty) as json_data
  from dept_cv cv
 where cv.data.&quot;_id&quot;.number() = 10;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">select</span><span style="color: #D4D4D4"> json_serialize(cv.data </span><span style="color: #569CD6">returning</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">varchar2</span><span style="color: #D4D4D4"> pretty) </span><span style="color: #569CD6">as</span><span style="color: #D4D4D4"> json_data</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">from</span><span style="color: #D4D4D4"> dept_cv cv</span></span>
<span class="line"><span style="color: #D4D4D4"> </span><span style="color: #569CD6">where</span><span style="color: #D4D4D4"> cv.data.</span><span style="color: #CE9178">&quot;_id&quot;</span><span style="color: #D4D4D4">.</span><span style="color: #569CD6">number</span><span style="color: #D4D4D4">() = </span><span style="color: #B5CEA8">10</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<p>And now the execution plan has changed for the better.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-width:calc(1 * 0.6 * .875rem);--cbp-line-highlight-color:rgba(234, 191, 191, 0.2);line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:flex;align-items:center;padding:10px 0px 10px 16px;margin-bottom:-2px;width:100%;text-align:left;background-color:#2b2b2b;color:#c7c7c7">13) Execution plan querying dept_cv with explicit type conversion</span><span role="button" tabindex="0" data-code="PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
SQL_ID  cca5xrgndnmkd, child number 2
-------------------------------------
select json_serialize(cv.data returning varchar2 pretty) as json_data   
from dept_cv cv  where cv.data.&quot;_id&quot;.number() = 10
 
Plan hash value: 2166484641
 
---------------------------------------------------------------------------------------
| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |         |       |       |     7 (100)|          |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP     |     1 |    10 |     1   (0)| 00:00:01 |
|*  2 |   INDEX UNIQUE SCAN         | EMP_PK  |     1 |       |     0   (0)|          |
|   3 |  SORT GROUP BY              |         |     1 |    38 |            |          |
|*  4 |   TABLE ACCESS FULL         | EMP     |     5 |   190 |     3   (0)| 00:00:01 |
|   5 |  TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    20 |     1   (0)| 00:00:01 |
|*  6 |   INDEX UNIQUE SCAN         | DEPT_PK |     1 |       |     0   (0)|          |
---------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access(&quot;OUTER_ALIAS2&quot;.&quot;EMPNO&quot;=:B1)
   4 - filter(&quot;OUTER_ALIAS1&quot;.&quot;DEPTNO&quot;=:B1)
   6 - access(&quot;DEPTNO&quot;=10)" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">PLAN_TABLE_OUTPUT</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">SQL_ID  cca5xrgndnmkd, child number 2</span></span>
<span class="line"><span style="color: #D4D4D4">-------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">select json_serialize(cv.data returning varchar2 pretty) as json_data   </span></span>
<span class="line"><span style="color: #D4D4D4">from dept_cv cv  where cv.data.&quot;_id&quot;.number() = 10</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Plan hash value: 2166484641</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">|   0 | SELECT STATEMENT            |         |       |       |     7 (100)|          |</span></span>
<span class="line"><span style="color: #D4D4D4">|   1 |  TABLE ACCESS BY INDEX ROWID| EMP     |     1 |    10 |     1   (0)| 00:00:01 |</span></span>
<span class="line"><span style="color: #D4D4D4">|*  2 |   INDEX UNIQUE SCAN         | EMP_PK  |     1 |       |     0   (0)|          |</span></span>
<span class="line"><span style="color: #D4D4D4">|   3 |  SORT GROUP BY              |         |     1 |    38 |            |          |</span></span>
<span class="line"><span style="color: #D4D4D4">|*  4 |   TABLE ACCESS FULL         | EMP     |     5 |   190 |     3   (0)| 00:00:01 |</span></span>
<span class="line"><span style="color: #D4D4D4">|   5 |  TABLE ACCESS BY INDEX ROWID| DEPT    |     1 |    20 |     1   (0)| 00:00:01 |</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">|*  6 |   INDEX UNIQUE SCAN         | DEPT_PK |     1 |       |     0   (0)|          |</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">Predicate Information (identified by operation id):</span></span>
<span class="line"><span style="color: #D4D4D4">---------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">   2 - access(&quot;OUTER_ALIAS2&quot;.&quot;EMPNO&quot;=:B1)</span></span>
<span class="line"><span style="color: #D4D4D4">   4 - filter(&quot;OUTER_ALIAS1&quot;.&quot;DEPTNO&quot;=:B1)</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">   6 - access(&quot;DEPTNO&quot;=10)</span></span></code></pre></div>



<p>Making an index unique scan possible.</p>



<h2 class="wp-block-heading" id="conclusion">6. Conclusion</h2>



<p>Always use a <a href="https://docs.oracle.com/en/database/oracle/oracle-database/23/adjsn/sql-json-path-expression-item-methods.html#GUID-8656CAB9-C293-4A99-BB62-F38F3CFC4C13__TABLE_U23_R3C_DSB">SQL/JSON path expression method</a> (<code>binary()</code>, <code>boolean()</code>, <code>date()</code>, <code>dateWithTime()</code>, <code>number()</code>, <code>string()</code>, &#8230;) when comparing a JSON value to a non-JSON value in SQL. This way you avoid implicit type conversions, improve the readability of your code, and give the Oracle Database everything it needs to create an optimal execution plan.</p>



<p></p>
<p>The post <a href="https://www.salvis.com/blog/2025/01/28/avoid-implicit-type-conversion-in-json-access/">Avoid Implicit Type Conversion in JSON Access</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
