<?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>oddgen Archives - Philipp Salvisberg&#039;s Blog</title>
	<atom:link href="https://www.salvis.com/blog/tag/oddgen/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.salvis.com/blog/tag/oddgen/</link>
	<description>Database-centric development</description>
	<lastBuildDate>Wed, 27 Mar 2024 09:53:44 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://www.salvis.com/blog/wp-content/uploads/2014/04/favicon.png</url>
	<title>oddgen Archives - Philipp Salvisberg&#039;s Blog</title>
	<link>https://www.salvis.com/blog/tag/oddgen/</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/oddgen/feed/"/>
	<item>
		<title>View-API for JOOQ Application</title>
		<link>https://www.salvis.com/blog/2018/08/05/view-api-jooq-application/</link>
					<comments>https://www.salvis.com/blog/2018/08/05/view-api-jooq-application/#comments</comments>
		
		<dc:creator><![CDATA[Philipp Salvisberg]]></dc:creator>
		<pubDate>Sun, 05 Aug 2018 20:34:07 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JOOQ]]></category>
		<category><![CDATA[oddgen]]></category>
		<category><![CDATA[PinkDB]]></category>
		<category><![CDATA[PL/SQL]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=8722</guid>

					<description><![CDATA[<p>In this blog post, I show how to build a read-only view-API for Oracle&#8217;s HR sample schema. And I will use this view-API in a JOOQ application. This application will fully comply with the Pink Database Paradigm (PinkDB). This means the application executes set-based SQL and retrieves data with as few network roundtrips as possible.<span class="excerpt-hellip"> […]</span></p>
<p>The post <a href="https://www.salvis.com/blog/2018/08/05/view-api-jooq-application/">View-API for JOOQ Application</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">In this blog post, I show how to build a read-only view-API for Oracle&#8217;s <a href="https://docs.oracle.com/en/database/oracle/oracle-database/18/comsc/introduction-to-sample-schemas.html#GUID-4DE9844F-0B28-4713-9AFC-CCD8D6249D76">HR sample schema</a>. And I will use this view-API in a <a href="https://www.jooq.org/">JOOQ</a> application. This application will fully comply with the <a href="https://www.salvis.com/blog/2018/07/18/the-pink-database-paradigm-pinkdb/">Pink Database Paradigm (PinkDB)</a>. This means the application executes set-based SQL and retrieves data with as few network roundtrips as possible.</p>



<p class="wp-block-paragraph">The following topics are covered:</p>



<ol class="wp-block-list">
<li><a href="#install_sample_schemas">Install Sample Schemas</a></li>



<li><a href="#build_view_api">Build the View-API</a></li>



<li><a href="#create_role">Create the View-API Database Role</a></li>



<li><a href="#create_connect_user">Create the Connect User</a></li>



<li><a href="#install_jooq">Install JOOQ</a></li>



<li><a href="#teach_jooq_view_api">Teach JOOQ the View-API</a></li>



<li><a href="#run_simple_query">Run a Simple Query</a></li>



<li><a href="#using_joins">Using Joins &amp; Aggregations</a></li>



<li><a href="#using_binds">Using Bind Variables</a></li>



<li><a href="#run_top_n_query">Run a Top N Query</a></li>



<li><a href="#using_row_pattern_matching">Using Row Pattern Matching</a></li>



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



<p class="wp-block-paragraph">This is not meant to be a tutorial. However, you should be able to build the application based on the information in this blog post and the referenced links.</p>



<p class="wp-block-paragraph">It&#8217;s the first time I&#8217;ve done anything with JOOQ. I read about it and understood the high-level concepts, but I have never used JOOQ before. This is one reason why this blog post became a bit more verbose. I hope it is helpful.</p>



<h2 class="wp-block-heading"><a name="install_sample_schemas"></a>1. Install Sample Schemas</h2>



<p class="wp-block-paragraph">See the&nbsp;<a href="https://docs.oracle.com/en/database/oracle/oracle-database/18/comsc/installing-sample-schemas.html#GUID-1E645D09-F91F-4BA6-A286-57C5EC66321D">Oracle documentation</a>.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Starting with Oracle Database 12c Release 2, the latest version of the sample schema scripts are available on GitHub at&nbsp;<a class="new-window" href="https://github.com/oracle/db-sample-schemas/releases/latest" target="_blank" rel="noopener noreferrer">https://github.com/oracle/db-sample-schemas/releases/latest</a>. (&#8230;)</p>
</blockquote>



<h2 class="wp-block-heading"><a name="build_view_api"></a>2. Build the View-API</h2>



<h3 class="wp-block-heading">1:1 Views</h3>



<p class="wp-block-paragraph">When building a view API I start with a 1:1 mapping to the table. There are usually some discussions on different topics.</p>



<h3 class="wp-block-heading">Expose Surrogate Keys</h3>



<p class="wp-block-paragraph">One topic is to include surrogate keys or just business keys in the view API. Nowadays, I tend to expose surrogate keys. The main reason is to avoid joins when business key columns are stored in related (parent) tables. Forcing the application to join views via such business key columns is a bad idea from a performance point of view.</p>



<h3 class="wp-block-heading">Convenience Views &#8211; Not a Replacement for 1:1 Views</h3>



<p class="wp-block-paragraph">Another topic is the simplification of the model. For example, provide data from various tables to simplify the usage. Simplification means here sparing the consuming application to use joins. This is sometimes a good idea, but it does not replace the 1:1 views, which are the key to the optimal path to the data. I know about join elimination, but in reality, they often do not work. One reason is that unnecessary columns are queried as well. Another problem is, to force the view to apply selective predicates as early as possible. Sometimes it is necessary to introduce an application context, just for that purpose, making the usage of the view not that simple anymore.</p>



<h3 class="wp-block-heading">Value of a 1:1 View-API</h3>



<p class="wp-block-paragraph">The logical next question is this: Why do we need a view layer when it just provides data the same way as the underlying tables? That&#8217;s an excellent question. I strongly recommend introducing a layer only, when it provides more value than the additional effort. So, what is the value of a 1:1 view layer? Most products evolve during their life cycle. Hence, the data model will most probably change as well. When we have a view layer, we have the option to change the physical data model and keep the existing view layer the same for the consuming applications. From that point on, the views are not a 1:1 representation of tables, at least not in every case.</p>



<p class="wp-block-paragraph">As long as we keep the interface to the application unchanged, we do not have to coordinate changes with the consuming applications. This gives us effective room for refactoring and simplifies going-live scenarios of new releases. Providing additional data and functionality is usually not a problem. However, adapting applications to new interfaces needs time. A view-API, especially if it implements some versioning concept, provides an excellent value in this area.</p>



<h3 class="wp-block-heading">View-API of HR Schema</h3>



<p class="wp-block-paragraph">I&#8217;ve generated the initial version of the 1:1 view layer with <a href="https://www.oddgen.org/">oddgen</a>&#8216;s 1:1 View generator.</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">View-API</span><span role="button" tabindex="0" data-code="ALTER SESSION SET current_schema=hr;

CREATE OR REPLACE VIEW COUNTRIES_V AS
   SELECT COUNTRY_ID,
          COUNTRY_NAME,
          REGION_ID
     FROM COUNTRIES;

CREATE OR REPLACE VIEW DEPARTMENTS_V AS
   SELECT DEPARTMENT_ID,
          DEPARTMENT_NAME,
          MANAGER_ID,
          LOCATION_ID
     FROM DEPARTMENTS;

CREATE OR REPLACE VIEW EMPLOYEES_V AS
   SELECT EMPLOYEE_ID,
          FIRST_NAME,
          LAST_NAME,
          EMAIL,
          PHONE_NUMBER,
          HIRE_DATE,
          JOB_ID,
          SALARY,
          COMMISSION_PCT,
          MANAGER_ID,
          DEPARTMENT_ID
     FROM EMPLOYEES;

CREATE OR REPLACE VIEW JOB_HISTORY_V AS
   SELECT EMPLOYEE_ID,
          START_DATE,
          END_DATE,
          JOB_ID,
          DEPARTMENT_ID
     FROM JOB_HISTORY;

CREATE OR REPLACE VIEW JOBS_V AS
   SELECT JOB_ID,
          JOB_TITLE,
          MIN_SALARY,
          MAX_SALARY
     FROM JOBS;

CREATE OR REPLACE VIEW LOCATIONS_V AS
   SELECT LOCATION_ID,
          STREET_ADDRESS,
          POSTAL_CODE,
          CITY,
          STATE_PROVINCE,
          COUNTRY_ID
     FROM LOCATIONS;

CREATE OR REPLACE VIEW REGIONS_V AS
   SELECT REGION_ID,
          REGION_NAME
     FROM REGIONS;" 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">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SESSION</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SET</span><span style="color: #D4D4D4"> current_schema=hr;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">CREATE OR REPLACE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">COUNTRIES_V</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> COUNTRY_ID,</span></span>
<span class="line"><span style="color: #D4D4D4">          COUNTRY_NAME,</span></span>
<span class="line"><span style="color: #D4D4D4">          REGION_ID</span></span>
<span class="line"><span style="color: #D4D4D4">     </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> COUNTRIES;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">CREATE OR REPLACE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">DEPARTMENTS_V</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> DEPARTMENT_ID,</span></span>
<span class="line"><span style="color: #D4D4D4">          DEPARTMENT_NAME,</span></span>
<span class="line"><span style="color: #D4D4D4">          MANAGER_ID,</span></span>
<span class="line"><span style="color: #D4D4D4">          LOCATION_ID</span></span>
<span class="line"><span style="color: #D4D4D4">     </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> DEPARTMENTS;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">CREATE OR REPLACE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">EMPLOYEES_V</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> EMPLOYEE_ID,</span></span>
<span class="line"><span style="color: #D4D4D4">          FIRST_NAME,</span></span>
<span class="line"><span style="color: #D4D4D4">          LAST_NAME,</span></span>
<span class="line"><span style="color: #D4D4D4">          EMAIL,</span></span>
<span class="line"><span style="color: #D4D4D4">          PHONE_NUMBER,</span></span>
<span class="line"><span style="color: #D4D4D4">          HIRE_DATE,</span></span>
<span class="line"><span style="color: #D4D4D4">          JOB_ID,</span></span>
<span class="line"><span style="color: #D4D4D4">          SALARY,</span></span>
<span class="line"><span style="color: #D4D4D4">          COMMISSION_PCT,</span></span>
<span class="line"><span style="color: #D4D4D4">          MANAGER_ID,</span></span>
<span class="line"><span style="color: #D4D4D4">          DEPARTMENT_ID</span></span>
<span class="line"><span style="color: #D4D4D4">     </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> EMPLOYEES;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">CREATE OR REPLACE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">JOB_HISTORY_V</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> EMPLOYEE_ID,</span></span>
<span class="line"><span style="color: #D4D4D4">          </span><span style="color: #569CD6">START_DATE</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">          END_DATE,</span></span>
<span class="line"><span style="color: #D4D4D4">          JOB_ID,</span></span>
<span class="line"><span style="color: #D4D4D4">          DEPARTMENT_ID</span></span>
<span class="line"><span style="color: #D4D4D4">     </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> JOB_HISTORY;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">CREATE OR REPLACE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">JOBS_V</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> JOB_ID,</span></span>
<span class="line"><span style="color: #D4D4D4">          JOB_TITLE,</span></span>
<span class="line"><span style="color: #D4D4D4">          MIN_SALARY,</span></span>
<span class="line"><span style="color: #D4D4D4">          MAX_SALARY</span></span>
<span class="line"><span style="color: #D4D4D4">     </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> JOBS;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">CREATE OR REPLACE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">LOCATIONS_V</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> LOCATION_ID,</span></span>
<span class="line"><span style="color: #D4D4D4">          STREET_ADDRESS,</span></span>
<span class="line"><span style="color: #D4D4D4">          POSTAL_CODE,</span></span>
<span class="line"><span style="color: #D4D4D4">          CITY,</span></span>
<span class="line"><span style="color: #D4D4D4">          STATE_PROVINCE,</span></span>
<span class="line"><span style="color: #D4D4D4">          COUNTRY_ID</span></span>
<span class="line"><span style="color: #D4D4D4">     </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> LOCATIONS;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">CREATE OR REPLACE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">REGIONS_V</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> REGION_ID,</span></span>
<span class="line"><span style="color: #D4D4D4">          REGION_NAME</span></span>
<span class="line"><span style="color: #D4D4D4">     </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> REGIONS;</span></span></code></pre></div>



<h3 class="wp-block-heading">View Constraints</h3>



<p class="wp-block-paragraph">When building a view-API it is a good idea to also define primary key, foreign key and unique constraints for these views. They will not be enforced by the Oracle database, but they are an excellent documentation. Furthermore, they will be used by JOOQ as we see later.</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">View Constraints</span><span role="button" tabindex="0" data-code="ALTER SESSION SET current_schema=hr;

-- primary key and unique constraints
ALTER VIEW countries_v   ADD PRIMARY KEY (country_id)              DISABLE NOVALIDATE;
ALTER VIEW departments_v ADD PRIMARY KEY (department_id)           DISABLE NOVALIDATE;
ALTER VIEW employees_v   ADD PRIMARY KEY (employee_id)             DISABLE NOVALIDATE;
ALTER VIEW employees_v   ADD UNIQUE      (email)                   DISABLE NOVALIDATE;
ALTER VIEW job_history_v ADD PRIMARY KEY (employee_id, start_date) DISABLE NOVALIDATE;
ALTER VIEW jobs_v        ADD PRIMARY KEY (job_id)                  DISABLE NOVALIDATE;
ALTER VIEW locations_v   ADD PRIMARY KEY (location_id)             DISABLE NOVALIDATE;
ALTER VIEW regions_v     ADD PRIMARY KEY (region_id)               DISABLE NOVALIDATE;

-- foreign key constraints
ALTER VIEW countries_v   ADD FOREIGN KEY (region_id)     REFERENCES hr.regions_v     DISABLE NOVALIDATE;
ALTER VIEW departments_v ADD FOREIGN KEY (location_id)   REFERENCES hr.locations_v   DISABLE NOVALIDATE;
ALTER VIEW departments_v ADD FOREIGN KEY (manager_id)    REFERENCES hr.employees_v   DISABLE NOVALIDATE;
ALTER VIEW employees_v   ADD FOREIGN KEY (department_id) REFERENCES hr.departments_v DISABLE NOVALIDATE;
ALTER VIEW employees_v   ADD FOREIGN KEY (job_id)        REFERENCES hr.jobs_v        DISABLE NOVALIDATE;
ALTER VIEW employees_v   ADD FOREIGN KEY (manager_id)    REFERENCES hr.employees_v   DISABLE NOVALIDATE;
ALTER VIEW job_history_v ADD FOREIGN KEY (department_id) REFERENCES hr.departments_v DISABLE NOVALIDATE;
ALTER VIEW job_history_v ADD FOREIGN KEY (employee_id)   REFERENCES hr.employees_v   DISABLE NOVALIDATE;
ALTER VIEW job_history_v ADD FOREIGN KEY (job_id)        REFERENCES hr.jobs_v        DISABLE NOVALIDATE;
ALTER VIEW locations_v   ADD FOREIGN KEY (country_id)    REFERENCES hr.countries_v   DISABLE NOVALIDATE;" 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">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SESSION</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">SET</span><span style="color: #D4D4D4"> current_schema=hr;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- primary key and unique constraints</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> countries_v   </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">PRIMARY KEY</span><span style="color: #D4D4D4"> (country_id)              </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> departments_v </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">PRIMARY KEY</span><span style="color: #D4D4D4"> (department_id)           </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> employees_v   </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">PRIMARY KEY</span><span style="color: #D4D4D4"> (employee_id)             </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> employees_v   </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">UNIQUE</span><span style="color: #D4D4D4">      (email)                   </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> job_history_v </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">PRIMARY KEY</span><span style="color: #D4D4D4"> (employee_id, </span><span style="color: #569CD6">start_date</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> jobs_v        </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">PRIMARY KEY</span><span style="color: #D4D4D4"> (job_id)                  </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> locations_v   </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">PRIMARY KEY</span><span style="color: #D4D4D4"> (location_id)             </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> regions_v     </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">PRIMARY KEY</span><span style="color: #D4D4D4"> (region_id)               </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955">-- foreign key constraints</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> countries_v   </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FOREIGN KEY</span><span style="color: #D4D4D4"> (region_id)     </span><span style="color: #569CD6">REFERENCES</span><span style="color: #D4D4D4"> hr.regions_v     </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> departments_v </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FOREIGN KEY</span><span style="color: #D4D4D4"> (location_id)   </span><span style="color: #569CD6">REFERENCES</span><span style="color: #D4D4D4"> hr.locations_v   </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> departments_v </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FOREIGN KEY</span><span style="color: #D4D4D4"> (manager_id)    </span><span style="color: #569CD6">REFERENCES</span><span style="color: #D4D4D4"> hr.employees_v   </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> employees_v   </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FOREIGN KEY</span><span style="color: #D4D4D4"> (department_id) </span><span style="color: #569CD6">REFERENCES</span><span style="color: #D4D4D4"> hr.departments_v </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> employees_v   </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FOREIGN KEY</span><span style="color: #D4D4D4"> (job_id)        </span><span style="color: #569CD6">REFERENCES</span><span style="color: #D4D4D4"> hr.jobs_v        </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> employees_v   </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FOREIGN KEY</span><span style="color: #D4D4D4"> (manager_id)    </span><span style="color: #569CD6">REFERENCES</span><span style="color: #D4D4D4"> hr.employees_v   </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> job_history_v </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FOREIGN KEY</span><span style="color: #D4D4D4"> (department_id) </span><span style="color: #569CD6">REFERENCES</span><span style="color: #D4D4D4"> hr.departments_v </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> job_history_v </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FOREIGN KEY</span><span style="color: #D4D4D4"> (employee_id)   </span><span style="color: #569CD6">REFERENCES</span><span style="color: #D4D4D4"> hr.employees_v   </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> job_history_v </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FOREIGN KEY</span><span style="color: #D4D4D4"> (job_id)        </span><span style="color: #569CD6">REFERENCES</span><span style="color: #D4D4D4"> hr.jobs_v        </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">VIEW</span><span style="color: #D4D4D4"> locations_v   </span><span style="color: #569CD6">ADD</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">FOREIGN KEY</span><span style="color: #D4D4D4"> (country_id)    </span><span style="color: #569CD6">REFERENCES</span><span style="color: #D4D4D4"> hr.countries_v   </span><span style="color: #569CD6">DISABLE</span><span style="color: #D4D4D4"> NOVALIDATE;</span></span></code></pre></div>



<h3 class="wp-block-heading">View-API Model</h3>



<p class="wp-block-paragraph">I created the following relational model with Oracle&#8217;s SQL Developer.&nbsp;SQL Developer automatically took into account all constraints defined on these 7 views. Most of the work was to rearrange the view boxes on the diagram,&nbsp;but with only 7 views it was no big deal.</p>



<figure class="wp-block-image"><a href="https://www.salvis.com/blog/wp-content/uploads/2018/08/HR-View-API.png"><img fetchpriority="high" decoding="async" width="949" height="657" src="https://www.salvis.com/blog/wp-content/uploads/2018/08/HR-View-API.png" alt="HR View-API" class="wp-image-8745" srcset="https://www.salvis.com/blog/wp-content/uploads/2018/08/HR-View-API.png 949w, https://www.salvis.com/blog/wp-content/uploads/2018/08/HR-View-API-300x208.png 300w, https://www.salvis.com/blog/wp-content/uploads/2018/08/HR-View-API-768x532.png 768w, https://www.salvis.com/blog/wp-content/uploads/2018/08/HR-View-API-211x146.png 211w, https://www.salvis.com/blog/wp-content/uploads/2018/08/HR-View-API-50x35.png 50w, https://www.salvis.com/blog/wp-content/uploads/2018/08/HR-View-API-108x75.png 108w" sizes="(max-width:767px) 480px, (max-width:949px) 100vw, 949px" /></a></figure>



<h2 class="wp-block-heading"><a name="create_role"></a>3. Create the View-API Database Role</h2>



<p class="wp-block-paragraph">We grant read access to all views as part of the API to the database role <code>HR_API_ROLE</code>. This is easier to maintain, especially when access to more than one connect user is granted.</p>



<p class="wp-block-paragraph">Please note that just <code>READ</code> access is granted on the views. We do not grant <code>SELECT</code> access to ensure that data can&#8217;t be locked by the connect users via <code>SELECT FOR UPDATE</code>.&nbsp; The <code>READ</code> privilege was introduced in Oracle Database 12c.</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">HR_API_ROLE</span><span role="button" tabindex="0" data-code="CREATE ROLE hr_api_role;

GRANT READ ON hr.countries_v   TO hr_api_role;
GRANT READ ON hr.departments_v TO hr_api_role;
GRANT READ ON hr.employees_v   TO hr_api_role;
GRANT READ ON hr.job_history_v TO hr_api_role;
GRANT READ ON hr.jobs_v        TO hr_api_role;
GRANT READ ON hr.locations_v   TO hr_api_role;
GRANT READ ON hr.regions_v     TO hr_api_role;" 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</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ROLE</span><span style="color: #D4D4D4"> hr_api_role;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">READ</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> hr.countries_v   </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> hr_api_role;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">READ</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> hr.departments_v </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> hr_api_role;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">READ</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> hr.employees_v   </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> hr_api_role;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">READ</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> hr.job_history_v </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> hr_api_role;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">READ</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> hr.jobs_v        </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> hr_api_role;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">READ</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> hr.locations_v   </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> hr_api_role;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">READ</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> hr.regions_v     </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> hr_api_role;</span></span></code></pre></div>



<p class="wp-block-paragraph">In this case, it does not make sense to define more than one role. But for larger projects, it might be helpful to create more roles. For example to distinguish between read and write roles or to manage access to sensitive data explicitly.</p>



<h2 class="wp-block-heading"><a name="create_connect_user"></a>4. Create the Connect User</h2>



<p class="wp-block-paragraph">Now we create a connect user named <code>JOOQ</code>. It will have the right to connect, access the view-API and execute the procedures in the <code>SYS.DBMS_MONITOR</code> package. The access to <code>DBMS_MONITOR</code> is given only to enable SQL Trace for some analysis on the database server.</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">Create Connect User JOOQ</span><span role="button" tabindex="0" data-code="CREATE USER jooq IDENTIFIED BY jooq;
GRANT connect, hr_api_role TO jooq;
GRANT EXECUTE ON sys.dbms_monitor TO jooq;" 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</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">USER</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">jooq</span><span style="color: #D4D4D4"> IDENTIFIED </span><span style="color: #569CD6">BY</span><span style="color: #D4D4D4"> jooq;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">connect</span><span style="color: #D4D4D4">, hr_api_role </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> jooq;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">EXECUTE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> sys.dbms_monitor </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> jooq;</span></span></code></pre></div>



<h2 class="wp-block-heading"><a name="install_jooq"></a>5. Install JOOQ</h2>



<p class="wp-block-paragraph"><a href="https://www.jooq.org/download/">Download</a> the trial version of JOOQ Professional for free. The trial period is 30 days. Registration is not required.</p>



<p class="wp-block-paragraph">JOOQ comes with an excellent documentation. In fact, I kept the PDF version open during all my tests and found everything I needed using the search function. After extracting the downloaded ZIP file, I run the following commands on my macOS system:</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">Install JOOQ in Local Maven Repository</span><span role="button" tabindex="0" data-code="chmod +x maven-deploy.sh
./maven-deploy.sh -u file:///Users/phs/.m2/repository" 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: #DCDCAA">chmod</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">+x</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">maven-deploy.sh</span></span>
<span class="line"><span style="color: #DCDCAA">./maven-deploy.sh</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-u</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">file:///Users/phs/.m2/repository</span></span></code></pre></div>



<p class="wp-block-paragraph">This deployed JOOQ in my local Maven repository. Run <code>./maven-deploy.sh -h</code> for command line options, e.g. when you want to deploy it on your Sonatype Nexus repository.</p>



<h2 class="wp-block-heading"><a name="teach_jooq_view_api"></a>6. Teach JOOQ the View-API</h2>



<p class="wp-block-paragraph">JOOQ allows to build SQL and execute SQL statements in a typesafe manner. It&#8217;s similar to SQL within PL/SQL. You avoid to build SQL using string concatenation. Instead, you use the JOOQ domain-specific language (DSL) that knows about SQL and can learn about your database model. For example, JOOQ must learn that <code>JOBS_V</code> is a view and <code>JOB_ID</code> is its primary key column.</p>



<p class="wp-block-paragraph">Technically JOOQ reads the data dictionary and generates a set of Java classes for you. You may call the generator via command line using a XML configuration file or use the JOOQ Maven plugin to configure the generator directly in your <code>pom.xml</code>. You may also generate these classes via Ant or Gradle. I&#8217;ve used the Maven plugin to include the code generation process in my project build.</p>



<p class="wp-block-paragraph">On lines 36-38, we define the JDBC driver.</p>



<p class="wp-block-paragraph">On lines 43-46, we configure the JDBC URL and the credentials of the connect user.</p>



<p class="wp-block-paragraph">Line 50 tells JOOQ to use the Oracle meta-model and line 51 is a regular expression to define the generation scope. In our case the visible objects in the <code>HR</code> schema and the PL/SQL package <code>SYS.DBMS_MONITOR</code>. Using the default would generate Java code for all public objects.</p>



<p class="wp-block-paragraph">Finally, on lines 54-55, we define the target directory for the generated Java classes and their Java package name.</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">XML</span><span role="button" tabindex="0" data-code="<project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
   xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
   <modelVersion&gt;4.0.0</modelVersion&gt;
   <groupId&gt;com.trivadis.pinkdb.jooq</groupId&gt;
   <artifactId&gt;jooq-pinkdb</artifactId&gt;
   <version&gt;0.0.1-SNAPSHOT</version&gt;
   <properties&gt;
      <project.build.sourceEncoding&gt;UTF-8</project.build.sourceEncoding&gt;
      <jdk.version&gt;1.8</jdk.version&gt;
      <xtend.version&gt;2.12.0</xtend.version&gt;
   </properties&gt;
   <build&gt;
      <plugins&gt;
         <plugin&gt;
            <groupId&gt;org.apache.maven.plugins</groupId&gt;
            <version&gt;3.8.0</version&gt;
            <artifactId&gt;maven-compiler-plugin</artifactId&gt;
            <configuration&gt;
               <source&gt;${jdk.version}</source&gt;
               <target&gt;${jdk.version}</target&gt;
            </configuration&gt;
         </plugin&gt;
         <plugin&gt;
            <groupId&gt;org.jooq.trial</groupId&gt;
            <artifactId&gt;jooq-codegen-maven</artifactId&gt;
            <version&gt;3.11.3</version&gt;
            <executions&gt;
               <execution&gt;
                  <goals&gt;
                     <goal&gt;generate</goal&gt;
                  </goals&gt;
               </execution&gt;
            </executions&gt;
            <dependencies&gt;
               <dependency&gt;
                  <groupId&gt;oracle</groupId&gt;
                  <artifactId&gt;ojdbc8</artifactId&gt;
                  <version&gt;12.2.0.1.0</version&gt;
               </dependency&gt;
            </dependencies&gt;
            <configuration&gt;
               <jdbc&gt;
                  <driver&gt;oracle.jdbc.OracleDriver</driver&gt;
                  <url&gt;jdbc:oracle:thin:@localhost:1521/odb.docker</url&gt;
                  <user&gt;jooq</user&gt;
                  <password&gt;jooq</password&gt;
               </jdbc&gt;
               <generator&gt;
                  <database&gt;
                     <name&gt;org.jooq.meta.oracle.OracleDatabase</name&gt;
                     <includes&gt;HR\..*|SYS\.DBMS_MONITOR</includes&gt;
                  </database&gt;
                  <target&gt;
                     <packageName&gt;com.trivadis.jooq.pinkdb.model.generated</packageName&gt;
                     <directory&gt;src/main/java</directory&gt;
                  </target&gt;
               </generator&gt;
            </configuration&gt;
         </plugin&gt;
      </plugins&gt;
   </build&gt;
   <dependencies&gt;
      <dependency&gt;
         <groupId&gt;org.jooq.trial</groupId&gt;
         <artifactId&gt;jooq</artifactId&gt;
         <version&gt;3.11.3</version&gt;
      </dependency&gt;
      <dependency&gt;
         <groupId&gt;oracle</groupId&gt;
         <artifactId&gt;ojdbc8</artifactId&gt;
         <version&gt;12.2.0.1.0</version&gt;
      </dependency&gt;
   </dependencies&gt;
</project&gt;" 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: #808080">&lt;</span><span style="color: #569CD6">project</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">xmlns</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;http://maven.apache.org/POM/4.0.0&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">xmlns:xsi</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;http://www.w3.org/2001/XMLSchema-instance&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #9CDCFE">xsi:schemaLocation</span><span style="color: #D4D4D4">=</span><span style="color: #CE9178">&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">modelVersion</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">4.0.0</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">modelVersion</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">com.trivadis.pinkdb.jooq</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">jooq-pinkdb</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">0.0.1-SNAPSHOT</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">properties</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">project.build.sourceEncoding</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">UTF-8</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">project.build.sourceEncoding</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">jdk.version</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">1.8</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">jdk.version</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">xtend.version</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">2.12.0</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">xtend.version</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">properties</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">build</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">plugins</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">plugin</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">org.apache.maven.plugins</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">3.8.0</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">maven-compiler-plugin</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">configuration</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">               </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">source</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">${jdk.version}</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">source</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">               </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">target</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">${jdk.version}</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">target</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">configuration</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">plugin</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">plugin</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">org.jooq.trial</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">jooq-codegen-maven</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">3.11.3</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">executions</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">               </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">execution</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">goals</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">                     </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">goal</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">generate</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">goal</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">goals</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">               </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">execution</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">executions</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">dependencies</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">               </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">dependency</span><span style="color: #808080">&gt;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">oracle</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">ojdbc8</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">12.2.0.1.0</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">               </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">dependency</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">dependencies</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">configuration</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">               </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">jdbc</span><span style="color: #808080">&gt;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">driver</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">oracle.jdbc.OracleDriver</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">driver</span><span style="color: #808080">&gt;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">url</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">jdbc:oracle:thin:@localhost:1521/odb.docker</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">url</span><span style="color: #808080">&gt;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">user</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">jooq</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">user</span><span style="color: #808080">&gt;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">password</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">jooq</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">password</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">               </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">jdbc</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">               </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">generator</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">database</span><span style="color: #808080">&gt;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                     </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">name</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">org.jooq.meta.oracle.OracleDatabase</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">name</span><span style="color: #808080">&gt;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                     </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">includes</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">HR\..*|SYS\.DBMS_MONITOR</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">includes</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">database</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">target</span><span style="color: #808080">&gt;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                     </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">packageName</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">com.trivadis.jooq.pinkdb.model.generated</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">packageName</span><span style="color: #808080">&gt;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                     </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">directory</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">src/main/java</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">directory</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">target</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">               </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">generator</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">configuration</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">plugin</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">plugins</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">build</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">dependencies</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">dependency</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">org.jooq.trial</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">jooq</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">3.11.3</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">dependency</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">dependency</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">oracle</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">groupId</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">ojdbc8</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">artifactId</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #808080">&lt;</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span><span style="color: #D4D4D4">12.2.0.1.0</span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">version</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">dependency</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #808080">&lt;/</span><span style="color: #569CD6">dependencies</span><span style="color: #808080">&gt;</span></span>
<span class="line"><span style="color: #808080">&lt;/</span><span style="color: #569CD6">project</span><span style="color: #808080">&gt;</span></span></code></pre></div>



<p class="wp-block-paragraph">Here&#8217;s the excerpt of the console output (of <code>mvn package</code>) regarding the generation run:</p>


<div class="accordion"><div class="mfn-acc accordion_wrapper "><br />
<div class="question"><div class="title"><i class="icon-plus acc-icon-plus" aria-hidden="true"></i><i class="icon-minus acc-icon-minus" aria-hidden="true"></i>JOOQ generator output</div><div class="answer"></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(3 * 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">JOOQ Generator Output</span><span role="button" tabindex="0" data-code="&#091;INFO&#093; --- jooq-codegen-maven:3.11.3:generate (default) @ jooq-pinkdb ---
&#091;INFO&#093; No &lt;inputCatalog/&gt; was provided. Generating ALL available catalogs instead.
&#091;INFO&#093; No &lt;inputSchema/&gt; was provided. Generating ALL available schemata instead.
&#091;INFO&#093; License parameters       
&#091;INFO&#093; ----------------------------------------------------------
&#091;INFO&#093;   Thank you for using jOOQ and jOOQ's code generator
&#091;INFO&#093;                          
&#091;INFO&#093; Database parameters      
&#091;INFO&#093; ----------------------------------------------------------
&#091;INFO&#093;   dialect                : ORACLE
&#091;INFO&#093;   URL                    : jdbc:oracle:thin:@localhost:1521/odb.docker
&#091;INFO&#093;   target dir             : /Users/phs/git/JooqPinkDB/src/main/java
&#091;INFO&#093;   target package         : com.trivadis.jooq.pinkdb.model.generated
&#091;INFO&#093;   includes               : &#091;HR\..*|SYS\.DBMS_MONITOR&#093;
&#091;INFO&#093;   excludes               : &#091;&#093;
&#091;INFO&#093;   includeExcludeColumns  : false
&#091;INFO&#093; ----------------------------------------------------------
&#091;INFO&#093;                          
&#091;INFO&#093; JavaGenerator parameters 
&#091;INFO&#093; ----------------------------------------------------------
&#091;INFO&#093;   annotations (generated): true
&#091;INFO&#093;   annotations (JPA: any) : false
&#091;INFO&#093;   annotations (JPA: version): 
&#091;INFO&#093;   annotations (validation): false
&#091;INFO&#093;   comments               : true
&#091;INFO&#093;   comments on attributes : true
&#091;INFO&#093;   comments on catalogs   : true
&#091;INFO&#093;   comments on columns    : true
&#091;INFO&#093;   comments on keys       : true
&#091;INFO&#093;   comments on links      : true
&#091;INFO&#093;   comments on packages   : true
&#091;INFO&#093;   comments on parameters : true
&#091;INFO&#093;   comments on queues     : true
&#091;INFO&#093;   comments on routines   : true
&#091;INFO&#093;   comments on schemas    : true
&#091;INFO&#093;   comments on sequences  : true
&#091;INFO&#093;   comments on tables     : true
&#091;INFO&#093;   comments on udts       : true
&#091;INFO&#093;   daos                   : false
&#091;INFO&#093;   deprecated code        : true
&#091;INFO&#093;   global references (any): true
&#091;INFO&#093;   global references (catalogs): true
&#091;INFO&#093;   global references (keys): true
&#091;INFO&#093;   global references (links): true
&#091;INFO&#093;   global references (queues): true
&#091;INFO&#093;   global references (routines): true
&#091;INFO&#093;   global references (schemas): true
&#091;INFO&#093;   global references (sequences): true
&#091;INFO&#093;   global references (tables): true
&#091;INFO&#093;   global references (udts): true
&#091;INFO&#093;   indexes                : true
&#091;INFO&#093;   instance fields        : true
&#091;INFO&#093;   interfaces             : false
&#091;INFO&#093;   interfaces (immutable) : false
&#091;INFO&#093;   javadoc                : true
&#091;INFO&#093;   keys                   : true
&#091;INFO&#093;   links                  : true
&#091;INFO&#093;   pojos                  : false
&#091;INFO&#093;   pojos (immutable)      : false
&#091;INFO&#093;   queues                 : true
&#091;INFO&#093;   records                : true
&#091;INFO&#093;   routines               : true
&#091;INFO&#093;   sequences              : true
&#091;INFO&#093;   table-valued functions : false
&#091;INFO&#093;   tables                 : true
&#091;INFO&#093;   udts                   : true
&#091;INFO&#093;   relations              : true
&#091;INFO&#093; ----------------------------------------------------------
&#091;INFO&#093;                          
&#091;INFO&#093; Generation remarks       
&#091;INFO&#093; ----------------------------------------------------------
&#091;INFO&#093;                          
&#091;INFO&#093; ----------------------------------------------------------
&#091;INFO&#093; Generating catalogs      : Total: 1
&#091;INFO&#093; 
                                      
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@  @@        @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@
@@@@@@@@@@@@@@@@  @@  @@    @@@@@@@@@@
@@@@@@@@@@  @@@@  @@  @@    @@@@@@@@@@
@@@@@@@@@@        @@        @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@        @@        @@@@@@@@@@
@@@@@@@@@@    @@  @@  @@@@  @@@@@@@@@@
@@@@@@@@@@    @@  @@  @@@@  @@@@@@@@@@
@@@@@@@@@@        @@  @  @  @@@@@@@@@@
@@@@@@@@@@        @@        @@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  Thank you for using the 30 day free jOOQ 3.11.3 trial edition
                                      
&#091;INFO&#093; Packages fetched         : 517 (1 included, 516 excluded)
&#091;INFO&#093; Applying synonym         : &quot;PUBLIC&quot;.&quot;KU$_LOGENTRY&quot; is synonym for &quot;SYS&quot;.&quot;KU$_LOGENTRY1010&quot;
&#091;INFO&#093; Applying synonym         : &quot;PUBLIC&quot;.&quot;XMLTYPE&quot; is synonym for &quot;SYS&quot;.&quot;XMLTYPE&quot;
&#091;INFO&#093; ARRAYs fetched           : 641 (0 included, 641 excluded)
&#091;INFO&#093; Enums fetched            : 0 (0 included, 0 excluded)
&#091;INFO&#093; No schema version is applied for catalog . Regenerating.
&#091;INFO&#093;                          
&#091;INFO&#093; Generating catalog       : DefaultCatalog.java
&#091;INFO&#093; ==========================================================
&#091;INFO&#093; Routines fetched         : 312 (0 included, 312 excluded)
&#091;INFO&#093; Tables fetched           : 2347 (7 included, 2340 excluded)
&#091;INFO&#093; UDTs fetched             : 1287 (0 included, 1287 excluded)
&#091;INFO&#093; Generating schemata      : Total: 63
&#091;INFO&#093; No schema version is applied for schema SYS. Regenerating.
&#091;INFO&#093; Generating schema        : Sys.java
&#091;INFO&#093; ----------------------------------------------------------
&#091;INFO&#093; Sequences fetched        : 12 (0 included, 12 excluded)
&#091;INFO&#093; Domains fetched          : 0 (0 included, 0 excluded)
&#091;INFO&#093; Generating packages      
&#091;INFO&#093; Generating package       : SYS.DBMS_MONITOR
&#091;INFO&#093; Generating routine       : ClientIdStatDisable.java
&#091;INFO&#093; Generating routine       : ClientIdStatEnable.java
&#091;INFO&#093; Generating routine       : ClientIdTraceDisable.java
&#091;INFO&#093; Generating routine       : ClientIdTraceEnable.java
&#091;INFO&#093; Generating routine       : DatabaseTraceDisable.java
&#091;INFO&#093; Generating routine       : DatabaseTraceEnable.java
&#091;INFO&#093; Generating routine       : ServModActStatDisable.java
&#091;INFO&#093; Generating routine       : ServModActStatEnable.java
&#091;INFO&#093; Generating routine       : ServModActTraceDisable.java
&#091;INFO&#093; Generating routine       : ServModActTraceEnable.java
&#091;INFO&#093; Generating routine       : SessionTraceDisable.java
&#091;INFO&#093; Generating routine       : SessionTraceEnable.java
&#091;INFO&#093; Packages generated       : Total: 7.009s
&#091;INFO&#093; UDT not supported or not in input schemata: SYS.SCHEDULER$_EVENT_INFO
&#091;INFO&#093; UDT not supported or not in input schemata: SYS.SCHEDULER_FILEWATCHER_RESULT
&#091;INFO&#093; Queues fetched           : 0 (0 included, 0 excluded)
&#091;INFO&#093; Links fetched            : 0 (0 included, 0 excluded)
&#091;INFO&#093; Generation finished: SYS : Total: 7.482s, +473.374ms
&#091;INFO&#093;                          
&#091;INFO&#093; Excluding empty schema   : AUDSYS
&#091;INFO&#093; Excluding empty schema   : SYSTEM
&#091;INFO&#093; Excluding empty schema   : SYSBACKUP
&#091;INFO&#093; Excluding empty schema   : SYSDG
&#091;INFO&#093; Excluding empty schema   : SYSKM
&#091;INFO&#093; Excluding empty schema   : SYSRAC
&#091;INFO&#093; Excluding empty schema   : OUTLN
&#091;INFO&#093; Excluding empty schema   : XS$NULL
&#091;INFO&#093; Excluding empty schema   : GSMADMIN_INTERNAL
&#091;INFO&#093; Excluding empty schema   : GSMUSER
&#091;INFO&#093; Excluding empty schema   : DIP
&#091;INFO&#093; Excluding empty schema   : REMOTE_SCHEDULER_AGENT
&#091;INFO&#093; Excluding empty schema   : DBSFWUSER
&#091;INFO&#093; Excluding empty schema   : ORACLE_OCM
&#091;INFO&#093; Excluding empty schema   : SYS$UMF
&#091;INFO&#093; Excluding empty schema   : DBSNMP
&#091;INFO&#093; Excluding empty schema   : APPQOSSYS
&#091;INFO&#093; Excluding empty schema   : GSMCATUSER
&#091;INFO&#093; Excluding empty schema   : GGSYS
&#091;INFO&#093; Excluding empty schema   : XDB
&#091;INFO&#093; Excluding empty schema   : ANONYMOUS
&#091;INFO&#093; Excluding empty schema   : WMSYS
&#091;INFO&#093; Excluding empty schema   : DVF
&#091;INFO&#093; Excluding empty schema   : OJVMSYS
&#091;INFO&#093; Excluding empty schema   : CTXSYS
&#091;INFO&#093; Excluding empty schema   : ORDSYS
&#091;INFO&#093; Excluding empty schema   : ORDDATA
&#091;INFO&#093; Excluding empty schema   : ORDPLUGINS
&#091;INFO&#093; Excluding empty schema   : SI_INFORMTN_SCHEMA
&#091;INFO&#093; Excluding empty schema   : MDSYS
&#091;INFO&#093; Excluding empty schema   : OLAPSYS
&#091;INFO&#093; Excluding empty schema   : MDDATA
&#091;INFO&#093; Excluding empty schema   : LBACSYS
&#091;INFO&#093; Excluding empty schema   : DVSYS
&#091;INFO&#093; Excluding empty schema   : FLOWS_FILES
&#091;INFO&#093; Excluding empty schema   : APEX_PUBLIC_USER
&#091;INFO&#093; Excluding empty schema   : APEX_180100
&#091;INFO&#093; Excluding empty schema   : APEX_INSTANCE_ADMIN_USER
&#091;INFO&#093; Excluding empty schema   : APEX_LISTENER
&#091;INFO&#093; Excluding empty schema   : APEX_REST_PUBLIC_USER
&#091;INFO&#093; Excluding empty schema   : ORDS_METADATA
&#091;INFO&#093; Excluding empty schema   : ORDS_PUBLIC_USER
&#091;INFO&#093; Excluding empty schema   : SCOTT
&#091;INFO&#093; No schema version is applied for schema HR. Regenerating.
&#091;INFO&#093; Generating schema        : Hr.java
&#091;INFO&#093; ----------------------------------------------------------
&#091;INFO&#093; Generating tables        
&#091;INFO&#093; Adding foreign key       : SYS_C0012240 (HR.COUNTRIES_V.REGION_ID) referencing SYS_C0012239
&#091;INFO&#093; Adding foreign key       : SYS_C0012241 (HR.DEPARTMENTS_V.LOCATION_ID) referencing SYS_C0012238
&#091;INFO&#093; Adding foreign key       : SYS_C0012242 (HR.DEPARTMENTS_V.MANAGER_ID) referencing SYS_C0012235
&#091;INFO&#093; Adding foreign key       : SYS_C0012244 (HR.EMPLOYEES_V.DEPARTMENT_ID) referencing SYS_C0012234
&#091;INFO&#093; Adding foreign key       : SYS_C0012245 (HR.EMPLOYEES_V.JOB_ID) referencing SYS_C0012237
&#091;INFO&#093; Adding foreign key       : SYS_C0012246 (HR.EMPLOYEES_V.MANAGER_ID) referencing SYS_C0012235
&#091;INFO&#093; Adding foreign key       : SYS_C0012247 (HR.JOB_HISTORY_V.DEPARTMENT_ID) referencing SYS_C0012234
&#091;INFO&#093; Adding foreign key       : SYS_C0012248 (HR.JOB_HISTORY_V.EMPLOYEE_ID) referencing SYS_C0012235
&#091;INFO&#093; Adding foreign key       : SYS_C0012249 (HR.JOB_HISTORY_V.JOB_ID) referencing SYS_C0012237
&#091;INFO&#093; Adding foreign key       : SYS_C0012250 (HR.LOCATIONS_V.COUNTRY_ID) referencing SYS_C0012233
&#091;INFO&#093; Synthetic primary keys   : 0 (0 included, 0 excluded)
&#091;INFO&#093; Overriding primary keys  : 8 (0 included, 8 excluded)
&#091;INFO&#093; Generating table         : CountriesV.java &#091;input=COUNTRIES_V, output=COUNTRIES_V, pk=SYS_C0012233&#093;
&#091;INFO&#093; Indexes fetched          : 0 (0 included, 0 excluded)
&#091;INFO&#093; Generating table         : DepartmentsV.java &#091;input=DEPARTMENTS_V, output=DEPARTMENTS_V, pk=SYS_C0012234&#093;
&#091;INFO&#093; Generating table         : EmployeesV.java &#091;input=EMPLOYEES_V, output=EMPLOYEES_V, pk=SYS_C0012235&#093;
&#091;INFO&#093; Generating table         : JobsV.java &#091;input=JOBS_V, output=JOBS_V, pk=SYS_C0012237&#093;
&#091;INFO&#093; Generating table         : JobHistoryV.java &#091;input=JOB_HISTORY_V, output=JOB_HISTORY_V, pk=SYS_C0012236&#093;
&#091;INFO&#093; Generating table         : LocationsV.java &#091;input=LOCATIONS_V, output=LOCATIONS_V, pk=SYS_C0012238&#093;
&#091;INFO&#093; Generating table         : RegionsV.java &#091;input=REGIONS_V, output=REGIONS_V, pk=SYS_C0012239&#093;
&#091;INFO&#093; Tables generated         : Total: 13.888s, +6.405s
&#091;INFO&#093; Generating table references
&#091;INFO&#093; Table refs generated     : Total: 13.889s, +1.9ms
&#091;INFO&#093; Generating Keys          
&#091;INFO&#093; Keys generated           : Total: 13.9s, +10.228ms
&#091;INFO&#093; Generating Indexes       
&#091;INFO&#093; Skipping empty indexes   
&#091;INFO&#093; Generating table records 
&#091;INFO&#093; Generating record        : CountriesVRecord.java
&#091;INFO&#093; Generating record        : DepartmentsVRecord.java
&#091;INFO&#093; Generating record        : EmployeesVRecord.java
&#091;INFO&#093; Generating record        : JobsVRecord.java
&#091;INFO&#093; Generating record        : JobHistoryVRecord.java
&#091;INFO&#093; Generating record        : LocationsVRecord.java
&#091;INFO&#093; Generating record        : RegionsVRecord.java
&#091;INFO&#093; Table records generated  : Total: 13.939s, +39.368ms
&#091;INFO&#093; Generation finished: HR  : Total: 13.939s, +0.14ms
&#091;INFO&#093;                          
&#091;INFO&#093; Excluding empty schema   : OE
&#091;INFO&#093; Excluding empty schema   : PM
&#091;INFO&#093; Excluding empty schema   : IX
&#091;INFO&#093; Excluding empty schema   : SH
&#091;INFO&#093; Excluding empty schema   : BI
&#091;INFO&#093; Excluding empty schema   : FTLDB
&#091;INFO&#093; Excluding empty schema   : TEPLSQL
&#091;INFO&#093; Excluding empty schema   : ODDGEN
&#091;INFO&#093; Excluding empty schema   : OGDEMO
&#091;INFO&#093; Excluding empty schema   : AQDEMO
&#091;INFO&#093; Excluding empty schema   : AX
&#091;INFO&#093; Excluding empty schema   : EMPTRACKER
&#091;INFO&#093; Excluding empty schema   : UT3
&#091;INFO&#093; Excluding empty schema   : PLSCOPE
&#091;INFO&#093; Excluding empty schema   : SONAR
&#091;INFO&#093; Excluding empty schema   : TVDCA
&#091;INFO&#093; Excluding empty schema   : DEMO
&#091;INFO&#093; Excluding empty schema   : JOOQ
&#091;INFO&#093; Removing excess files" 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">[INFO] --- jooq-codegen-maven:3.11.3:generate (default) @ jooq-pinkdb ---</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] No &lt;inputCatalog/&gt; was provided. Generating ALL available catalogs instead.</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] No &lt;inputSchema/&gt; was provided. Generating ALL available schemata instead.</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] License parameters       </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] ----------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   Thank you for using jOOQ and jOOQ&#39;s code generator</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]                          </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Database parameters      </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] ----------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   dialect                : ORACLE</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   URL                    : jdbc:oracle:thin:@localhost:1521/odb.docker</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   target dir             : /Users/phs/git/JooqPinkDB/src/main/java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   target package         : com.trivadis.jooq.pinkdb.model.generated</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   includes               : [HR\..*|SYS\.DBMS_MONITOR]</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   excludes               : []</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   includeExcludeColumns  : false</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] ----------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]                          </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] JavaGenerator parameters </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] ----------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   annotations (generated): true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   annotations (JPA: any) : false</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   annotations (JPA: version): </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   annotations (validation): false</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments               : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on attributes : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on catalogs   : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on columns    : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on keys       : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on links      : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on packages   : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on parameters : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on queues     : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on routines   : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on schemas    : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on sequences  : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on tables     : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   comments on udts       : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   daos                   : false</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   deprecated code        : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   global references (any): true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   global references (catalogs): true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   global references (keys): true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   global references (links): true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   global references (queues): true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   global references (routines): true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   global references (schemas): true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   global references (sequences): true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   global references (tables): true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   global references (udts): true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   indexes                : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   instance fields        : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   interfaces             : false</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   interfaces (immutable) : false</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   javadoc                : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   keys                   : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   links                  : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   pojos                  : false</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   pojos (immutable)      : false</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   queues                 : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   records                : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   routines               : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   sequences              : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   table-valued functions : false</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   tables                 : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   udts                   : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]   relations              : true</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] ----------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]                          </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generation remarks       </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] ----------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]                          </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] ----------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating catalogs      : Total: 1</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] </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">@@@@@@@@@@@@@@@@  @@        @@@@@@@@@@</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">@@@@@@@@@@        @@        @@@@@@@@@@</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">@@@@@@@@@@    @@  @@  @@@@  @@@@@@@@@@</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">@@@@@@@@@@@@@@@@@@@@@@@  @@@@@@@@@@@@@</span></span>
<span class="line"><span style="color: #D4D4D4">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@</span></span>
<span class="line"><span style="color: #D4D4D4">@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  Thank you for using the 30 day free jOOQ 3.11.3 trial edition</span></span>
<span class="line"><span style="color: #D4D4D4">                                      </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Packages fetched         : 517 (1 included, 516 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Applying synonym         : &quot;PUBLIC&quot;.&quot;KU$_LOGENTRY&quot; is synonym for &quot;SYS&quot;.&quot;KU$_LOGENTRY1010&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Applying synonym         : &quot;PUBLIC&quot;.&quot;XMLTYPE&quot; is synonym for &quot;SYS&quot;.&quot;XMLTYPE&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] ARRAYs fetched           : 641 (0 included, 641 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Enums fetched            : 0 (0 included, 0 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] No schema version is applied for catalog . Regenerating.</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]                          </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating catalog       : DefaultCatalog.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] ==========================================================</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Routines fetched         : 312 (0 included, 312 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Tables fetched           : 2347 (7 included, 2340 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] UDTs fetched             : 1287 (0 included, 1287 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating schemata      : Total: 63</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] No schema version is applied for schema SYS. Regenerating.</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating schema        : Sys.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] ----------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Sequences fetched        : 12 (0 included, 12 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Domains fetched          : 0 (0 included, 0 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating packages      </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating package       : SYS.DBMS_MONITOR</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : ClientIdStatDisable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : ClientIdStatEnable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : ClientIdTraceDisable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : ClientIdTraceEnable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : DatabaseTraceDisable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : DatabaseTraceEnable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : ServModActStatDisable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : ServModActStatEnable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : ServModActTraceDisable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : ServModActTraceEnable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : SessionTraceDisable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating routine       : SessionTraceEnable.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Packages generated       : Total: 7.009s</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] UDT not supported or not in input schemata: SYS.SCHEDULER$_EVENT_INFO</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] UDT not supported or not in input schemata: SYS.SCHEDULER_FILEWATCHER_RESULT</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Queues fetched           : 0 (0 included, 0 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Links fetched            : 0 (0 included, 0 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generation finished: SYS : Total: 7.482s, +473.374ms</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]                          </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : AUDSYS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : SYSTEM</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : SYSBACKUP</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : SYSDG</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : SYSKM</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : SYSRAC</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : OUTLN</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : XS$NULL</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : GSMADMIN_INTERNAL</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : GSMUSER</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : DIP</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : REMOTE_SCHEDULER_AGENT</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : DBSFWUSER</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : ORACLE_OCM</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : SYS$UMF</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : DBSNMP</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : APPQOSSYS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : GSMCATUSER</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : GGSYS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : XDB</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : ANONYMOUS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : WMSYS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : DVF</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : OJVMSYS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : CTXSYS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : ORDSYS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : ORDDATA</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : ORDPLUGINS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : SI_INFORMTN_SCHEMA</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : MDSYS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : OLAPSYS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : MDDATA</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : LBACSYS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : DVSYS</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : FLOWS_FILES</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : APEX_PUBLIC_USER</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : APEX_180100</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : APEX_INSTANCE_ADMIN_USER</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : APEX_LISTENER</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : APEX_REST_PUBLIC_USER</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : ORDS_METADATA</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : ORDS_PUBLIC_USER</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : SCOTT</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] No schema version is applied for schema HR. Regenerating.</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating schema        : Hr.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] ----------------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating tables        </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Adding foreign key       : SYS_C0012240 (HR.COUNTRIES_V.REGION_ID) referencing SYS_C0012239</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Adding foreign key       : SYS_C0012241 (HR.DEPARTMENTS_V.LOCATION_ID) referencing SYS_C0012238</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Adding foreign key       : SYS_C0012242 (HR.DEPARTMENTS_V.MANAGER_ID) referencing SYS_C0012235</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Adding foreign key       : SYS_C0012244 (HR.EMPLOYEES_V.DEPARTMENT_ID) referencing SYS_C0012234</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Adding foreign key       : SYS_C0012245 (HR.EMPLOYEES_V.JOB_ID) referencing SYS_C0012237</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Adding foreign key       : SYS_C0012246 (HR.EMPLOYEES_V.MANAGER_ID) referencing SYS_C0012235</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Adding foreign key       : SYS_C0012247 (HR.JOB_HISTORY_V.DEPARTMENT_ID) referencing SYS_C0012234</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Adding foreign key       : SYS_C0012248 (HR.JOB_HISTORY_V.EMPLOYEE_ID) referencing SYS_C0012235</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Adding foreign key       : SYS_C0012249 (HR.JOB_HISTORY_V.JOB_ID) referencing SYS_C0012237</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Adding foreign key       : SYS_C0012250 (HR.LOCATIONS_V.COUNTRY_ID) referencing SYS_C0012233</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Synthetic primary keys   : 0 (0 included, 0 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Overriding primary keys  : 8 (0 included, 8 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating table         : CountriesV.java [input=COUNTRIES_V, output=COUNTRIES_V, pk=SYS_C0012233]</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Indexes fetched          : 0 (0 included, 0 excluded)</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating table         : DepartmentsV.java [input=DEPARTMENTS_V, output=DEPARTMENTS_V, pk=SYS_C0012234]</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating table         : EmployeesV.java [input=EMPLOYEES_V, output=EMPLOYEES_V, pk=SYS_C0012235]</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating table         : JobsV.java [input=JOBS_V, output=JOBS_V, pk=SYS_C0012237]</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating table         : JobHistoryV.java [input=JOB_HISTORY_V, output=JOB_HISTORY_V, pk=SYS_C0012236]</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating table         : LocationsV.java [input=LOCATIONS_V, output=LOCATIONS_V, pk=SYS_C0012238]</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating table         : RegionsV.java [input=REGIONS_V, output=REGIONS_V, pk=SYS_C0012239]</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Tables generated         : Total: 13.888s, +6.405s</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating table references</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Table refs generated     : Total: 13.889s, +1.9ms</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating Keys          </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Keys generated           : Total: 13.9s, +10.228ms</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating Indexes       </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Skipping empty indexes   </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating table records </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating record        : CountriesVRecord.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating record        : DepartmentsVRecord.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating record        : EmployeesVRecord.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating record        : JobsVRecord.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating record        : JobHistoryVRecord.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating record        : LocationsVRecord.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generating record        : RegionsVRecord.java</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Table records generated  : Total: 13.939s, +39.368ms</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Generation finished: HR  : Total: 13.939s, +0.14ms</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO]                          </span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : OE</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : PM</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : IX</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : SH</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : BI</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : FTLDB</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : TEPLSQL</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : ODDGEN</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : OGDEMO</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : AQDEMO</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : AX</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : EMPTRACKER</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : UT3</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : PLSCOPE</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : SONAR</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : TVDCA</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : DEMO</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Excluding empty schema   : JOOQ</span></span>
<span class="line"><span style="color: #D4D4D4">[INFO] Removing excess files</span></span></code></pre></div>


<p></div></div>
<br />
</div></div>




<h2 class="wp-block-heading"><a name="run_simple_query"></a>7. Run a Simple Query</h2>



<p class="wp-block-paragraph">The following code is a complete Java program. It contains a bit more than the simple query because I will need these parts in the next chapters and would like to focus on the JOOQ query only.</p>



<h3 class="wp-block-heading">Java Program (JOOQ Query)</h3>



<p class="wp-block-paragraph">On line 3 the view-API is imported statically. This allows to reference the view <code>JOBS_V</code> instead of&nbsp; <code>JobsV.JOBS_V</code> or <code>Hr.JOBS_V</code>. It&#8217;s just convenience, but it makes the code much more readable.</p>



<p class="wp-block-paragraph">The next static import on line 4 allows for example to use SQL functions such as <code>count()</code>, <code>sum()</code>, etc. without the <code>DSL.</code> prefix. Again, it&#8217;s just convenience, but makes to code shorter and improves readability.</p>



<p class="wp-block-paragraph">On lines 27-28, the DSL context is initialized.  The context holds the connection to the database and some configuration. In this case I&#8217;ve configured JOOQ to produce formatted SQL statements and fetch data with an array size of 30 from the database. The JDBC default is 10, which is not bad, but 30 is in our case better, since it reduces the network roundtrips to 1 for all SQL query results.</p>



<p class="wp-block-paragraph">On lines 64-67, we build the SQL statement using the JOOQ DSL. The statement is equivalent to <code>SELECT * FROM hr.jobs_v ORDER BY job_id</code>.</p>



<p class="wp-block-paragraph">Finally, on line 68 the function <code>fetchAndPrint</code> is called. This function prints the query produced by JOOQ, all used bind variables and the query result. See lines 51, 59 and 60.</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">Simple Query &#8211; Java Program</span><span role="button" tabindex="0" data-code="package com.trivadis.jooq.pinkdb;

import static com.trivadis.jooq.pinkdb.model.generated.hr.Tables.*;
import static org.jooq.impl.DSL.*;

import com.trivadis.jooq.pinkdb.model.generated.sys.packages.DbmsMonitor;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;

import org.jooq.DSLContext;
import org.jooq.Result;
import org.jooq.ResultQuery;
import org.jooq.SQLDialect;
import org.jooq.conf.Settings;
import org.jooq.impl.DSL;

public class Main {
   private static DSLContext ctx;
   private static boolean sqlTrace = false;
   
   private static void initCtx(boolean withSqlTrace) throws SQLException {
      final Connection conn = DriverManager.getConnection(
            &quot;jdbc:oracle:thin:@localhost:1521/odb.docker&quot;, &quot;jooq&quot;, &quot;jooq&quot;);
      ctx = DSL.using(conn, SQLDialect.ORACLE12C, 
            new Settings().withRenderFormatted(true).withFetchSize(30));
      sqlTrace = withSqlTrace;
      enableSqlTrace();
   }
   
   private static void closeCtx() throws SQLException {
      disableSqlTrace();
      ctx.close();
   }
   
   private static void enableSqlTrace() throws SQLException {
      if (sqlTrace) {
         DbmsMonitor.sessionTraceEnable(ctx.configuration(), null, null, true, true, &quot;all_executions&quot;);
      }
   }

   private static void disableSqlTrace() throws SQLException {
      if (sqlTrace) {
         DbmsMonitor.sessionTraceDisable(ctx.configuration(), null, null);
      }
   }
   
   private static void fetchAndPrint(String name, ResultQuery<?&gt; query) {
      System.out.println(name + &quot;: \n\n&quot; + query.getSQL());
      final List<Object&gt; binds = query.getBindValues();
      if (binds.size() &gt; 0) {
         System.out.println(&quot;\n&quot; + name + &quot; binds:&quot;);
         for (int i=0; i<binds.size(); i++) {
            System.out.println(&quot;   &quot; + &quot;:&quot; + (i+1) + &quot; = &quot; + binds.get(i));
         }
      }
      final Result<?&gt; result = query.fetch();
      System.out.println(&quot;\n&quot; + name + &quot; result (&quot; + result.size() + &quot; rows): \n\n&quot; + result.format());            
   }
   
   private static void queryJobs() {
      final ResultQuery<?&gt; query = ctx
            .select()
            .from(JOBS_V)
            .orderBy(JOBS_V.JOB_ID);
      fetchAndPrint(&quot;Jobs&quot;, query);
   }
   
   public static void main(String[] args) throws SQLException {
      initCtx(true);
      queryJobs();
      closeCtx();
   }
}" 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">package</span><span style="color: #D4D4D4"> com.trivadis.jooq.pinkdb;</span></span>
<span class="line"></span>
<span class="line cbp-line-highlight"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> com.trivadis.jooq.pinkdb.model.generated.hr.Tables.*;</span></span>
<span class="line cbp-line-highlight"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> org.jooq.impl.DSL.*;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> com.trivadis.jooq.pinkdb.model.generated.sys.packages.DbmsMonitor;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> java.sql.Connection;</span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> java.sql.DriverManager;</span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> java.sql.SQLException;</span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> java.util.List;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.jooq.DSLContext;</span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.jooq.Result;</span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.jooq.ResultQuery;</span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.jooq.SQLDialect;</span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.jooq.conf.Settings;</span></span>
<span class="line"><span style="color: #569CD6">import</span><span style="color: #D4D4D4"> org.jooq.impl.DSL;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Main</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">DSLContext</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ctx</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">boolean</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">sqlTrace</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">initCtx</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">boolean</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">withSqlTrace</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">throws</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">SQLException</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Connection</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">conn</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">DriverManager</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">getConnection</span><span style="color: #D4D4D4">(</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #CE9178">&quot;jdbc:oracle:thin:@localhost:1521/odb.docker&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;jooq&quot;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;jooq&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">      ctx = </span><span style="color: #9CDCFE">DSL</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">using</span><span style="color: #D4D4D4">(conn, </span><span style="color: #9CDCFE">SQLDialect</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">ORACLE12C</span><span style="color: #D4D4D4">, </span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">            </span><span style="color: #C586C0">new</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">Settings</span><span style="color: #D4D4D4">().</span><span style="color: #DCDCAA">withRenderFormatted</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">true</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">withFetchSize</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">      sqlTrace = withSqlTrace;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">enableSqlTrace</span><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">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">closeCtx</span><span style="color: #D4D4D4">() </span><span style="color: #569CD6">throws</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">SQLException</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">disableSqlTrace</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">ctx</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">close</span><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">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">enableSqlTrace</span><span style="color: #D4D4D4">() </span><span style="color: #569CD6">throws</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">SQLException</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (sqlTrace) {</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">         </span><span style="color: #9CDCFE">DbmsMonitor</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">sessionTraceEnable</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">ctx</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">configuration</span><span style="color: #D4D4D4">(), </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">true</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">true</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&quot;all_executions&quot;</span><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>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">disableSqlTrace</span><span style="color: #D4D4D4">() </span><span style="color: #569CD6">throws</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">SQLException</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (sqlTrace) {</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #9CDCFE">DbmsMonitor</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">sessionTraceDisable</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">ctx</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">configuration</span><span style="color: #D4D4D4">(), </span><span style="color: #569CD6">null</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>
<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 style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">fetchAndPrint</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">name</span><span style="color: #D4D4D4">, </span><span style="color: #4EC9B0">ResultQuery</span><span style="color: #D4D4D4">&lt;</span><span style="color: #569CD6">?</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">query</span><span style="color: #D4D4D4">) {</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">System</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">out</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">println</span><span style="color: #D4D4D4">(name + </span><span style="color: #CE9178">&quot;: </span><span style="color: #D7BA7D">\n\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> + </span><span style="color: #9CDCFE">query</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">getSQL</span><span style="color: #D4D4D4">());</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">List</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">Object</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">binds</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">query</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">getBindValues</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">binds</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">size</span><span style="color: #D4D4D4">() &gt; </span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #9CDCFE">System</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">out</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">println</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> + name + </span><span style="color: #CE9178">&quot; binds:&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #C586C0">for</span><span style="color: #D4D4D4"> (</span><span style="color: #4EC9B0">int</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">i</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">0</span><span style="color: #D4D4D4">; i&lt;</span><span style="color: #9CDCFE">binds</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">size</span><span style="color: #D4D4D4">(); i++) {</span></span>
<span class="line"><span style="color: #D4D4D4">            </span><span style="color: #9CDCFE">System</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">out</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">println</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;   &quot;</span><span style="color: #D4D4D4"> + </span><span style="color: #CE9178">&quot;:&quot;</span><span style="color: #D4D4D4"> + (i+</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">) + </span><span style="color: #CE9178">&quot; = &quot;</span><span style="color: #D4D4D4"> + </span><span style="color: #9CDCFE">binds</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">get</span><span style="color: #D4D4D4">(i));</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">      </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Result</span><span style="color: #D4D4D4">&lt;</span><span style="color: #569CD6">?</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">result</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">query</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">fetch</span><span style="color: #D4D4D4">();</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">System</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">out</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">println</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> + name + </span><span style="color: #CE9178">&quot; result (&quot;</span><span style="color: #D4D4D4"> + </span><span style="color: #9CDCFE">result</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">size</span><span style="color: #D4D4D4">() + </span><span style="color: #CE9178">&quot; rows): </span><span style="color: #D7BA7D">\n\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4"> + </span><span style="color: #9CDCFE">result</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">format</span><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">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">queryJobs</span><span style="color: #D4D4D4">() {</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ResultQuery</span><span style="color: #D4D4D4">&lt;</span><span style="color: #569CD6">?</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">query</span><span style="color: #D4D4D4"> = ctx</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">select</span><span style="color: #D4D4D4">()</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">from</span><span style="color: #D4D4D4">(JOBS_V)</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">orderBy</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">JOBS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">JOB_ID</span><span style="color: #D4D4D4">);</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">fetchAndPrint</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;Jobs&quot;</span><span style="color: #D4D4D4">, query);</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 style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">main</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4">[] </span><span style="color: #9CDCFE">args</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">throws</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">SQLException</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">initCtx</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">true</span><span style="color: #D4D4D4">);</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">queryJobs</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">closeCtx</span><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>



<h3 class="wp-block-heading">Java Program Output (SQL Query &amp; Result)</h3>



<p class="wp-block-paragraph">The program produces this output:</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">Simple Query &#8211; SQL Query &amp; Result</span><span role="button" tabindex="0" data-code="Jobs: 

select 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_ID&quot;, 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_TITLE&quot;, 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MIN_SALARY&quot;, 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MAX_SALARY&quot;
from &quot;HR&quot;.&quot;JOBS_V&quot;
order by &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_ID&quot;

Jobs result (19 rows): 

+----------+-------------------------------+----------+----------+
|JOB_ID    |JOB_TITLE                      |MIN_SALARY|MAX_SALARY|
+----------+-------------------------------+----------+----------+
|AC_ACCOUNT|Public Accountant              |      4200|      9000|
|AC_MGR    |Accounting Manager             |      8200|     16000|
|AD_ASST   |Administration Assistant       |      3000|      6000|
|AD_PRES   |President                      |     20080|     40000|
|AD_VP     |Administration Vice President  |     15000|     30000|
|FI_ACCOUNT|Accountant                     |      4200|      9000|
|FI_MGR    |Finance Manager                |      8200|     16000|
|HR_REP    |Human Resources Representative |      4000|      9000|
|IT_PROG   |Programmer                     |      4000|     10000|
|MK_MAN    |Marketing Manager              |      9000|     15000|
|MK_REP    |Marketing Representative       |      4000|      9000|
|PR_REP    |Public Relations Representative|      4500|     10500|
|PU_CLERK  |Purchasing Clerk               |      2500|      5500|
|PU_MAN    |Purchasing Manager             |      8000|     15000|
|SA_MAN    |Sales Manager                  |     10000|     20080|
|SA_REP    |Sales Representative           |      6000|     12008|
|SH_CLERK  |Shipping Clerk                 |      2500|      5500|
|ST_CLERK  |Stock Clerk                    |      2008|      5000|
|ST_MAN    |Stock Manager                  |      5500|      8500|
+----------+-------------------------------+----------+----------+" 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">Jobs: </span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">select </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_ID&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_TITLE&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MIN_SALARY&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MAX_SALARY&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">from &quot;HR&quot;.&quot;JOBS_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">order by &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_ID&quot;</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Jobs result (19 rows): </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">|JOB_ID    |JOB_TITLE                      |MIN_SALARY|MAX_SALARY|</span></span>
<span class="line"><span style="color: #D4D4D4">+----------+-------------------------------+----------+----------+</span></span>
<span class="line"><span style="color: #D4D4D4">|AC_ACCOUNT|Public Accountant              |      4200|      9000|</span></span>
<span class="line"><span style="color: #D4D4D4">|AC_MGR    |Accounting Manager             |      8200|     16000|</span></span>
<span class="line"><span style="color: #D4D4D4">|AD_ASST   |Administration Assistant       |      3000|      6000|</span></span>
<span class="line"><span style="color: #D4D4D4">|AD_PRES   |President                      |     20080|     40000|</span></span>
<span class="line"><span style="color: #D4D4D4">|AD_VP     |Administration Vice President  |     15000|     30000|</span></span>
<span class="line"><span style="color: #D4D4D4">|FI_ACCOUNT|Accountant                     |      4200|      9000|</span></span>
<span class="line"><span style="color: #D4D4D4">|FI_MGR    |Finance Manager                |      8200|     16000|</span></span>
<span class="line"><span style="color: #D4D4D4">|HR_REP    |Human Resources Representative |      4000|      9000|</span></span>
<span class="line"><span style="color: #D4D4D4">|IT_PROG   |Programmer                     |      4000|     10000|</span></span>
<span class="line"><span style="color: #D4D4D4">|MK_MAN    |Marketing Manager              |      9000|     15000|</span></span>
<span class="line"><span style="color: #D4D4D4">|MK_REP    |Marketing Representative       |      4000|      9000|</span></span>
<span class="line"><span style="color: #D4D4D4">|PR_REP    |Public Relations Representative|      4500|     10500|</span></span>
<span class="line"><span style="color: #D4D4D4">|PU_CLERK  |Purchasing Clerk               |      2500|      5500|</span></span>
<span class="line"><span style="color: #D4D4D4">|PU_MAN    |Purchasing Manager             |      8000|     15000|</span></span>
<span class="line"><span style="color: #D4D4D4">|SA_MAN    |Sales Manager                  |     10000|     20080|</span></span>
<span class="line"><span style="color: #D4D4D4">|SA_REP    |Sales Representative           |      6000|     12008|</span></span>
<span class="line"><span style="color: #D4D4D4">|SH_CLERK  |Shipping Clerk                 |      2500|      5500|</span></span>
<span class="line"><span style="color: #D4D4D4">|ST_CLERK  |Stock Clerk                    |      2008|      5000|</span></span>
<span class="line"><span style="color: #D4D4D4">|ST_MAN    |Stock Manager                  |      5500|      8500|</span></span>
<span class="line"><span style="color: #D4D4D4">+----------+-------------------------------+----------+----------+</span></span></code></pre></div>



<p class="wp-block-paragraph">Two things are interesting.</p>



<p class="wp-block-paragraph">First, the generated <code>SELECT</code> statement lists all columns, even if no column was defined in the query on program line 65.</p>



<p class="wp-block-paragraph">Second, the output is formatted nicely. Where did this happen? On line 59 the query is executed and the result is saved in the local variable named <code>result</code>. This is a result set and contains all rows. For example, you may get the number of rows via <code>result.size()</code>, as on line 60. I may also loop through the result set and do whatever I want. In this case, I just used a convenience function <code>format</code> to format the result set as text. There are other convenience functions such as <code>formatCSV</code>, <code>formatHTML</code>, <code>formatJSON</code> or <code>formatXML</code>.  You may guess by the name what they are doing. Nice!</p>



<h3 class="wp-block-heading">SQL Trace Output</h3>



<p class="wp-block-paragraph">The Java program produces a SQL Trace file by default. See program line 40. Here&#8217;s the relevant <code>tkprof</code> excerpt:</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">Simple Query &#8211; TKPROF excerpt</span><span role="button" tabindex="0" data-code="call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.03       0.18          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      0.00       0.00          0          2          0          19
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      0.03       0.18          0          2          0          19

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 133  
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
        19         19         19  TABLE ACCESS BY INDEX ROWID JOBS (cr=2 pr=0 pw=0 time=45 us starts=1 cost=2 size=627 card=19)
        19         19         19   INDEX FULL SCAN JOB_ID_PK (cr=1 pr=0 pw=0 time=18 us starts=1 cost=1 size=0 card=19)(object id 78619)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1        0.10          0.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">call     count       cpu    elapsed       disk      query    current        rows</span></span>
<span class="line"><span style="color: #D4D4D4">------- ------  -------- ---------- ---------- ---------- ----------  ----------</span></span>
<span class="line"><span style="color: #D4D4D4">Parse        1      0.03       0.18          0          0          0           0</span></span>
<span class="line"><span style="color: #D4D4D4">Execute      1      0.00       0.00          0          0          0           0</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Fetch        1      0.00       0.00          0          2          0          19</span></span>
<span class="line"><span style="color: #D4D4D4">------- ------  -------- ---------- ---------- ---------- ----------  ----------</span></span>
<span class="line"><span style="color: #D4D4D4">total        3      0.03       0.18          0          2          0          19</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Misses in library cache during parse: 1</span></span>
<span class="line"><span style="color: #D4D4D4">Optimizer mode: ALL_ROWS</span></span>
<span class="line"><span style="color: #D4D4D4">Parsing user id: 133  </span></span>
<span class="line"><span style="color: #D4D4D4">Number of plan statistics captured: 1</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Rows (1st) Rows (avg) Rows (max)  Row Source Operation</span></span>
<span class="line"><span style="color: #D4D4D4">---------- ---------- ----------  ---------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">        19         19         19  TABLE ACCESS BY INDEX ROWID JOBS (cr=2 pr=0 pw=0 time=45 us starts=1 cost=2 size=627 card=19)</span></span>
<span class="line"><span style="color: #D4D4D4">        19         19         19   INDEX FULL SCAN JOB_ID_PK (cr=1 pr=0 pw=0 time=18 us starts=1 cost=1 size=0 card=19)(object id 78619)</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">Elapsed times include waiting on following events:</span></span>
<span class="line"><span style="color: #D4D4D4">  Event waited on                             Times   Max. Wait  Total Waited</span></span>
<span class="line"><span style="color: #D4D4D4">  ----------------------------------------   Waited  ----------  ------------</span></span>
<span class="line"><span style="color: #D4D4D4">  SQL*Net message to client                       1        0.00          0.00</span></span>
<span class="line"><span style="color: #D4D4D4">  SQL*Net message from client                     1        0.10          0.10</span></span></code></pre></div>



<p class="wp-block-paragraph">Interesting is line 5 of the output. There was just one fetch to retrieve 19 rows. A default configuration of the JDBC driver would have caused two fetches. Our configuration on program line 28 worked. All data fetched in a single network roundtrip.</p>



<h2 class="wp-block-heading"><a name="using_joins"></a>8. Using Joins &amp; Aggregations</h2>



<p class="wp-block-paragraph">In the next example we query the salaries per location. The idea is to look at a JOOQ query with joins and aggregations.</p>



<h3 class="wp-block-heading">JOOQ Query</h3>



<p class="wp-block-paragraph">On lines 6-8, you see how aggregate functions are used in JOOQ and how to define an alias for the resulting column.</p>



<p class="wp-block-paragraph">Line 10 is interesting. It defines the join using the <code>onKey</code> function. This function requires a parameter when multiple join paths are possible. In this case <code>EMPLOYEE_V</code> and <code>DEPARTMENTS_V</code> may be joined either via <code>DEPARTMENTS_V.MANAGER_ID</code> or via <code>EMPLOYEES_V.DEPARTMENT_ID</code>. In this case we defined the latter.</p>



<p class="wp-block-paragraph">On line 11 the <code>onKey</code> function has no parameters, since only one join path exists to <code>LOCATIONS</code>. This clearly shows how JOOQ uses our referential integrity constraints on the view-API to build the query. The idea is similar to a <code>NATURAL JOIN</code>, but the implementation is better since it relies on constraints and not naming conventions. I already miss this feature in SQL.</p>



<p class="wp-block-paragraph">The use of the functions <code>groupBy</code> and <code>orderBy</code> on line 14 and 15 should be self-explanatory.</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">Joins &amp; Aggregations &#8211; JOOQ Query</span><span role="button" tabindex="0" data-code="   private static void querySalariesPerLocation() {
      final ResultQuery<?&gt; query = ctx
            .select(REGIONS_V.REGION_NAME,
                  COUNTRIES_V.COUNTRY_NAME,
                  LOCATIONS_V.CITY,
                  count().as(&quot;employees&quot;),
                  sum(EMPLOYEES_V.SALARY).as(&quot;sum_salaray&quot;),
                  max(EMPLOYEES_V.SALARY).as(&quot;max_salary&quot;))
            .from(EMPLOYEES_V)
            .join(DEPARTMENTS_V).onKey(EMPLOYEES_V.DEPARTMENT_ID)
            .join(LOCATIONS_V).onKey()
            .join(COUNTRIES_V).onKey()
            .join(REGIONS_V).onKey()
            .groupBy(REGIONS_V.REGION_NAME, COUNTRIES_V.COUNTRY_NAME, LOCATIONS_V.CITY)
            .orderBy(REGIONS_V.REGION_NAME, COUNTRIES_V.COUNTRY_NAME, LOCATIONS_V.CITY);
      fetchAndPrint(&quot;Salaries Per Location&quot;, query);
   }" 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">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">querySalariesPerLocation</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ResultQuery</span><span style="color: #D4D4D4">&lt;</span><span style="color: #569CD6">?</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">query</span><span style="color: #D4D4D4"> = ctx</span></span>
<span class="line"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">select</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">REGIONS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">REGION_NAME</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #9CDCFE">COUNTRIES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">COUNTRY_NAME</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #9CDCFE">LOCATIONS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">CITY</span><span style="color: #D4D4D4">,</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                  </span><span style="color: #DCDCAA">count</span><span style="color: #D4D4D4">().</span><span style="color: #DCDCAA">as</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;employees&quot;</span><span style="color: #D4D4D4">),</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                  </span><span style="color: #DCDCAA">sum</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">SALARY</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">as</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;sum_salaray&quot;</span><span style="color: #D4D4D4">),</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                  </span><span style="color: #DCDCAA">max</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">SALARY</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">as</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;max_salary&quot;</span><span style="color: #D4D4D4">))</span></span>
<span class="line"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">from</span><span style="color: #D4D4D4">(EMPLOYEES_V)</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">join</span><span style="color: #D4D4D4">(DEPARTMENTS_V).</span><span style="color: #DCDCAA">onKey</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">DEPARTMENT_ID</span><span style="color: #D4D4D4">)</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">join</span><span style="color: #D4D4D4">(LOCATIONS_V).</span><span style="color: #DCDCAA">onKey</span><span style="color: #D4D4D4">()</span></span>
<span class="line"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">join</span><span style="color: #D4D4D4">(COUNTRIES_V).</span><span style="color: #DCDCAA">onKey</span><span style="color: #D4D4D4">()</span></span>
<span class="line"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">join</span><span style="color: #D4D4D4">(REGIONS_V).</span><span style="color: #DCDCAA">onKey</span><span style="color: #D4D4D4">()</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">groupBy</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">REGIONS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">REGION_NAME</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">COUNTRIES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">COUNTRY_NAME</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">LOCATIONS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">CITY</span><span style="color: #D4D4D4">)</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">orderBy</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">REGIONS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">REGION_NAME</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">COUNTRIES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">COUNTRY_NAME</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">LOCATIONS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">CITY</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">fetchAndPrint</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;Salaries Per Location&quot;</span><span style="color: #D4D4D4">, query);</span></span>
<span class="line"><span style="color: #D4D4D4">   }</span></span></code></pre></div>



<h3 class="wp-block-heading">SQL Query &amp; Result</h3>



<p class="wp-block-paragraph">No surprises. The query looks 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">Joins &amp; Aggregations &#8211; SQL Query &amp; Result</span><span role="button" tabindex="0" data-code="Salaries Per Location: 

select 
  &quot;HR&quot;.&quot;REGIONS_V&quot;.&quot;REGION_NAME&quot;, 
  &quot;HR&quot;.&quot;COUNTRIES_V&quot;.&quot;COUNTRY_NAME&quot;, 
  &quot;HR&quot;.&quot;LOCATIONS_V&quot;.&quot;CITY&quot;, 
  count(*) &quot;employees&quot;, 
  sum(&quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;) &quot;sum_salaray&quot;, 
  max(&quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;) &quot;max_salary&quot;
from &quot;HR&quot;.&quot;EMPLOYEES_V&quot;
  join &quot;HR&quot;.&quot;DEPARTMENTS_V&quot;
  on &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;DEPARTMENT_ID&quot; = &quot;HR&quot;.&quot;DEPARTMENTS_V&quot;.&quot;DEPARTMENT_ID&quot;
  join &quot;HR&quot;.&quot;LOCATIONS_V&quot;
  on &quot;HR&quot;.&quot;DEPARTMENTS_V&quot;.&quot;LOCATION_ID&quot; = &quot;HR&quot;.&quot;LOCATIONS_V&quot;.&quot;LOCATION_ID&quot;
  join &quot;HR&quot;.&quot;COUNTRIES_V&quot;
  on &quot;HR&quot;.&quot;LOCATIONS_V&quot;.&quot;COUNTRY_ID&quot; = &quot;HR&quot;.&quot;COUNTRIES_V&quot;.&quot;COUNTRY_ID&quot;
  join &quot;HR&quot;.&quot;REGIONS_V&quot;
  on &quot;HR&quot;.&quot;COUNTRIES_V&quot;.&quot;REGION_ID&quot; = &quot;HR&quot;.&quot;REGIONS_V&quot;.&quot;REGION_ID&quot;
group by 
  &quot;HR&quot;.&quot;REGIONS_V&quot;.&quot;REGION_NAME&quot;, 
  &quot;HR&quot;.&quot;COUNTRIES_V&quot;.&quot;COUNTRY_NAME&quot;, 
  &quot;HR&quot;.&quot;LOCATIONS_V&quot;.&quot;CITY&quot;
order by 
  &quot;HR&quot;.&quot;REGIONS_V&quot;.&quot;REGION_NAME&quot;, 
  &quot;HR&quot;.&quot;COUNTRIES_V&quot;.&quot;COUNTRY_NAME&quot;, 
  &quot;HR&quot;.&quot;LOCATIONS_V&quot;.&quot;CITY&quot;


Salaries Per Location result (7 rows): 

+-----------+------------------------+-------------------+---------+-----------+----------+
|REGION_NAME|COUNTRY_NAME            |CITY               |employees|sum_salaray|max_salary|
+-----------+------------------------+-------------------+---------+-----------+----------+
|Americas   |Canada                  |Toronto            |        2|      19000|     13000|
|Americas   |United States of America|Seattle            |       18|     159216|     24000|
|Americas   |United States of America|South San Francisco|       45|     156400|      8200|
|Americas   |United States of America|Southlake          |        5|      28800|      9000|
|Europe     |Germany                 |Munich             |        1|      10000|     10000|
|Europe     |United Kingdom          |London             |        1|       6500|      6500|
|Europe     |United Kingdom          |Oxford             |       34|     304500|     14000|
+-----------+------------------------+-------------------+---------+-----------+----------+" 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">Salaries Per Location: </span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">select </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;REGIONS_V&quot;.&quot;REGION_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;COUNTRIES_V&quot;.&quot;COUNTRY_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;LOCATIONS_V&quot;.&quot;CITY&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  count(*) &quot;employees&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  sum(&quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;) &quot;sum_salaray&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  max(&quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;) &quot;max_salary&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">from &quot;HR&quot;.&quot;EMPLOYEES_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  join &quot;HR&quot;.&quot;DEPARTMENTS_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  on &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;DEPARTMENT_ID&quot; = &quot;HR&quot;.&quot;DEPARTMENTS_V&quot;.&quot;DEPARTMENT_ID&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  join &quot;HR&quot;.&quot;LOCATIONS_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  on &quot;HR&quot;.&quot;DEPARTMENTS_V&quot;.&quot;LOCATION_ID&quot; = &quot;HR&quot;.&quot;LOCATIONS_V&quot;.&quot;LOCATION_ID&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  join &quot;HR&quot;.&quot;COUNTRIES_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  on &quot;HR&quot;.&quot;LOCATIONS_V&quot;.&quot;COUNTRY_ID&quot; = &quot;HR&quot;.&quot;COUNTRIES_V&quot;.&quot;COUNTRY_ID&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  join &quot;HR&quot;.&quot;REGIONS_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  on &quot;HR&quot;.&quot;COUNTRIES_V&quot;.&quot;REGION_ID&quot; = &quot;HR&quot;.&quot;REGIONS_V&quot;.&quot;REGION_ID&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">group by </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;REGIONS_V&quot;.&quot;REGION_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;COUNTRIES_V&quot;.&quot;COUNTRY_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;LOCATIONS_V&quot;.&quot;CITY&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">order by </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;REGIONS_V&quot;.&quot;REGION_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;COUNTRIES_V&quot;.&quot;COUNTRY_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;LOCATIONS_V&quot;.&quot;CITY&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">Salaries Per Location result (7 rows): </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">|REGION_NAME|COUNTRY_NAME            |CITY               |employees|sum_salaray|max_salary|</span></span>
<span class="line"><span style="color: #D4D4D4">+-----------+------------------------+-------------------+---------+-----------+----------+</span></span>
<span class="line"><span style="color: #D4D4D4">|Americas   |Canada                  |Toronto            |        2|      19000|     13000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Americas   |United States of America|Seattle            |       18|     159216|     24000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Americas   |United States of America|South San Francisco|       45|     156400|      8200|</span></span>
<span class="line"><span style="color: #D4D4D4">|Americas   |United States of America|Southlake          |        5|      28800|      9000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Europe     |Germany                 |Munich             |        1|      10000|     10000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Europe     |United Kingdom          |London             |        1|       6500|      6500|</span></span>
<span class="line"><span style="color: #D4D4D4">|Europe     |United Kingdom          |Oxford             |       34|     304500|     14000|</span></span>
<span class="line"><span style="color: #D4D4D4">+-----------+------------------------+-------------------+---------+-----------+----------+</span></span></code></pre></div>



<h3 class="wp-block-heading">SQL Trace Output</h3>



<p class="wp-block-paragraph">In the <code>tkprof</code> output we see that parsing took more than a second. This is a bit too long for this kind of query. However, that is not a problem of JOOQ. Beside that, the output looks good. Single network roundtrip 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);--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">Joins &amp; Aggregations &#8211; TKPROF excerpt</span><span role="button" tabindex="0" data-code="call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.24       1.09          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      0.00       0.00          0         22          0           7
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      0.25       1.09          0         22          0           7

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 133  
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         7          7          7  SORT GROUP BY (cr=24 pr=0 pw=0 time=8817 us starts=1 cost=12 size=5512 card=106)
       106        106        106   HASH JOIN  (cr=24 pr=0 pw=0 time=8745 us starts=1 cost=11 size=5512 card=106)
        27         27         27    MERGE JOIN  (cr=16 pr=0 pw=0 time=294 us starts=1 cost=8 size=1215 card=27)
         3          3          3     TABLE ACCESS BY INDEX ROWID REGIONS (cr=2 pr=0 pw=0 time=43 us starts=1 cost=2 size=56 card=4)
         3          3          3      INDEX FULL SCAN REG_ID_PK (cr=1 pr=0 pw=0 time=11 us starts=1 cost=1 size=0 card=4)(object id 78609)
        27         27         27     SORT JOIN (cr=14 pr=0 pw=0 time=251 us starts=3 cost=6 size=837 card=27)
        27         27         27      VIEW  VW_GBF_23 (cr=14 pr=0 pw=0 time=328 us starts=1 cost=5 size=837 card=27)
        27         27         27       NESTED LOOPS  (cr=14 pr=0 pw=0 time=325 us starts=1 cost=5 size=999 card=27)
        27         27         27        MERGE JOIN  (cr=10 pr=0 pw=0 time=238 us starts=1 cost=5 size=594 card=27)
        19         19         19         TABLE ACCESS BY INDEX ROWID LOCATIONS (cr=2 pr=0 pw=0 time=32 us starts=1 cost=2 size=345 card=23)
        19         19         19          INDEX FULL SCAN LOC_ID_PK (cr=1 pr=0 pw=0 time=26 us starts=1 cost=1 size=0 card=23)(object id 78613)
        27         27         27         SORT JOIN (cr=8 pr=0 pw=0 time=189 us starts=19 cost=3 size=189 card=27)
        27         27         27          VIEW  index$_join$_013 (cr=8 pr=0 pw=0 time=163 us starts=1 cost=2 size=189 card=27)
        27         27         27           HASH JOIN  (cr=8 pr=0 pw=0 time=162 us starts=1)
        27         27         27            INDEX FAST FULL SCAN DEPT_ID_PK (cr=4 pr=0 pw=0 time=35 us starts=1 cost=1 size=189 card=27)(object id 78616)
        27         27         27            INDEX FAST FULL SCAN DEPT_LOCATION_IX (cr=4 pr=0 pw=0 time=15 us starts=1 cost=1 size=189 card=27)(object id 78631)
        27         27         27        INDEX UNIQUE SCAN COUNTRY_C_ID_PK (cr=4 pr=0 pw=0 time=20 us starts=27 cost=0 size=15 card=1)(object id 78611)
       107        107        107    TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=35 us starts=1 cost=3 size=749 card=107)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       1        0.00          0.00
  PGA memory operation                            1        0.00          0.00
  SQL*Net message from client                     1        0.01          0.01" 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">call     count       cpu    elapsed       disk      query    current        rows</span></span>
<span class="line"><span style="color: #D4D4D4">------- ------  -------- ---------- ---------- ---------- ----------  ----------</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Parse        1      0.24       1.09          0          0          0           0</span></span>
<span class="line"><span style="color: #D4D4D4">Execute      1      0.00       0.00          0          0          0           0</span></span>
<span class="line"><span style="color: #D4D4D4">Fetch        1      0.00       0.00          0         22          0           7</span></span>
<span class="line"><span style="color: #D4D4D4">------- ------  -------- ---------- ---------- ---------- ----------  ----------</span></span>
<span class="line"><span style="color: #D4D4D4">total        3      0.25       1.09          0         22          0           7</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Misses in library cache during parse: 1</span></span>
<span class="line"><span style="color: #D4D4D4">Optimizer mode: ALL_ROWS</span></span>
<span class="line"><span style="color: #D4D4D4">Parsing user id: 133  </span></span>
<span class="line"><span style="color: #D4D4D4">Number of plan statistics captured: 1</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Rows (1st) Rows (avg) Rows (max)  Row Source Operation</span></span>
<span class="line"><span style="color: #D4D4D4">---------- ---------- ----------  ---------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">         7          7          7  SORT GROUP BY (cr=24 pr=0 pw=0 time=8817 us starts=1 cost=12 size=5512 card=106)</span></span>
<span class="line"><span style="color: #D4D4D4">       106        106        106   HASH JOIN  (cr=24 pr=0 pw=0 time=8745 us starts=1 cost=11 size=5512 card=106)</span></span>
<span class="line"><span style="color: #D4D4D4">        27         27         27    MERGE JOIN  (cr=16 pr=0 pw=0 time=294 us starts=1 cost=8 size=1215 card=27)</span></span>
<span class="line"><span style="color: #D4D4D4">         3          3          3     TABLE ACCESS BY INDEX ROWID REGIONS (cr=2 pr=0 pw=0 time=43 us starts=1 cost=2 size=56 card=4)</span></span>
<span class="line"><span style="color: #D4D4D4">         3          3          3      INDEX FULL SCAN REG_ID_PK (cr=1 pr=0 pw=0 time=11 us starts=1 cost=1 size=0 card=4)(object id 78609)</span></span>
<span class="line"><span style="color: #D4D4D4">        27         27         27     SORT JOIN (cr=14 pr=0 pw=0 time=251 us starts=3 cost=6 size=837 card=27)</span></span>
<span class="line"><span style="color: #D4D4D4">        27         27         27      VIEW  VW_GBF_23 (cr=14 pr=0 pw=0 time=328 us starts=1 cost=5 size=837 card=27)</span></span>
<span class="line"><span style="color: #D4D4D4">        27         27         27       NESTED LOOPS  (cr=14 pr=0 pw=0 time=325 us starts=1 cost=5 size=999 card=27)</span></span>
<span class="line"><span style="color: #D4D4D4">        27         27         27        MERGE JOIN  (cr=10 pr=0 pw=0 time=238 us starts=1 cost=5 size=594 card=27)</span></span>
<span class="line"><span style="color: #D4D4D4">        19         19         19         TABLE ACCESS BY INDEX ROWID LOCATIONS (cr=2 pr=0 pw=0 time=32 us starts=1 cost=2 size=345 card=23)</span></span>
<span class="line"><span style="color: #D4D4D4">        19         19         19          INDEX FULL SCAN LOC_ID_PK (cr=1 pr=0 pw=0 time=26 us starts=1 cost=1 size=0 card=23)(object id 78613)</span></span>
<span class="line"><span style="color: #D4D4D4">        27         27         27         SORT JOIN (cr=8 pr=0 pw=0 time=189 us starts=19 cost=3 size=189 card=27)</span></span>
<span class="line"><span style="color: #D4D4D4">        27         27         27          VIEW  index$_join$_013 (cr=8 pr=0 pw=0 time=163 us starts=1 cost=2 size=189 card=27)</span></span>
<span class="line"><span style="color: #D4D4D4">        27         27         27           HASH JOIN  (cr=8 pr=0 pw=0 time=162 us starts=1)</span></span>
<span class="line"><span style="color: #D4D4D4">        27         27         27            INDEX FAST FULL SCAN DEPT_ID_PK (cr=4 pr=0 pw=0 time=35 us starts=1 cost=1 size=189 card=27)(object id 78616)</span></span>
<span class="line"><span style="color: #D4D4D4">        27         27         27            INDEX FAST FULL SCAN DEPT_LOCATION_IX (cr=4 pr=0 pw=0 time=15 us starts=1 cost=1 size=189 card=27)(object id 78631)</span></span>
<span class="line"><span style="color: #D4D4D4">        27         27         27        INDEX UNIQUE SCAN COUNTRY_C_ID_PK (cr=4 pr=0 pw=0 time=20 us starts=27 cost=0 size=15 card=1)(object id 78611)</span></span>
<span class="line"><span style="color: #D4D4D4">       107        107        107    TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=35 us starts=1 cost=3 size=749 card=107)</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">Elapsed times include waiting on following events:</span></span>
<span class="line"><span style="color: #D4D4D4">  Event waited on                             Times   Max. Wait  Total Waited</span></span>
<span class="line"><span style="color: #D4D4D4">  ----------------------------------------   Waited  ----------  ------------</span></span>
<span class="line"><span style="color: #D4D4D4">  SQL*Net message to client                       1        0.00          0.00</span></span>
<span class="line"><span style="color: #D4D4D4">  PGA memory operation                            1        0.00          0.00</span></span>
<span class="line"><span style="color: #D4D4D4">  SQL*Net message from client                     1        0.01          0.01</span></span></code></pre></div>



<h2 class="wp-block-heading"><a name="using_binds"></a>9. Using Bind Variables</h2>



<p class="wp-block-paragraph">Parsing can be costly, as we have seen in the previous example. Using bind variables can reduce parsing. In this case I&#8217;d like to see how I can avoid hard- and soft-parsing. See <a href="http://www.orafaq.com/wiki/Parsing">Oracle FAQs</a> for good parsing definitions.</p>



<h3 class="wp-block-heading">JOOQ Query</h3>



<p class="wp-block-paragraph">JOOQ automatically creates bind variables for the usages of <code>fromSalary</code> and <code>toSalary</code> on line 23. This means that JOOQ eliminates unnecessary hard parses by design. To eliminate unnecessary soft-parses we have to ensure that the Java statement behind the scenes is not closed. JOOQ provides the <code>keepStatement</code> function for that purpose as used on line 25. When using this function we are responsible to close the statement. We do so on line 7.</p>



<p class="wp-block-paragraph">We call the query twice. See lines 36 and 37. On the first call, the bind variables are set automatically by JOOQ when building the <code>preparedQuery</code>. On subsequent calls the <code>preparedQuery</code> is reused and its bind variable values are changed. See line 27 and 28. Fetching and printing works as for the other JOOQ queries. The only difference is, that the statement is not closed after the last row is fetched.</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">Bind Variables &#8211; JOOQ Query</span><span role="button" tabindex="0" data-code="public class Main {
   private static ResultQuery<?&gt; preparedQuery;
   (...)
   private static void closeCtx() throws SQLException {
      disableSqlTrace();
      if (preparedQuery != null) {
         preparedQuery.close();
      }
      ctx.close();
   }
   (...)
   private static void queryEmployeesInSalaryRange(BigDecimal fromSalary, BigDecimal toSalary) {
      if (preparedQuery == null) {
         preparedQuery = ctx
               .select(JOBS_V.JOB_TITLE,
                     EMPLOYEES_V.LAST_NAME,
                     EMPLOYEES_V.FIRST_NAME,
                     EMPLOYEES_V.SALARY,
                     JOBS_V.MIN_SALARY,
                     JOBS_V.MAX_SALARY)
               .from(EMPLOYEES_V)
               .join(JOBS_V).onKey()
               .where(EMPLOYEES_V.SALARY.between(fromSalary, toSalary))
               .orderBy(EMPLOYEES_V.SALARY.desc())
               .keepStatement(true);
      } else {
         preparedQuery.bind(1, fromSalary);
         preparedQuery.bind(2, toSalary);
      }
      fetchAndPrint(&quot;Employees in Salary Range&quot;, preparedQuery);
   }
   (...)
   public static void main(String[] args) throws SQLException {
      initCtx(true);
      (...)
      queryEmployeesInSalaryRange(BigDecimal.valueOf(13000), BigDecimal.valueOf(100000));
      queryEmployeesInSalaryRange(BigDecimal.valueOf(10000), BigDecimal.valueOf(13000));
      closeCtx();
   }
}" 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">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">class</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">Main</span><span style="color: #D4D4D4"> {</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ResultQuery</span><span style="color: #D4D4D4">&lt;</span><span style="color: #569CD6">?</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">preparedQuery</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">   (...)</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">closeCtx</span><span style="color: #D4D4D4">() </span><span style="color: #569CD6">throws</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">SQLException</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">disableSqlTrace</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (preparedQuery != </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">) {</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">         </span><span style="color: #9CDCFE">preparedQuery</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">close</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">      }</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">ctx</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">close</span><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">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">queryEmployeesInSalaryRange</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">BigDecimal</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">fromSalary</span><span style="color: #D4D4D4">, </span><span style="color: #4EC9B0">BigDecimal</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">toSalary</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (preparedQuery == </span><span style="color: #569CD6">null</span><span style="color: #D4D4D4">) {</span></span>
<span class="line"><span style="color: #D4D4D4">         preparedQuery = ctx</span></span>
<span class="line"><span style="color: #D4D4D4">               .</span><span style="color: #DCDCAA">select</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">JOBS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">JOB_TITLE</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                     </span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">LAST_NAME</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                     </span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">FIRST_NAME</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                     </span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">SALARY</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                     </span><span style="color: #9CDCFE">JOBS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">MIN_SALARY</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                     </span><span style="color: #9CDCFE">JOBS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">MAX_SALARY</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">               .</span><span style="color: #DCDCAA">from</span><span style="color: #D4D4D4">(EMPLOYEES_V)</span></span>
<span class="line"><span style="color: #D4D4D4">               .</span><span style="color: #DCDCAA">join</span><span style="color: #D4D4D4">(JOBS_V).</span><span style="color: #DCDCAA">onKey</span><span style="color: #D4D4D4">()</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">               .</span><span style="color: #DCDCAA">where</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">SALARY</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">between</span><span style="color: #D4D4D4">(fromSalary, toSalary))</span></span>
<span class="line"><span style="color: #D4D4D4">               .</span><span style="color: #DCDCAA">orderBy</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">SALARY</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">desc</span><span style="color: #D4D4D4">())</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">               .</span><span style="color: #DCDCAA">keepStatement</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">true</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      } </span><span style="color: #C586C0">else</span><span style="color: #D4D4D4"> {</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">         </span><span style="color: #9CDCFE">preparedQuery</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">bind</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">, fromSalary);</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">         </span><span style="color: #9CDCFE">preparedQuery</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">bind</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">2</span><span style="color: #D4D4D4">, toSalary);</span></span>
<span class="line"><span style="color: #D4D4D4">      }</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">fetchAndPrint</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;Employees in Salary Range&quot;</span><span style="color: #D4D4D4">, preparedQuery);</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 style="color: #569CD6">public</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">main</span><span style="color: #D4D4D4">(</span><span style="color: #4EC9B0">String</span><span style="color: #D4D4D4">[] </span><span style="color: #9CDCFE">args</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">throws</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">SQLException</span><span style="color: #D4D4D4"> {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">initCtx</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">true</span><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">      </span><span style="color: #DCDCAA">queryEmployeesInSalaryRange</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">BigDecimal</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">valueOf</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">13000</span><span style="color: #D4D4D4">), </span><span style="color: #9CDCFE">BigDecimal</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">valueOf</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">100000</span><span style="color: #D4D4D4">));</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">queryEmployeesInSalaryRange</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">BigDecimal</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">valueOf</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">10000</span><span style="color: #D4D4D4">), </span><span style="color: #9CDCFE">BigDecimal</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">valueOf</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">13000</span><span style="color: #D4D4D4">));</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">closeCtx</span><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>



<h3 class="wp-block-heading">SQL Query &amp; Result</h3>



<p class="wp-block-paragraph">We are executing the query twice. Hence we see two output sets.</p>



<p class="wp-block-paragraph">On lines 13/45, you see the bind variable placeholders (?).</p>



<p class="wp-block-paragraph">On lines 17-18/49-50, you see the values of the bind variables.</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">Plaintext</span><span role="button" tabindex="0" data-code="Employees in Salary Range: 

select 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_TITLE&quot;, 
  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;LAST_NAME&quot;, 
  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;FIRST_NAME&quot;, 
  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;, 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MIN_SALARY&quot;, 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MAX_SALARY&quot;
from &quot;HR&quot;.&quot;EMPLOYEES_V&quot;
  join &quot;HR&quot;.&quot;JOBS_V&quot;
  on &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;JOB_ID&quot; = &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_ID&quot;
where &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot; between ? and ?
order by &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot; desc

Employees in Salary Range binds:
   :1 = 13000
   :2 = 100000

Employees in Salary Range result (6 rows): 

+-----------------------------+---------+----------+------+----------+----------+
|JOB_TITLE                    |LAST_NAME|FIRST_NAME|SALARY|MIN_SALARY|MAX_SALARY|
+-----------------------------+---------+----------+------+----------+----------+
|President                    |King     |Steven    | 24000|     20080|     40000|
|Administration Vice President|Kochhar  |Neena     | 17000|     15000|     30000|
|Administration Vice President|De Haan  |Lex       | 17000|     15000|     30000|
|Sales Manager                |Russell  |John      | 14000|     10000|     20080|
|Sales Manager                |Partners |Karen     | 13500|     10000|     20080|
|Marketing Manager            |Hartstein|Michael   | 13000|      9000|     15000|
+-----------------------------+---------+----------+------+----------+----------+

Employees in Salary Range: 

select 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_TITLE&quot;, 
  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;LAST_NAME&quot;, 
  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;FIRST_NAME&quot;, 
  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;, 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MIN_SALARY&quot;, 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MAX_SALARY&quot;
from &quot;HR&quot;.&quot;EMPLOYEES_V&quot;
  join &quot;HR&quot;.&quot;JOBS_V&quot;
  on &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;JOB_ID&quot; = &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_ID&quot;
where &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot; between ? and ?
order by &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot; desc

Employees in Salary Range binds:
   :1 = 10000
   :2 = 13000

Employees in Salary Range result (14 rows): 

+-------------------------------+---------+----------+------+----------+----------+
|JOB_TITLE                      |LAST_NAME|FIRST_NAME|SALARY|MIN_SALARY|MAX_SALARY|
+-------------------------------+---------+----------+------+----------+----------+
|Marketing Manager              |Hartstein|Michael   | 13000|      9000|     15000|
|Finance Manager                |Greenberg|Nancy     | 12008|      8200|     16000|
|Accounting Manager             |Higgins  |Shelley   | 12008|      8200|     16000|
|Sales Manager                  |Errazuriz|Alberto   | 12000|     10000|     20080|
|Sales Representative           |Ozer     |Lisa      | 11500|      6000|     12008|
|Purchasing Manager             |Raphaely |Den       | 11000|      8000|     15000|
|Sales Manager                  |Cambrault|Gerald    | 11000|     10000|     20080|
|Sales Representative           |Abel     |Ellen     | 11000|      6000|     12008|
|Sales Representative           |Vishney  |Clara     | 10500|      6000|     12008|
|Sales Manager                  |Zlotkey  |Eleni     | 10500|     10000|     20080|
|Sales Representative           |Tucker   |Peter     | 10000|      6000|     12008|
|Sales Representative           |Bloom    |Harrison  | 10000|      6000|     12008|
|Public Relations Representative|Baer     |Hermann   | 10000|      4500|     10500|
|Sales Representative           |King     |Janette   | 10000|      6000|     12008|
+-------------------------------+---------+----------+------+----------+----------+" 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">Employees in Salary Range: </span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">select </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_TITLE&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;LAST_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;FIRST_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MIN_SALARY&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MAX_SALARY&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">from &quot;HR&quot;.&quot;EMPLOYEES_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  join &quot;HR&quot;.&quot;JOBS_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  on &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;JOB_ID&quot; = &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_ID&quot;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">where &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot; between ? and ?</span></span>
<span class="line"><span style="color: #D4D4D4">order by &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot; desc</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Employees in Salary Range binds:</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">   :1 = 13000</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">   :2 = 100000</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Employees in Salary Range result (6 rows): </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">|JOB_TITLE                    |LAST_NAME|FIRST_NAME|SALARY|MIN_SALARY|MAX_SALARY|</span></span>
<span class="line"><span style="color: #D4D4D4">+-----------------------------+---------+----------+------+----------+----------+</span></span>
<span class="line"><span style="color: #D4D4D4">|President                    |King     |Steven    | 24000|     20080|     40000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Administration Vice President|Kochhar  |Neena     | 17000|     15000|     30000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Administration Vice President|De Haan  |Lex       | 17000|     15000|     30000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Manager                |Russell  |John      | 14000|     10000|     20080|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Manager                |Partners |Karen     | 13500|     10000|     20080|</span></span>
<span class="line"><span style="color: #D4D4D4">|Marketing Manager            |Hartstein|Michael   | 13000|      9000|     15000|</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">Employees in Salary Range: </span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">select </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_TITLE&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;LAST_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;FIRST_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MIN_SALARY&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MAX_SALARY&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">from &quot;HR&quot;.&quot;EMPLOYEES_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  join &quot;HR&quot;.&quot;JOBS_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  on &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;JOB_ID&quot; = &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_ID&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">where &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot; between ? and ?</span></span>
<span class="line"><span style="color: #D4D4D4">order by &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot; desc</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Employees in Salary Range binds:</span></span>
<span class="line"><span style="color: #D4D4D4">   :1 = 10000</span></span>
<span class="line"><span style="color: #D4D4D4">   :2 = 13000</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Employees in Salary Range result (14 rows): </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">|JOB_TITLE                      |LAST_NAME|FIRST_NAME|SALARY|MIN_SALARY|MAX_SALARY|</span></span>
<span class="line"><span style="color: #D4D4D4">+-------------------------------+---------+----------+------+----------+----------+</span></span>
<span class="line"><span style="color: #D4D4D4">|Marketing Manager              |Hartstein|Michael   | 13000|      9000|     15000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Finance Manager                |Greenberg|Nancy     | 12008|      8200|     16000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Accounting Manager             |Higgins  |Shelley   | 12008|      8200|     16000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Manager                  |Errazuriz|Alberto   | 12000|     10000|     20080|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Representative           |Ozer     |Lisa      | 11500|      6000|     12008|</span></span>
<span class="line"><span style="color: #D4D4D4">|Purchasing Manager             |Raphaely |Den       | 11000|      8000|     15000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Manager                  |Cambrault|Gerald    | 11000|     10000|     20080|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Representative           |Abel     |Ellen     | 11000|      6000|     12008|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Representative           |Vishney  |Clara     | 10500|      6000|     12008|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Manager                  |Zlotkey  |Eleni     | 10500|     10000|     20080|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Representative           |Tucker   |Peter     | 10000|      6000|     12008|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Representative           |Bloom    |Harrison  | 10000|      6000|     12008|</span></span>
<span class="line"><span style="color: #D4D4D4">|Public Relations Representative|Baer     |Hermann   | 10000|      4500|     10500|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Representative           |King     |Janette   | 10000|      6000|     12008|</span></span>
<span class="line"><span style="color: #D4D4D4">+-------------------------------+---------+----------+------+----------+----------+</span></span></code></pre></div>



<h3 class="wp-block-heading">SQL Trace Output</h3>



<p class="wp-block-paragraph">The <code>tkprof</code> excerpt on line 4 shows that the query is executed twice. Line 3 reveals that the query is parsed only once. The total of 20 rows are read in two network roundtrips. That&#8217;s perfect.</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">Bind Variables &#8211; TKPROF excerpt</span><span role="button" tabindex="0" data-code="call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      2      0.01       0.05          0          0          0           0
Fetch        2      0.00       0.00          0         16          0          20
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        5      0.01       0.05          0         16          0          20

Misses in library cache during parse: 1
Misses in library cache during execute: 1
Optimizer mode: ALL_ROWS
Parsing user id: 133  
Number of plan statistics captured: 2

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         6         10         14  SORT ORDER BY (cr=8 pr=0 pw=0 time=160 us starts=1 cost=7 size=366 card=6)
         6         10         14   FILTER  (cr=8 pr=0 pw=0 time=156 us starts=1)
         6         10         14    MERGE JOIN  (cr=8 pr=0 pw=0 time=153 us starts=1 cost=6 size=366 card=6)
        16         16         17     TABLE ACCESS BY INDEX ROWID JOBS (cr=2 pr=0 pw=0 time=38 us starts=1 cost=2 size=627 card=19)
        16         16         17      INDEX FULL SCAN JOB_ID_PK (cr=1 pr=0 pw=0 time=20 us starts=1 cost=1 size=0 card=19)(object id 78619)
         6         10         14     SORT JOIN (cr=6 pr=0 pw=0 time=94 us starts=16 cost=4 size=168 card=6)
         6         10         14      TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=68 us starts=1 cost=3 size=168 card=6)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       2        0.00          0.00
  SQL*Net message from client                     2        0.00          0.00" 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">call     count       cpu    elapsed       disk      query    current        rows</span></span>
<span class="line"><span style="color: #D4D4D4">------- ------  -------- ---------- ---------- ---------- ----------  ----------</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Parse        1      0.00       0.00          0          0          0           0</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Execute      2      0.01       0.05          0          0          0           0</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Fetch        2      0.00       0.00          0         16          0          20</span></span>
<span class="line"><span style="color: #D4D4D4">------- ------  -------- ---------- ---------- ---------- ----------  ----------</span></span>
<span class="line"><span style="color: #D4D4D4">total        5      0.01       0.05          0         16          0          20</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Misses in library cache during parse: 1</span></span>
<span class="line"><span style="color: #D4D4D4">Misses in library cache during execute: 1</span></span>
<span class="line"><span style="color: #D4D4D4">Optimizer mode: ALL_ROWS</span></span>
<span class="line"><span style="color: #D4D4D4">Parsing user id: 133  </span></span>
<span class="line"><span style="color: #D4D4D4">Number of plan statistics captured: 2</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Rows (1st) Rows (avg) Rows (max)  Row Source Operation</span></span>
<span class="line"><span style="color: #D4D4D4">---------- ---------- ----------  ---------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">         6         10         14  SORT ORDER BY (cr=8 pr=0 pw=0 time=160 us starts=1 cost=7 size=366 card=6)</span></span>
<span class="line"><span style="color: #D4D4D4">         6         10         14   FILTER  (cr=8 pr=0 pw=0 time=156 us starts=1)</span></span>
<span class="line"><span style="color: #D4D4D4">         6         10         14    MERGE JOIN  (cr=8 pr=0 pw=0 time=153 us starts=1 cost=6 size=366 card=6)</span></span>
<span class="line"><span style="color: #D4D4D4">        16         16         17     TABLE ACCESS BY INDEX ROWID JOBS (cr=2 pr=0 pw=0 time=38 us starts=1 cost=2 size=627 card=19)</span></span>
<span class="line"><span style="color: #D4D4D4">        16         16         17      INDEX FULL SCAN JOB_ID_PK (cr=1 pr=0 pw=0 time=20 us starts=1 cost=1 size=0 card=19)(object id 78619)</span></span>
<span class="line"><span style="color: #D4D4D4">         6         10         14     SORT JOIN (cr=6 pr=0 pw=0 time=94 us starts=16 cost=4 size=168 card=6)</span></span>
<span class="line"><span style="color: #D4D4D4">         6         10         14      TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=68 us starts=1 cost=3 size=168 card=6)</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">Elapsed times include waiting on following events:</span></span>
<span class="line"><span style="color: #D4D4D4">  Event waited on                             Times   Max. Wait  Total Waited</span></span>
<span class="line"><span style="color: #D4D4D4">  ----------------------------------------   Waited  ----------  ------------</span></span>
<span class="line"><span style="color: #D4D4D4">  SQL*Net message to client                       2        0.00          0.00</span></span>
<span class="line"><span style="color: #D4D4D4">  SQL*Net message from client                     2        0.00          0.00</span></span></code></pre></div>



<h2 class="wp-block-heading"><a name="run_top_n_query"></a>10. Run a Top N Query</h2>



<p class="wp-block-paragraph">In the next example we query the 4 employees with the lowest salary along with some general salary information. It&#8217;ll be interesting to see if JOOQ uses Oracle&#8217;s native top-n query syntax.</p>



<h3 class="wp-block-heading">JOOQ Query</h3>



<p class="wp-block-paragraph">On line 8 we see that JOOQ has no problems dealing with analytic functions.</p>



<p class="wp-block-paragraph">On line 14 the top n query is defined. Limit the result to 4 rows with ties, this means rows with the same order by values are considered as well.</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">Top N Query &#8211; JOOQ Query</span><span role="button" tabindex="0" data-code="   private static void queryTopBadEarners() {
       final ResultQuery<?&gt; query = ctx
            .select(JOBS_V.JOB_TITLE,
                  EMPLOYEES_V.LAST_NAME,
                  EMPLOYEES_V.FIRST_NAME,
                  EMPLOYEES_V.HIRE_DATE,
                  EMPLOYEES_V.SALARY,
                  avg(EMPLOYEES_V.SALARY).over().partitionBy(EMPLOYEES_V.JOB_ID).as(&quot;avg_salary&quot;),
                  JOBS_V.MIN_SALARY,
                  JOBS_V.MAX_SALARY)
            .from(EMPLOYEES_V)
            .join(JOBS_V).onKey()
            .orderBy(EMPLOYEES_V.SALARY)
            .limit(4).withTies();
      fetchAndPrint(&quot;Top 4 Bad Earners&quot;, query);
   }" 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">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">queryTopBadEarners</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">       </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ResultQuery</span><span style="color: #D4D4D4">&lt;</span><span style="color: #569CD6">?</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">query</span><span style="color: #D4D4D4"> = ctx</span></span>
<span class="line"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">select</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">JOBS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">JOB_TITLE</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">LAST_NAME</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">FIRST_NAME</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">HIRE_DATE</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">SALARY</span><span style="color: #D4D4D4">,</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">                  </span><span style="color: #DCDCAA">avg</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">SALARY</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">over</span><span style="color: #D4D4D4">().</span><span style="color: #DCDCAA">partitionBy</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">JOB_ID</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">as</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;avg_salary&quot;</span><span style="color: #D4D4D4">),</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #9CDCFE">JOBS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">MIN_SALARY</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #9CDCFE">JOBS_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">MAX_SALARY</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">from</span><span style="color: #D4D4D4">(EMPLOYEES_V)</span></span>
<span class="line"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">join</span><span style="color: #D4D4D4">(JOBS_V).</span><span style="color: #DCDCAA">onKey</span><span style="color: #D4D4D4">()</span></span>
<span class="line"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">orderBy</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">EMPLOYEES_V</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">SALARY</span><span style="color: #D4D4D4">)</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">            .</span><span style="color: #DCDCAA">limit</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">4</span><span style="color: #D4D4D4">).</span><span style="color: #DCDCAA">withTies</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">fetchAndPrint</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;Top 4 Bad Earners&quot;</span><span style="color: #D4D4D4">, query);</span></span>
<span class="line"><span style="color: #D4D4D4">   }</span></span></code></pre></div>



<h3 class="wp-block-heading">SQL Query &amp; Result</h3>



<p class="wp-block-paragraph">The query crafted by JOOQ is a native Oracle top n query. See line 16. Very good.</p>



<p class="wp-block-paragraph">Interesting is, that JOOQ also creates a bind variable for the literal 4. This could be good or bad. If you want to use a literal instead of a bind variable, you can simply use <code>inline(4)</code>&nbsp; instead of <code>4</code>. The default behaviour of JOOQ reminds a little of <code>CURSOR_SHARING=FORCE</code>. But since you may control the behaviour on statement level, I think it is a good and sensible default.</p>



<p class="wp-block-paragraph">We got a result of 5 rows, because Landry and Gee both have a salary of 2400. That&#8217;s the result of <code>WITH TIES</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);--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">Top N Query &#8211; SQL Query &amp; Result</span><span role="button" tabindex="0" data-code="Top 4 Bad Earners: 

select 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_TITLE&quot;, 
  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;LAST_NAME&quot;, 
  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;FIRST_NAME&quot;, 
  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;HIRE_DATE&quot;, 
  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;, 
  avg(&quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;) over (partition by &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;JOB_ID&quot;) &quot;avg_salary&quot;, 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MIN_SALARY&quot;, 
  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MAX_SALARY&quot;
from &quot;HR&quot;.&quot;EMPLOYEES_V&quot;
  join &quot;HR&quot;.&quot;JOBS_V&quot;
  on &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;JOB_ID&quot; = &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_ID&quot;
order by &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;
fetch next ? rows with ties

Top 4 Bad Earners binds:
   :1 = 4

Top 4 Bad Earners result (5 rows): 

+-----------+----------+----------+----------+------+----------+----------+----------+
|JOB_TITLE  |LAST_NAME |FIRST_NAME|HIRE_DATE |SALARY|avg_salary|MIN_SALARY|MAX_SALARY|
+-----------+----------+----------+----------+------+----------+----------+----------+
|Stock Clerk|Olson     |TJ        |2007-04-10|  2100|      2785|      2008|      5000|
|Stock Clerk|Markle    |Steven    |2008-03-08|  2200|      2785|      2008|      5000|
|Stock Clerk|Philtanker|Hazel     |2008-02-06|  2200|      2785|      2008|      5000|
|Stock Clerk|Landry    |James     |2007-01-14|  2400|      2785|      2008|      5000|
|Stock Clerk|Gee       |Ki        |2007-12-12|  2400|      2785|      2008|      5000|
+-----------+----------+----------+----------+------+----------+----------+----------+" 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">Top 4 Bad Earners: </span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">select </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_TITLE&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;LAST_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;FIRST_NAME&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;HIRE_DATE&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  avg(&quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;) over (partition by &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;JOB_ID&quot;) &quot;avg_salary&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MIN_SALARY&quot;, </span></span>
<span class="line"><span style="color: #D4D4D4">  &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;MAX_SALARY&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">from &quot;HR&quot;.&quot;EMPLOYEES_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  join &quot;HR&quot;.&quot;JOBS_V&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">  on &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;JOB_ID&quot; = &quot;HR&quot;.&quot;JOBS_V&quot;.&quot;JOB_ID&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">order by &quot;HR&quot;.&quot;EMPLOYEES_V&quot;.&quot;SALARY&quot;</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">fetch next ? rows with ties</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Top 4 Bad Earners binds:</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">   :1 = 4</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Top 4 Bad Earners result (5 rows): </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">|JOB_TITLE  |LAST_NAME |FIRST_NAME|HIRE_DATE |SALARY|avg_salary|MIN_SALARY|MAX_SALARY|</span></span>
<span class="line"><span style="color: #D4D4D4">+-----------+----------+----------+----------+------+----------+----------+----------+</span></span>
<span class="line"><span style="color: #D4D4D4">|Stock Clerk|Olson     |TJ        |2007-04-10|  2100|      2785|      2008|      5000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Stock Clerk|Markle    |Steven    |2008-03-08|  2200|      2785|      2008|      5000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Stock Clerk|Philtanker|Hazel     |2008-02-06|  2200|      2785|      2008|      5000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Stock Clerk|Landry    |James     |2007-01-14|  2400|      2785|      2008|      5000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Stock Clerk|Gee       |Ki        |2007-12-12|  2400|      2785|      2008|      5000|</span></span>
<span class="line"><span style="color: #D4D4D4">+-----------+----------+----------+----------+------+----------+----------+----------+</span></span></code></pre></div>



<h3 class="wp-block-heading">SQL Trace Output</h3>



<p class="wp-block-paragraph">The <code>tkprof</code> excerpt looks good. Good performance, single network roundtrip.</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">Top N Query &#8211; TKPROF excerpt</span><span role="button" tabindex="0" data-code="call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      0.00       0.00          0          8          0           5
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      0.00       0.01          0          8          0           5

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 133  
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
         5          5          5  VIEW  (cr=8 pr=0 pw=0 time=335 us starts=1 cost=7 size=14124 card=107)
        11         11         11   WINDOW SORT PUSHED RANK (cr=8 pr=0 pw=0 time=326 us starts=1 cost=7 size=7383 card=107)
       107        107        107    WINDOW BUFFER (cr=8 pr=0 pw=0 time=260 us starts=1 cost=7 size=7383 card=107)
       107        107        107     MERGE JOIN  (cr=8 pr=0 pw=0 time=634 us starts=1 cost=6 size=7383 card=107)
        19         19         19      TABLE ACCESS BY INDEX ROWID JOBS (cr=2 pr=0 pw=0 time=42 us starts=1 cost=2 size=627 card=19)
        19         19         19       INDEX FULL SCAN JOB_ID_PK (cr=1 pr=0 pw=0 time=30 us starts=1 cost=1 size=0 card=19)(object id 78619)
       107        107        107      SORT JOIN (cr=6 pr=0 pw=0 time=97 us starts=19 cost=4 size=3852 card=107)
       107        107        107       TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=28 us starts=1 cost=3 size=3852 card=107)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1        0.01          0.01" 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">call     count       cpu    elapsed       disk      query    current        rows</span></span>
<span class="line"><span style="color: #D4D4D4">------- ------  -------- ---------- ---------- ---------- ----------  ----------</span></span>
<span class="line"><span style="color: #D4D4D4">Parse        1      0.00       0.00          0          0          0           0</span></span>
<span class="line"><span style="color: #D4D4D4">Execute      1      0.00       0.00          0          0          0           0</span></span>
<span class="line"><span style="color: #D4D4D4">Fetch        1      0.00       0.00          0          8          0           5</span></span>
<span class="line"><span style="color: #D4D4D4">------- ------  -------- ---------- ---------- ---------- ----------  ----------</span></span>
<span class="line"><span style="color: #D4D4D4">total        3      0.00       0.01          0          8          0           5</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Misses in library cache during parse: 1</span></span>
<span class="line"><span style="color: #D4D4D4">Optimizer mode: ALL_ROWS</span></span>
<span class="line"><span style="color: #D4D4D4">Parsing user id: 133  </span></span>
<span class="line"><span style="color: #D4D4D4">Number of plan statistics captured: 1</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Rows (1st) Rows (avg) Rows (max)  Row Source Operation</span></span>
<span class="line"><span style="color: #D4D4D4">---------- ---------- ----------  ---------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">         5          5          5  VIEW  (cr=8 pr=0 pw=0 time=335 us starts=1 cost=7 size=14124 card=107)</span></span>
<span class="line"><span style="color: #D4D4D4">        11         11         11   WINDOW SORT PUSHED RANK (cr=8 pr=0 pw=0 time=326 us starts=1 cost=7 size=7383 card=107)</span></span>
<span class="line"><span style="color: #D4D4D4">       107        107        107    WINDOW BUFFER (cr=8 pr=0 pw=0 time=260 us starts=1 cost=7 size=7383 card=107)</span></span>
<span class="line"><span style="color: #D4D4D4">       107        107        107     MERGE JOIN  (cr=8 pr=0 pw=0 time=634 us starts=1 cost=6 size=7383 card=107)</span></span>
<span class="line"><span style="color: #D4D4D4">        19         19         19      TABLE ACCESS BY INDEX ROWID JOBS (cr=2 pr=0 pw=0 time=42 us starts=1 cost=2 size=627 card=19)</span></span>
<span class="line"><span style="color: #D4D4D4">        19         19         19       INDEX FULL SCAN JOB_ID_PK (cr=1 pr=0 pw=0 time=30 us starts=1 cost=1 size=0 card=19)(object id 78619)</span></span>
<span class="line"><span style="color: #D4D4D4">       107        107        107      SORT JOIN (cr=6 pr=0 pw=0 time=97 us starts=19 cost=4 size=3852 card=107)</span></span>
<span class="line"><span style="color: #D4D4D4">       107        107        107       TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=28 us starts=1 cost=3 size=3852 card=107)</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">Elapsed times include waiting on following events:</span></span>
<span class="line"><span style="color: #D4D4D4">  Event waited on                             Times   Max. Wait  Total Waited</span></span>
<span class="line"><span style="color: #D4D4D4">  ----------------------------------------   Waited  ----------  ------------</span></span>
<span class="line"><span style="color: #D4D4D4">  SQL*Net message to client                       1        0.00          0.00</span></span>
<span class="line"><span style="color: #D4D4D4">  SQL*Net message from client                     1        0.01          0.01</span></span></code></pre></div>



<h2 class="wp-block-heading"><a name="using_row_pattern_matching"></a>11. Using Row Pattern Matching</h2>



<p class="wp-block-paragraph">What about <code>match_recognize</code>, does JOOQ support that? No, not currently. JOOQ has some limitations regarding SQL support. <code>match_recognize</code> is one and the <code>model_clause</code> is another. This is something to be expected, since the SQL grammar is still evolving. However, the question is, how do we deal with queries that must apply some SQL which cannot be created by JOOQ&#8217;s query builder? The solution is simple. We simply pass the pure SQL to JOOQ.</p>



<h3 class="wp-block-heading">&nbsp;JOOQ Query</h3>



<p class="wp-block-paragraph">There are other ways to produce the same result without using <code>match_recognize</code>. However, if you would like to use JOOQ and <code>match_recognize</code> then you have to build the SQL yourself and pass it to JOOQ as on line 58.</p>



<p class="wp-block-paragraph">It&#8217;s sad that Java still does not support multiline strings. The code is much simpler in other JVM languages that support multiline strings, such as Scala, Groovy, Kotlin or Xtend.</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">Row Pattern Matching &#8211; JOOQ Query</span><span role="button" tabindex="0" data-code="   private static void queryBestPayedNewEntries() {
      // using {{\\??\\}} instead of &quot;??&quot; to ensure JDBC does not interpret questions marks as a bind variable placeholders
      // see https://docs.oracle.com/en/database/oracle/oracle-database/18/jjdbc/JDBC-reference-information.html#GUID-3454411C-5F24-4D46-83A9-5DA0BA704F5D
      // documentation is wrong, escaping is required.
      StringBuffer sb = new StringBuffer();
      sb.append(&quot;WITH\n&quot;);
      sb.append(&quot;   base AS (\n&quot;);
      sb.append(&quot;      SELECT emp.employee_id,\n&quot;);
      sb.append(&quot;             emp.last_name,\n&quot;);
      sb.append(&quot;             emp.first_name,\n&quot;);
      sb.append(&quot;             job.job_title,\n&quot;);
      sb.append(&quot;             jhist.start_date,\n&quot;);
      sb.append(&quot;             emp.salary\n&quot;);
      sb.append(&quot;        FROM hr.employees_v emp\n&quot;);
      sb.append(&quot;        JOIN hr.job_history_v jhist\n&quot;);
      sb.append(&quot;          ON jhist.employee_id = emp.employee_id\n&quot;);
      sb.append(&quot;        JOIN hr.jobs_v job\n&quot;);
      sb.append(&quot;          ON job.job_id = jhist.job_id\n&quot;);
      sb.append(&quot;      UNION\n&quot;);
      sb.append(&quot;      SELECT emp.employee_id,\n&quot;);
      sb.append(&quot;             emp.last_name,\n&quot;);
      sb.append(&quot;             emp.first_name,\n&quot;);
      sb.append(&quot;             job.job_title,\n&quot;);
      sb.append(&quot;             emp.hire_date AS start_date,\n&quot;);
      sb.append(&quot;             emp.salary\n&quot;);
      sb.append(&quot;        FROM hr.employees_v emp\n&quot;);
      sb.append(&quot;        JOIN hr.jobs_v job\n&quot;);
      sb.append(&quot;          ON job.job_id = emp.job_id\n&quot;);
      sb.append(&quot;   ),\n&quot;);
      sb.append(&quot;   aggr AS (\n&quot;);
      sb.append(&quot;      SELECT employee_id,\n&quot;);
      sb.append(&quot;             last_name,\n&quot;);
      sb.append(&quot;             first_name,\n&quot;);
      sb.append(&quot;             job_title,\n&quot;);
      sb.append(&quot;             MAX(start_date) AS start_date,\n&quot;);
      sb.append(&quot;             salary,\n&quot;);
      sb.append(&quot;             MAX(salary) OVER (PARTITION BY job_title ORDER BY MAX(start_date)\n&quot;);
      sb.append(&quot;                ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS max_salary\n&quot;);
      sb.append(&quot;        FROM base\n&quot;);
      sb.append(&quot;       GROUP BY employee_id, last_name, first_name, job_title, salary\n&quot;);
      sb.append(&quot;   )\n&quot;);
      sb.append(&quot;SELECT job_title, start_date, last_name, first_name, salary\n&quot;);
      sb.append(&quot;  FROM aggr MATCH_RECOGNIZE (\n&quot;);
      sb.append(&quot;          PARTITION BY job_title\n&quot;);
      sb.append(&quot;          ORDER BY start_date\n&quot;);
      sb.append(&quot;          MEASURES LAST(employee_id) AS employee_id,\n&quot;);
      sb.append(&quot;                   LAST(last_name) AS last_name,\n&quot;);
      sb.append(&quot;                   LAST(first_name) AS first_name,\n&quot;);
      sb.append(&quot;                   LAST(start_date) AS start_date,\n&quot;);
      sb.append(&quot;                   LAST(salary) AS salary\n&quot;);
      sb.append(&quot;          ONE ROW PER MATCH\n&quot;);
      sb.append(&quot;          PATTERN((strt down*){{\\??\\}} up)\n&quot;);
      sb.append(&quot;          DEFINE strt AS salary = MAX(max_salary),\n&quot;);
      sb.append(&quot;                 down AS salary < MAX(max_salary),\n&quot;);
      sb.append(&quot;                 up AS salary = MAX(max_salary)\n&quot;);
      sb.append(&quot;       )\n&quot;);
      sb.append(&quot; ORDER BY job_title, start_date&quot;);
      final ResultQuery<Record&gt; query = ctx.resultQuery(sb.toString());
      fetchAndPrint(&quot;Best Payed New Entries&quot;, query);
   }" 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">   </span><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">static</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">void</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">queryBestPayedNewEntries</span><span style="color: #D4D4D4">() {</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #6A9955">// using {{\\??\\}} instead of &quot;??&quot; to ensure JDBC does not interpret questions marks as a bind variable placeholders</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #6A9955">// see https://docs.oracle.com/en/database/oracle/oracle-database/18/jjdbc/JDBC-reference-information.html#GUID-3454411C-5F24-4D46-83A9-5DA0BA704F5D</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #6A9955">// documentation is wrong, escaping is required.</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #4EC9B0">StringBuffer</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4"> = </span><span style="color: #C586C0">new</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">StringBuffer</span><span style="color: #D4D4D4">();</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;WITH</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;   base AS (</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;      SELECT emp.employee_id,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             emp.last_name,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             emp.first_name,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             job.job_title,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             jhist.start_date,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             emp.salary</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;        FROM hr.employees_v emp</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;        JOIN hr.job_history_v jhist</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;          ON jhist.employee_id = emp.employee_id</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;        JOIN hr.jobs_v job</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;          ON job.job_id = jhist.job_id</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;      UNION</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;      SELECT emp.employee_id,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             emp.last_name,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             emp.first_name,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             job.job_title,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             emp.hire_date AS start_date,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             emp.salary</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;        FROM hr.employees_v emp</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;        JOIN hr.jobs_v job</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;          ON job.job_id = emp.job_id</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;   ),</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;   aggr AS (</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;      SELECT employee_id,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             last_name,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             first_name,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             job_title,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             MAX(start_date) AS start_date,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             salary,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;             MAX(salary) OVER (PARTITION BY job_title ORDER BY MAX(start_date)</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;                ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS max_salary</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;        FROM base</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;       GROUP BY employee_id, last_name, first_name, job_title, salary</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;   )</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;SELECT job_title, start_date, last_name, first_name, salary</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;  FROM aggr MATCH_RECOGNIZE (</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;          PARTITION BY job_title</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;          ORDER BY start_date</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;          MEASURES LAST(employee_id) AS employee_id,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;                   LAST(last_name) AS last_name,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;                   LAST(first_name) AS first_name,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;                   LAST(start_date) AS start_date,</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;                   LAST(salary) AS salary</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;          ONE ROW PER MATCH</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;          PATTERN((strt down*){{</span><span style="color: #D7BA7D">\\</span><span style="color: #CE9178">??</span><span style="color: #D7BA7D">\\</span><span style="color: #CE9178">}} up)</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;          DEFINE strt AS salary = MAX(max_salary),</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;                 down AS salary &lt; MAX(max_salary),</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;                 up AS salary = MAX(max_salary)</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;       )</span><span style="color: #D7BA7D">\n</span><span style="color: #CE9178">&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">append</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot; ORDER BY job_title, start_date&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">final</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">ResultQuery</span><span style="color: #D4D4D4">&lt;</span><span style="color: #4EC9B0">Record</span><span style="color: #D4D4D4">&gt; </span><span style="color: #9CDCFE">query</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">ctx</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">resultQuery</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">sb</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">toString</span><span style="color: #D4D4D4">());</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">fetchAndPrint</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">&quot;Best Payed New Entries&quot;</span><span style="color: #D4D4D4">, query);</span></span>
<span class="line"><span style="color: #D4D4D4">   }</span></span></code></pre></div>



<h3 class="wp-block-heading">SQL Query &amp; Result</h3>



<p class="wp-block-paragraph">On line 49 you see that <code>{\??\}</code>&nbsp; is used instead of <code>??</code>. This is a necessity for the JDBC driver. Otherwise, the driver would expect bind variables for these question marks. All Java-based tools such as SQL Developer and SQLcl do have the same &#8220;problem&#8221;.</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">Row Pattern Matching &#8211; SQL Query &amp; Result</span><span role="button" tabindex="0" data-code="Best Payed New Entries: 

WITH
   base AS (
      SELECT emp.employee_id,
             emp.last_name,
             emp.first_name,
             job.job_title,
             jhist.start_date,
             emp.salary
        FROM hr.employees_v emp
        JOIN hr.job_history_v jhist
          ON jhist.employee_id = emp.employee_id
        JOIN hr.jobs_v job
          ON job.job_id = jhist.job_id
      UNION
      SELECT emp.employee_id,
             emp.last_name,
             emp.first_name,
             job.job_title,
             emp.hire_date AS start_date,
             emp.salary
        FROM hr.employees_v emp
        JOIN hr.jobs_v job
          ON job.job_id = emp.job_id
   ),
   aggr AS (
      SELECT employee_id,
             last_name,
             first_name,
             job_title,
             MAX(start_date) AS start_date,
             salary,
             MAX(salary) OVER (PARTITION BY job_title ORDER BY MAX(start_date)
                ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS max_salary
        FROM base
       GROUP BY employee_id, last_name, first_name, job_title, salary
   )
SELECT job_title, start_date, last_name, first_name, salary
  FROM aggr MATCH_RECOGNIZE (
          PARTITION BY job_title
          ORDER BY start_date
          MEASURES LAST(employee_id) AS employee_id,
                   LAST(last_name) AS last_name,
                   LAST(first_name) AS first_name,
                   LAST(start_date) AS start_date,
                   LAST(salary) AS salary
          ONE ROW PER MATCH
          PATTERN((strt down*){\??\} up)
          DEFINE strt AS salary = MAX(max_salary),
                 down AS salary < MAX(max_salary),
                 up AS salary = MAX(max_salary)
       )
 ORDER BY job_title, start_date

Best Payed New Entries result (25 rows): 

+-------------------------------+----------+---------+----------+------+
|JOB_TITLE                      |START_DATE|LAST_NAME|FIRST_NAME|SALARY|
+-------------------------------+----------+---------+----------+------+
|Accountant                     |2002-08-16|Faviet   |Daniel    |  9000|
|Accounting Manager             |2001-10-28|Kochhar  |Neena     | 17000|
|Administration Assistant       |2003-09-17|Whalen   |Jennifer  |  4400|
|Administration Vice President  |2001-01-13|De Haan  |Lex       | 17000|
|Administration Vice President  |2005-09-21|Kochhar  |Neena     | 17000|
|Finance Manager                |2002-08-17|Greenberg|Nancy     | 12008|
|Human Resources Representative |2002-06-07|Mavris   |Susan     |  6500|
|Marketing Manager              |2004-02-17|Hartstein|Michael   | 13000|
|Marketing Representative       |2004-02-17|Hartstein|Michael   | 13000|
|President                      |2003-06-17|King     |Steven    | 24000|
|Programmer                     |2001-01-13|De Haan  |Lex       | 17000|
|Public Accountant              |1997-09-21|Kochhar  |Neena     | 17000|
|Public Relations Representative|2002-06-07|Baer     |Hermann   | 10000|
|Purchasing Clerk               |2003-05-18|Khoo     |Alexander |  3100|
|Purchasing Manager             |2002-12-07|Raphaely |Den       | 11000|
|Sales Manager                  |2004-10-01|Russell  |John      | 14000|
|Sales Representative           |2004-01-30|King     |Janette   | 10000|
|Sales Representative           |2004-05-11|Abel     |Ellen     | 11000|
|Sales Representative           |2005-03-11|Ozer     |Lisa      | 11500|
|Shipping Clerk                 |2004-01-27|Sarchand |Nandita   |  4200|
|Stock Clerk                    |2003-07-14|Ladwig   |Renske    |  3600|
|Stock Clerk                    |2006-03-24|Raphaely |Den       | 11000|
|Stock Manager                  |2003-05-01|Kaufling |Payam     |  7900|
|Stock Manager                  |2004-07-18|Weiss    |Matthew   |  8000|
|Stock Manager                  |2005-04-10|Fripp    |Adam      |  8200|
+-------------------------------+----------+---------+----------+------+" 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">Best Payed New Entries: </span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">WITH</span></span>
<span class="line"><span style="color: #D4D4D4">   base AS (</span></span>
<span class="line"><span style="color: #D4D4D4">      SELECT emp.employee_id,</span></span>
<span class="line"><span style="color: #D4D4D4">             emp.last_name,</span></span>
<span class="line"><span style="color: #D4D4D4">             emp.first_name,</span></span>
<span class="line"><span style="color: #D4D4D4">             job.job_title,</span></span>
<span class="line"><span style="color: #D4D4D4">             jhist.start_date,</span></span>
<span class="line"><span style="color: #D4D4D4">             emp.salary</span></span>
<span class="line"><span style="color: #D4D4D4">        FROM hr.employees_v emp</span></span>
<span class="line"><span style="color: #D4D4D4">        JOIN hr.job_history_v jhist</span></span>
<span class="line"><span style="color: #D4D4D4">          ON jhist.employee_id = emp.employee_id</span></span>
<span class="line"><span style="color: #D4D4D4">        JOIN hr.jobs_v job</span></span>
<span class="line"><span style="color: #D4D4D4">          ON job.job_id = jhist.job_id</span></span>
<span class="line"><span style="color: #D4D4D4">      UNION</span></span>
<span class="line"><span style="color: #D4D4D4">      SELECT emp.employee_id,</span></span>
<span class="line"><span style="color: #D4D4D4">             emp.last_name,</span></span>
<span class="line"><span style="color: #D4D4D4">             emp.first_name,</span></span>
<span class="line"><span style="color: #D4D4D4">             job.job_title,</span></span>
<span class="line"><span style="color: #D4D4D4">             emp.hire_date AS start_date,</span></span>
<span class="line"><span style="color: #D4D4D4">             emp.salary</span></span>
<span class="line"><span style="color: #D4D4D4">        FROM hr.employees_v emp</span></span>
<span class="line"><span style="color: #D4D4D4">        JOIN hr.jobs_v job</span></span>
<span class="line"><span style="color: #D4D4D4">          ON job.job_id = emp.job_id</span></span>
<span class="line"><span style="color: #D4D4D4">   ),</span></span>
<span class="line"><span style="color: #D4D4D4">   aggr AS (</span></span>
<span class="line"><span style="color: #D4D4D4">      SELECT employee_id,</span></span>
<span class="line"><span style="color: #D4D4D4">             last_name,</span></span>
<span class="line"><span style="color: #D4D4D4">             first_name,</span></span>
<span class="line"><span style="color: #D4D4D4">             job_title,</span></span>
<span class="line"><span style="color: #D4D4D4">             MAX(start_date) AS start_date,</span></span>
<span class="line"><span style="color: #D4D4D4">             salary,</span></span>
<span class="line"><span style="color: #D4D4D4">             MAX(salary) OVER (PARTITION BY job_title ORDER BY MAX(start_date)</span></span>
<span class="line"><span style="color: #D4D4D4">                ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS max_salary</span></span>
<span class="line"><span style="color: #D4D4D4">        FROM base</span></span>
<span class="line"><span style="color: #D4D4D4">       GROUP BY employee_id, last_name, first_name, job_title, salary</span></span>
<span class="line"><span style="color: #D4D4D4">   )</span></span>
<span class="line"><span style="color: #D4D4D4">SELECT job_title, start_date, last_name, first_name, salary</span></span>
<span class="line"><span style="color: #D4D4D4">  FROM aggr MATCH_RECOGNIZE (</span></span>
<span class="line"><span style="color: #D4D4D4">          PARTITION BY job_title</span></span>
<span class="line"><span style="color: #D4D4D4">          ORDER BY start_date</span></span>
<span class="line"><span style="color: #D4D4D4">          MEASURES LAST(employee_id) AS employee_id,</span></span>
<span class="line"><span style="color: #D4D4D4">                   LAST(last_name) AS last_name,</span></span>
<span class="line"><span style="color: #D4D4D4">                   LAST(first_name) AS first_name,</span></span>
<span class="line"><span style="color: #D4D4D4">                   LAST(start_date) AS start_date,</span></span>
<span class="line"><span style="color: #D4D4D4">                   LAST(salary) AS salary</span></span>
<span class="line"><span style="color: #D4D4D4">          ONE ROW PER MATCH</span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">          PATTERN((strt down*){\??\} up)</span></span>
<span class="line"><span style="color: #D4D4D4">          DEFINE strt AS salary = MAX(max_salary),</span></span>
<span class="line"><span style="color: #D4D4D4">                 down AS salary &lt; MAX(max_salary),</span></span>
<span class="line"><span style="color: #D4D4D4">                 up AS salary = MAX(max_salary)</span></span>
<span class="line"><span style="color: #D4D4D4">       )</span></span>
<span class="line"><span style="color: #D4D4D4"> ORDER BY job_title, start_date</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Best Payed New Entries result (25 rows): </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">|JOB_TITLE                      |START_DATE|LAST_NAME|FIRST_NAME|SALARY|</span></span>
<span class="line"><span style="color: #D4D4D4">+-------------------------------+----------+---------+----------+------+</span></span>
<span class="line"><span style="color: #D4D4D4">|Accountant                     |2002-08-16|Faviet   |Daniel    |  9000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Accounting Manager             |2001-10-28|Kochhar  |Neena     | 17000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Administration Assistant       |2003-09-17|Whalen   |Jennifer  |  4400|</span></span>
<span class="line"><span style="color: #D4D4D4">|Administration Vice President  |2001-01-13|De Haan  |Lex       | 17000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Administration Vice President  |2005-09-21|Kochhar  |Neena     | 17000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Finance Manager                |2002-08-17|Greenberg|Nancy     | 12008|</span></span>
<span class="line"><span style="color: #D4D4D4">|Human Resources Representative |2002-06-07|Mavris   |Susan     |  6500|</span></span>
<span class="line"><span style="color: #D4D4D4">|Marketing Manager              |2004-02-17|Hartstein|Michael   | 13000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Marketing Representative       |2004-02-17|Hartstein|Michael   | 13000|</span></span>
<span class="line"><span style="color: #D4D4D4">|President                      |2003-06-17|King     |Steven    | 24000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Programmer                     |2001-01-13|De Haan  |Lex       | 17000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Public Accountant              |1997-09-21|Kochhar  |Neena     | 17000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Public Relations Representative|2002-06-07|Baer     |Hermann   | 10000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Purchasing Clerk               |2003-05-18|Khoo     |Alexander |  3100|</span></span>
<span class="line"><span style="color: #D4D4D4">|Purchasing Manager             |2002-12-07|Raphaely |Den       | 11000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Manager                  |2004-10-01|Russell  |John      | 14000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Representative           |2004-01-30|King     |Janette   | 10000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Representative           |2004-05-11|Abel     |Ellen     | 11000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Sales Representative           |2005-03-11|Ozer     |Lisa      | 11500|</span></span>
<span class="line"><span style="color: #D4D4D4">|Shipping Clerk                 |2004-01-27|Sarchand |Nandita   |  4200|</span></span>
<span class="line"><span style="color: #D4D4D4">|Stock Clerk                    |2003-07-14|Ladwig   |Renske    |  3600|</span></span>
<span class="line"><span style="color: #D4D4D4">|Stock Clerk                    |2006-03-24|Raphaely |Den       | 11000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Stock Manager                  |2003-05-01|Kaufling |Payam     |  7900|</span></span>
<span class="line"><span style="color: #D4D4D4">|Stock Manager                  |2004-07-18|Weiss    |Matthew   |  8000|</span></span>
<span class="line"><span style="color: #D4D4D4">|Stock Manager                  |2005-04-10|Fripp    |Adam      |  8200|</span></span>
<span class="line"><span style="color: #D4D4D4">+-------------------------------+----------+---------+----------+------+</span></span></code></pre></div>



<h3 class="wp-block-heading">SQL Trace Output</h3>



<p class="wp-block-paragraph">The <code>tkprof</code> excerpt shows that most of the time is spent parsing the query, but it is still fast. All 25 result rows are fetched in a single network roundtrip.</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">Row Pattern Matching &#8211; TKPROF excerpt</span><span role="button" tabindex="0" data-code="call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.01       0.20          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        1      0.00       0.00          0         22          0          25
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        3      0.01       0.20          0         22          0          25

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 133  
Number of plan statistics captured: 1

Rows (1st) Rows (avg) Rows (max)  Row Source Operation
---------- ---------- ----------  ---------------------------------------------------
        25         25         25  SORT ORDER BY (cr=22 pr=0 pw=0 time=1965 us starts=1 cost=22 size=7839 card=117)
        25         25         25   VIEW  (cr=22 pr=0 pw=0 time=2016 us starts=1 cost=21 size=7839 card=117)
        25         25         25    MATCH RECOGNIZE SORT (cr=22 pr=0 pw=0 time=2016 us starts=1 cost=21 size=9360 card=117)
       115        115        115     VIEW  (cr=22 pr=0 pw=0 time=1905 us starts=1 cost=20 size=9360 card=117)
       115        115        115      WINDOW SORT (cr=22 pr=0 pw=0 time=1904 us starts=1 cost=20 size=9360 card=117)
       115        115        115       HASH GROUP BY (cr=22 pr=0 pw=0 time=1718 us starts=1 cost=20 size=9360 card=117)
       116        116        116        VIEW  (cr=22 pr=0 pw=0 time=385 us starts=1 cost=18 size=9360 card=117)
       116        116        116         SORT UNIQUE (cr=22 pr=0 pw=0 time=384 us starts=1 cost=18 size=7879 card=117)
       117        117        117          UNION-ALL  (cr=22 pr=0 pw=0 time=213 us starts=1)
        10         10         10           HASH JOIN  (cr=14 pr=0 pw=0 time=210 us starts=1 cost=9 size=710 card=10)
        10         10         10            NESTED LOOPS  (cr=8 pr=0 pw=0 time=126 us starts=1 cost=9 size=710 card=10)
        10         10         10             NESTED LOOPS  (cr=8 pr=0 pw=0 time=116 us starts=1)
        10         10         10              STATISTICS COLLECTOR  (cr=8 pr=0 pw=0 time=115 us starts=1)
        10         10         10               MERGE JOIN  (cr=8 pr=0 pw=0 time=121 us starts=1 cost=6 size=480 card=10)
        10         10         10                TABLE ACCESS BY INDEX ROWID JOB_HISTORY (cr=2 pr=0 pw=0 time=34 us starts=1 cost=2 size=210 card=10)
        10         10         10                 INDEX FULL SCAN JHIST_JOB_IX (cr=1 pr=0 pw=0 time=24 us starts=1 cost=1 size=0 card=10)(object id 78632)
        10         10         10                SORT JOIN (cr=6 pr=0 pw=0 time=72 us starts=10 cost=4 size=513 card=19)
        19         19         19                 TABLE ACCESS FULL JOBS (cr=6 pr=0 pw=0 time=42 us starts=1 cost=3 size=513 card=19)
         0          0          0              INDEX UNIQUE SCAN EMP_EMP_ID_PK (cr=0 pr=0 pw=0 time=0 us starts=0)(object id 78622)
         0          0          0             TABLE ACCESS BY INDEX ROWID EMPLOYEES (cr=0 pr=0 pw=0 time=0 us starts=0 cost=3 size=23 card=1)
       107        107        107            TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=11 us starts=1 cost=3 size=2461 card=107)
       107        107        107           MERGE JOIN  (cr=8 pr=0 pw=0 time=366 us starts=1 cost=6 size=7169 card=107)
        19         19         19            TABLE ACCESS BY INDEX ROWID JOBS (cr=2 pr=0 pw=0 time=27 us starts=1 cost=2 size=513 card=19)
        19         19         19             INDEX FULL SCAN JOB_ID_PK (cr=1 pr=0 pw=0 time=5 us starts=1 cost=1 size=0 card=19)(object id 78619)
       107        107        107            SORT JOIN (cr=6 pr=0 pw=0 time=67 us starts=19 cost=4 size=4280 card=107)
       107        107        107             TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=7 us starts=1 cost=3 size=4280 card=107)


Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  SQL*Net message to client                       1        0.00          0.00
  PGA memory operation                            5        0.00          0.00
  SQL*Net message from client                     1        0.01          0.01" 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">call     count       cpu    elapsed       disk      query    current        rows</span></span>
<span class="line"><span style="color: #D4D4D4">------- ------  -------- ---------- ---------- ---------- ----------  ----------</span></span>
<span class="line"><span style="color: #D4D4D4">Parse        1      0.01       0.20          0          0          0           0</span></span>
<span class="line"><span style="color: #D4D4D4">Execute      1      0.00       0.00          0          0          0           0</span></span>
<span class="line"><span style="color: #D4D4D4">Fetch        1      0.00       0.00          0         22          0          25</span></span>
<span class="line"><span style="color: #D4D4D4">------- ------  -------- ---------- ---------- ---------- ----------  ----------</span></span>
<span class="line"><span style="color: #D4D4D4">total        3      0.01       0.20          0         22          0          25</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Misses in library cache during parse: 1</span></span>
<span class="line"><span style="color: #D4D4D4">Optimizer mode: ALL_ROWS</span></span>
<span class="line"><span style="color: #D4D4D4">Parsing user id: 133  </span></span>
<span class="line"><span style="color: #D4D4D4">Number of plan statistics captured: 1</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Rows (1st) Rows (avg) Rows (max)  Row Source Operation</span></span>
<span class="line"><span style="color: #D4D4D4">---------- ---------- ----------  ---------------------------------------------------</span></span>
<span class="line"><span style="color: #D4D4D4">        25         25         25  SORT ORDER BY (cr=22 pr=0 pw=0 time=1965 us starts=1 cost=22 size=7839 card=117)</span></span>
<span class="line"><span style="color: #D4D4D4">        25         25         25   VIEW  (cr=22 pr=0 pw=0 time=2016 us starts=1 cost=21 size=7839 card=117)</span></span>
<span class="line"><span style="color: #D4D4D4">        25         25         25    MATCH RECOGNIZE SORT (cr=22 pr=0 pw=0 time=2016 us starts=1 cost=21 size=9360 card=117)</span></span>
<span class="line"><span style="color: #D4D4D4">       115        115        115     VIEW  (cr=22 pr=0 pw=0 time=1905 us starts=1 cost=20 size=9360 card=117)</span></span>
<span class="line"><span style="color: #D4D4D4">       115        115        115      WINDOW SORT (cr=22 pr=0 pw=0 time=1904 us starts=1 cost=20 size=9360 card=117)</span></span>
<span class="line"><span style="color: #D4D4D4">       115        115        115       HASH GROUP BY (cr=22 pr=0 pw=0 time=1718 us starts=1 cost=20 size=9360 card=117)</span></span>
<span class="line"><span style="color: #D4D4D4">       116        116        116        VIEW  (cr=22 pr=0 pw=0 time=385 us starts=1 cost=18 size=9360 card=117)</span></span>
<span class="line"><span style="color: #D4D4D4">       116        116        116         SORT UNIQUE (cr=22 pr=0 pw=0 time=384 us starts=1 cost=18 size=7879 card=117)</span></span>
<span class="line"><span style="color: #D4D4D4">       117        117        117          UNION-ALL  (cr=22 pr=0 pw=0 time=213 us starts=1)</span></span>
<span class="line"><span style="color: #D4D4D4">        10         10         10           HASH JOIN  (cr=14 pr=0 pw=0 time=210 us starts=1 cost=9 size=710 card=10)</span></span>
<span class="line"><span style="color: #D4D4D4">        10         10         10            NESTED LOOPS  (cr=8 pr=0 pw=0 time=126 us starts=1 cost=9 size=710 card=10)</span></span>
<span class="line"><span style="color: #D4D4D4">        10         10         10             NESTED LOOPS  (cr=8 pr=0 pw=0 time=116 us starts=1)</span></span>
<span class="line"><span style="color: #D4D4D4">        10         10         10              STATISTICS COLLECTOR  (cr=8 pr=0 pw=0 time=115 us starts=1)</span></span>
<span class="line"><span style="color: #D4D4D4">        10         10         10               MERGE JOIN  (cr=8 pr=0 pw=0 time=121 us starts=1 cost=6 size=480 card=10)</span></span>
<span class="line"><span style="color: #D4D4D4">        10         10         10                TABLE ACCESS BY INDEX ROWID JOB_HISTORY (cr=2 pr=0 pw=0 time=34 us starts=1 cost=2 size=210 card=10)</span></span>
<span class="line"><span style="color: #D4D4D4">        10         10         10                 INDEX FULL SCAN JHIST_JOB_IX (cr=1 pr=0 pw=0 time=24 us starts=1 cost=1 size=0 card=10)(object id 78632)</span></span>
<span class="line"><span style="color: #D4D4D4">        10         10         10                SORT JOIN (cr=6 pr=0 pw=0 time=72 us starts=10 cost=4 size=513 card=19)</span></span>
<span class="line"><span style="color: #D4D4D4">        19         19         19                 TABLE ACCESS FULL JOBS (cr=6 pr=0 pw=0 time=42 us starts=1 cost=3 size=513 card=19)</span></span>
<span class="line"><span style="color: #D4D4D4">         0          0          0              INDEX UNIQUE SCAN EMP_EMP_ID_PK (cr=0 pr=0 pw=0 time=0 us starts=0)(object id 78622)</span></span>
<span class="line"><span style="color: #D4D4D4">         0          0          0             TABLE ACCESS BY INDEX ROWID EMPLOYEES (cr=0 pr=0 pw=0 time=0 us starts=0 cost=3 size=23 card=1)</span></span>
<span class="line"><span style="color: #D4D4D4">       107        107        107            TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=11 us starts=1 cost=3 size=2461 card=107)</span></span>
<span class="line"><span style="color: #D4D4D4">       107        107        107           MERGE JOIN  (cr=8 pr=0 pw=0 time=366 us starts=1 cost=6 size=7169 card=107)</span></span>
<span class="line"><span style="color: #D4D4D4">        19         19         19            TABLE ACCESS BY INDEX ROWID JOBS (cr=2 pr=0 pw=0 time=27 us starts=1 cost=2 size=513 card=19)</span></span>
<span class="line"><span style="color: #D4D4D4">        19         19         19             INDEX FULL SCAN JOB_ID_PK (cr=1 pr=0 pw=0 time=5 us starts=1 cost=1 size=0 card=19)(object id 78619)</span></span>
<span class="line"><span style="color: #D4D4D4">       107        107        107            SORT JOIN (cr=6 pr=0 pw=0 time=67 us starts=19 cost=4 size=4280 card=107)</span></span>
<span class="line"><span style="color: #D4D4D4">       107        107        107             TABLE ACCESS FULL EMPLOYEES (cr=6 pr=0 pw=0 time=7 us starts=1 cost=3 size=4280 card=107)</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">Elapsed times include waiting on following events:</span></span>
<span class="line"><span style="color: #D4D4D4">  Event waited on                             Times   Max. Wait  Total Waited</span></span>
<span class="line"><span style="color: #D4D4D4">  ----------------------------------------   Waited  ----------  ------------</span></span>
<span class="line"><span style="color: #D4D4D4">  SQL*Net message to client                       1        0.00          0.00</span></span>
<span class="line"><span style="color: #D4D4D4">  PGA memory operation                            5        0.00          0.00</span></span>
<span class="line"><span style="color: #D4D4D4">  SQL*Net message from client                     1        0.01          0.01</span></span></code></pre></div>



<h2 class="wp-block-heading"><a name="conclusion"></a>12. Conclusion</h2>



<p class="wp-block-paragraph">A view-API has a value. You can change the physical data model and keep the existing view layer compatible for the consuming applications. This makes the database application independent, at least to a certain extent. That&#8217;s a great value when you think of testing interfaces or releasing new versions. Building an initial 1:1 view-API is no big deal, especially since it can be generated. The maintenance costs for such a view-API depend on many things. But I can&#8217;t imagine a scenario that isn&#8217;t worth it.</p>



<p class="wp-block-paragraph">I was positively surprised by the feature richness and good usability of JOOQ. Things like the deep data model awareness including referential integrity constraints to make joins simpler and less error-prone are impressive. Ok, the DSL needs some getting used to, but the excellent documentation helps a lot. Although I have only scratched the surface of JOOQ, I am convinced that it is very well suited for developing high-performing PinkDB applications. Because JOOQ developers have control over the SQL statements sent to the database.</p>
<p>The post <a href="https://www.salvis.com/blog/2018/08/05/view-api-jooq-application/">View-API for JOOQ Application</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/2018/08/05/view-api-jooq-application/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Bitemp Remodeler v0.1.0 Released</title>
		<link>https://www.salvis.com/blog/2016/09/25/bitemp-remodeler-v0-1-0-released/</link>
		
		<dc:creator><![CDATA[Philipp Salvisberg]]></dc:creator>
		<pubDate>Sun, 25 Sep 2016 21:21:21 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[Flashback]]></category>
		<category><![CDATA[Flashback Data Archive]]></category>
		<category><![CDATA[oddgen]]></category>
		<category><![CDATA[PL/SQL]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[SQL Developer]]></category>
		<category><![CDATA[Temporal Database]]></category>
		<category><![CDATA[Transaction Time]]></category>
		<category><![CDATA[Valid Time]]></category>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=7254</guid>

					<description><![CDATA[<p>I&#8217;ve been working on a flexible table API generator for Oracle Databases for several months. A TAPI generator doesn&#8217;t sound like a real innovation. But this one contains some features you probably have not seen before in the TAPI generator and hopefully will like it as much as I do. In this post, I will<span class="excerpt-hellip"> […]</span></p>
<p>The post <a href="https://www.salvis.com/blog/2016/09/25/bitemp-remodeler-v0-1-0-released/">Bitemp Remodeler v0.1.0 Released</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I&#8217;ve been working on a flexible table API generator for Oracle Databases for several months. A TAPI generator doesn&#8217;t sound like a real innovation. But this one contains some features you probably have not seen before in the TAPI generator and hopefully will like it as much as I do.</p>



<p class="wp-block-paragraph">In this post, I will not explain the feature set thoroughly. Instead, I will more or less focus on one of my favourite features.</p>



<h2 class="wp-block-heading">Four models</h2>



<p class="wp-block-paragraph">The generator knows the following four data models.</p>



<figure class="wp-block-image"><a href="https://www.salvis.com/blog/wp-content/uploads/2016/09/four_models.png"><img decoding="async" width="1424" height="643" src="https://www.salvis.com/blog/wp-content/uploads/2016/09/four_models.png" alt="four_models" class="wp-image-7258" srcset="https://www.salvis.com/blog/wp-content/uploads/2016/09/four_models.png 1424w, https://www.salvis.com/blog/wp-content/uploads/2016/09/four_models-300x135.png 300w, https://www.salvis.com/blog/wp-content/uploads/2016/09/four_models-768x347.png 768w, https://www.salvis.com/blog/wp-content/uploads/2016/09/four_models-1024x462.png 1024w" sizes="(max-width:767px) 480px, (max-width:1424px) 100vw, 1424px" /></a></figure>



<p class="wp-block-paragraph">If your table is based on one of these four models you may</p>



<ol class="wp-block-list">
<li>simply generate a table API for it&nbsp;or</li>



<li>switch to another model and optionally generate a table API as well.</li>
</ol>



<p class="wp-block-paragraph">Option 2) is extraordinary, since it will preserve the existing data. E.g. it will preserve the content of the flashback data archive when you switch your model from uni-temporal transaction time to a bi-temporal model even if the flashback archive tables need to be moved to another table. Furthermore, it will keep the interface for the latest table the same. No application change is required. Everything with just a few mouse clicks. If this sounds interesting to you, then have a look at https://github.com/oddgen/bitemp/blob/main/README.md where the concept is briefly explained or join me in my session &#8220;oddgen &#8211; Bi-temporal Table API in Action&#8221; at the <a href="http://www.trivadis.com/en/training/more-just-performance-days-2016-tvdpdays">More than just – Performance Days 2016</a>. Remote participation is still possible.</p>



<p class="wp-block-paragraph">Option 1) is what we had for years. It was part of Oracle Designer, it&#8217;s part of SQL Developer in a simplified way and there are some more or less simple table API generators around. So no big deal. However, when you choose option 1), there is one cool part. The hook API package concept.</p>



<h2 class="wp-block-heading">The Hook API</h2>



<p class="wp-block-paragraph">The problem with a lot of table API solutions is, that there is typically no developer-friendly way to include the business logic. I&#8217;ve seen the following:</p>



<ul class="wp-block-list">
<li>Manual changes of the generated code, which is for various reasons not a good solution.</li>



<li>External hooks, e.g. in XML files, INI files, relational tables, etc. and merged at generation time into the final code. Oracle Designer worked that way.</li>



<li>Code which is dynamically executed by the generator at runtime, e.g. code snippets is stored in a pre-defined way in relational tables.</li>
</ul>



<p class="wp-block-paragraph">But what I&#8217;ve never seen, was business logic implemented in manually crafted PL/SQL packages, separated from the PL/SQL generated code. That&#8217;s strange because this is a common practice in Java-based projects.</p>



<p class="wp-block-paragraph">In Java, you typically define an interface for that and configure at runtime the right implementation. In PL/SQL we may do that similarly. A PL/SQL specification is an interface definition. That just one implementation may exist for an interface is not a limiting factor in this case.</p>



<p class="wp-block-paragraph">Bitemp Remodeler generates the following hook API package specification for the famous EMP&nbsp;table in schema SCOTT:</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">Package specification EMP_HOOK</span><span role="button" tabindex="0" data-code="CREATE OR REPLACE PACKAGE emp_hook AS
   /** 
   * Hooks called by non-temporal API for table emp_lt (see package body of emp_api)
   * generated by Bitemp Remodeler for SQL Developer.
   * The body of this package is not generated. It has to be crafted and maintained manually. 
   * Since the API for table emp_lt ignores errors caused by a missing hook package body, the implementation is optional.
   *
   * @headcom
   */

   /**
   * Hook called before insert into non-temporal table emp_lt.
   *
   * @param io_new_row new Row to be inserted
   */
   PROCEDURE pre_ins (
      io_new_row IN OUT emp_ot
   );

   /**
   * Hook called after insert into non-temporal table emp_lt.
   *
   * @param in_new_row new Row to be inserted
   */
   PROCEDURE post_ins (
      in_new_row IN emp_ot
   );

   /**
   * Hook called before update non-temporal table emp_lt.
   *
   * @param io_new_row Row with updated column values
   * @param in_old_row Row with original column values
   */
   PROCEDURE pre_upd (
      io_new_row IN OUT emp_ot,
      in_old_row IN emp_ot
   );

   /**
   * Hook called after update non-temporal table emp_lt.
   *
   * @param in_new_row Row with updated column values
   * @param in_old_row Row with original column values
   */
   PROCEDURE post_upd (
      in_new_row IN emp_ot,
      in_old_row IN emp_ot
   );

   /**
   * Hook called before delete from non-temporal table emp_lt.
   *
   * @param in_old_row Row with original column values
   */
   PROCEDURE pre_del (
      in_old_row IN emp_ot
   );

   /**
   * Hook called after delete from non-temporal table emp_lt.
   *
   * @param in_old_row Row with original column values
   */
   PROCEDURE post_del (
      in_old_row IN emp_ot
   );

END emp_hook;
/" 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"> </span><span style="color: #569CD6">PACKAGE</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">emp_hook</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #6A9955">/** </span></span>
<span class="line"><span style="color: #6A9955">   * Hooks called by non-temporal API for table emp_lt (see package body of emp_api)</span></span>
<span class="line"><span style="color: #6A9955">   * generated by Bitemp Remodeler for SQL Developer.</span></span>
<span class="line cbp-line-highlight"><span style="color: #6A9955">   * The body of this package is not generated. It has to be crafted and maintained manually. </span></span>
<span class="line cbp-line-highlight"><span style="color: #6A9955">   * Since the API for table emp_lt ignores errors caused by a missing hook package body, the implementation is optional.</span></span>
<span class="line"><span style="color: #6A9955">   *</span></span>
<span class="line"><span style="color: #6A9955">   * @headcom</span></span>
<span class="line"><span style="color: #6A9955">   */</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #6A9955">/**</span></span>
<span class="line"><span style="color: #6A9955">   * Hook called before insert into non-temporal table emp_lt.</span></span>
<span class="line"><span style="color: #6A9955">   *</span></span>
<span class="line"><span style="color: #6A9955">   * @param io_new_row new Row to be inserted</span></span>
<span class="line"><span style="color: #6A9955">   */</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">pre_ins</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      io_new_row </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OUT</span><span style="color: #D4D4D4"> emp_ot</span></span>
<span class="line"><span style="color: #D4D4D4">   );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #6A9955">/**</span></span>
<span class="line"><span style="color: #6A9955">   * Hook called after insert into non-temporal table emp_lt.</span></span>
<span class="line"><span style="color: #6A9955">   *</span></span>
<span class="line"><span style="color: #6A9955">   * @param in_new_row new Row to be inserted</span></span>
<span class="line"><span style="color: #6A9955">   */</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">post_ins</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      in_new_row </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> emp_ot</span></span>
<span class="line"><span style="color: #D4D4D4">   );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #6A9955">/**</span></span>
<span class="line"><span style="color: #6A9955">   * Hook called before update non-temporal table emp_lt.</span></span>
<span class="line"><span style="color: #6A9955">   *</span></span>
<span class="line"><span style="color: #6A9955">   * @param io_new_row Row with updated column values</span></span>
<span class="line"><span style="color: #6A9955">   * @param in_old_row Row with original column values</span></span>
<span class="line"><span style="color: #6A9955">   */</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">pre_upd</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      io_new_row </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">OUT</span><span style="color: #D4D4D4"> emp_ot,</span></span>
<span class="line"><span style="color: #D4D4D4">      in_old_row </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> emp_ot</span></span>
<span class="line"><span style="color: #D4D4D4">   );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #6A9955">/**</span></span>
<span class="line"><span style="color: #6A9955">   * Hook called after update non-temporal table emp_lt.</span></span>
<span class="line"><span style="color: #6A9955">   *</span></span>
<span class="line"><span style="color: #6A9955">   * @param in_new_row Row with updated column values</span></span>
<span class="line"><span style="color: #6A9955">   * @param in_old_row Row with original column values</span></span>
<span class="line"><span style="color: #6A9955">   */</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">post_upd</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      in_new_row </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> emp_ot,</span></span>
<span class="line"><span style="color: #D4D4D4">      in_old_row </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> emp_ot</span></span>
<span class="line"><span style="color: #D4D4D4">   );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #6A9955">/**</span></span>
<span class="line"><span style="color: #6A9955">   * Hook called before delete from non-temporal table emp_lt.</span></span>
<span class="line"><span style="color: #6A9955">   *</span></span>
<span class="line"><span style="color: #6A9955">   * @param in_old_row Row with original column values</span></span>
<span class="line"><span style="color: #6A9955">   */</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">pre_del</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      in_old_row </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> emp_ot</span></span>
<span class="line"><span style="color: #D4D4D4">   );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #6A9955">/**</span></span>
<span class="line"><span style="color: #6A9955">   * Hook called after delete from non-temporal table emp_lt.</span></span>
<span class="line"><span style="color: #6A9955">   *</span></span>
<span class="line"><span style="color: #6A9955">   * @param in_old_row Row with original column values</span></span>
<span class="line"><span style="color: #6A9955">   */</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">post_del</span><span style="color: #D4D4D4"> (</span></span>
<span class="line"><span style="color: #D4D4D4">      in_old_row </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> emp_ot</span></span>
<span class="line"><span style="color: #D4D4D4">   );</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> emp_hook;</span></span>
<span class="line"><span style="color: #D4D4D4">/</span></span></code></pre></div>



<p class="wp-block-paragraph">The generated table API calls before an INSERT the pre_ins procedure and after the INSERT the post_ins procedures. For DELETE and UPDATE this works the same way. On the highlighted line 5 and 6 two interested things are pointed out. The body is not generated and the body does not need to be implemented since the API ignores errors caused by a missing PL/SQL hook package body.</p>



<p class="wp-block-paragraph">Technically this is solved as follows in the API package body:</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-start:16;--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">Excerpt 1 of package body EMP_API</span><span role="button" tabindex="0" data-code="   e_hook_body_missing EXCEPTION;
   PRAGMA exception_init(e_hook_body_missing, -6508);" 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">   e_hook_body_missing </span><span style="color: #569CD6">EXCEPTION</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">PRAGMA exception_init</span><span style="color: #D4D4D4">(e_hook_body_missing, -</span><span style="color: #B5CEA8">6508</span><span style="color: #D4D4D4">);</span></span></code></pre></div>



<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-start:167;--cbp-line-number-width:calc(3 * 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">Excerpt 2 of package body EMP_API</span><span role="button" tabindex="0" data-code="      &lt;&lt;pre_ins&gt;&gt;
      BEGIN
         emp_hook.pre_ins(io_new_row =&gt; l_new_row);
      EXCEPTION
         WHEN e_hook_body_missing THEN
            NULL;
      END pre_ins;
      do_ins(io_row =&gt; l_new_row);" 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">      &lt;&lt;pre_ins&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">         emp_hook.pre_ins(io_new_row =&gt; </span><span style="color: #9CDCFE">l_new_row</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">EXCEPTION</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> e_hook_body_missing </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><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">END</span><span style="color: #D4D4D4"> pre_ins;</span></span>
<span class="line"><span style="color: #D4D4D4">      do_ins(io_row =&gt; </span><span style="color: #9CDCFE">l_new_row</span><span style="color: #D4D4D4">);</span></span></code></pre></div>



<p class="wp-block-paragraph">Now you may ask what the performance impact of these e_hook_body_missing exceptions are. I&#8217;ve done a small test and called a procedure without and with implemented body 1 million times. The overhead of the missing body exception is about 7 microseconds per call. Here&#8217;s the test output from SQL Developer, the relevant lines 51 and 89 are highlighted.</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">Overhead of missing package body</span><span role="button" tabindex="0" data-code="SQL&gt; SET FEEDBACK ON
SQL&gt; SET ECHO ON
SQL&gt; SET TIMING ON
SQL&gt; DROP PACKAGE dummy_api;

Package DUMMY_API dropped.

Elapsed: 00:00:00.027
SQL&gt; DROP PACKAGE dummy_hook;

Package DUMMY_HOOK dropped.

Elapsed: 00:00:00.030
SQL&gt; CREATE OR REPLACE PACKAGE dummy_hook AS
   PROCEDURE pre_ins;
END dummy_hook;
/

Package DUMMY_HOOK compiled

Elapsed: 00:00:00.023
SQL&gt; CREATE OR REPLACE PACKAGE dummy_api AS
   PROCEDURE ins;
END dummy_api;
/

Package DUMMY_API compiled

Elapsed: 00:00:00.034
SQL&gt; CREATE OR REPLACE PACKAGE BODY dummy_api AS
   e_hook_body_missing EXCEPTION;
   PRAGMA exception_init(e_hook_body_missing, -6508);  
   PROCEDURE ins IS
   BEGIN
      BEGIN
         dummy_hook.pre_ins;
      EXCEPTION
         WHEN e_hook_body_missing THEN
            NULL;
      END pre_ins;
      dbms_output.put('.');
   END ins;
END dummy_api;
/

Package body DUMMY_API compiled

Elapsed: 00:00:00.040
SQL&gt; -- without hook body
SQL&gt; BEGIN
   FOR i IN 1..1E6 LOOP
      dummy_api.ins;
   END LOOP;
END;
/

PL/SQL procedure successfully completed.

Elapsed: 00:00:07.878
SQL&gt; CREATE OR REPLACE PACKAGE BODY dummy_hook AS
   PROCEDURE pre_ins IS
   BEGIN
      dbms_output.put('-');
   END pre_ins;
END dummy_hook;
/

Package body DUMMY_HOOK compiled

Elapsed: 00:00:00.029
SQL&gt; -- with hook body
SQL&gt; BEGIN
   FOR i IN 1..1E6 LOOP
      dummy_api.ins;
   END LOOP;
END;
/

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.632" 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">SQL&gt; SET FEEDBACK ON</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; SET ECHO ON</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; SET TIMING ON</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; DROP PACKAGE dummy_api;</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Package DUMMY_API dropped.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Elapsed: 00:00:00.027</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; DROP PACKAGE dummy_hook;</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Package DUMMY_HOOK dropped.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Elapsed: 00:00:00.030</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; CREATE OR REPLACE PACKAGE dummy_hook AS</span></span>
<span class="line"><span style="color: #D4D4D4">   PROCEDURE pre_ins;</span></span>
<span class="line"><span style="color: #D4D4D4">END dummy_hook;</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">Package DUMMY_HOOK compiled</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Elapsed: 00:00:00.023</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; CREATE OR REPLACE PACKAGE dummy_api AS</span></span>
<span class="line"><span style="color: #D4D4D4">   PROCEDURE ins;</span></span>
<span class="line"><span style="color: #D4D4D4">END dummy_api;</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">Package DUMMY_API compiled</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Elapsed: 00:00:00.034</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; CREATE OR REPLACE PACKAGE BODY dummy_api AS</span></span>
<span class="line"><span style="color: #D4D4D4">   e_hook_body_missing EXCEPTION;</span></span>
<span class="line"><span style="color: #D4D4D4">   PRAGMA exception_init(e_hook_body_missing, -6508);  </span></span>
<span class="line"><span style="color: #D4D4D4">   PROCEDURE ins IS</span></span>
<span class="line"><span style="color: #D4D4D4">   BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">      BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">         dummy_hook.pre_ins;</span></span>
<span class="line"><span style="color: #D4D4D4">      EXCEPTION</span></span>
<span class="line"><span style="color: #D4D4D4">         WHEN e_hook_body_missing THEN</span></span>
<span class="line"><span style="color: #D4D4D4">            NULL;</span></span>
<span class="line"><span style="color: #D4D4D4">      END pre_ins;</span></span>
<span class="line"><span style="color: #D4D4D4">      dbms_output.put(&#39;.&#39;);</span></span>
<span class="line"><span style="color: #D4D4D4">   END ins;</span></span>
<span class="line"><span style="color: #D4D4D4">END dummy_api;</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">Package body DUMMY_API compiled</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Elapsed: 00:00:00.040</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; -- without hook body</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">   FOR i IN 1..1E6 LOOP</span></span>
<span class="line"><span style="color: #D4D4D4">      dummy_api.ins;</span></span>
<span class="line"><span style="color: #D4D4D4">   END LOOP;</span></span>
<span class="line"><span style="color: #D4D4D4">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">PL/SQL procedure successfully completed.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Elapsed: 00:00:07.878</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; CREATE OR REPLACE PACKAGE BODY dummy_hook AS</span></span>
<span class="line"><span style="color: #D4D4D4">   PROCEDURE pre_ins IS</span></span>
<span class="line"><span style="color: #D4D4D4">   BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">      dbms_output.put(&#39;-&#39;);</span></span>
<span class="line"><span style="color: #D4D4D4">   END pre_ins;</span></span>
<span class="line"><span style="color: #D4D4D4">END dummy_hook;</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">Package body DUMMY_HOOK compiled</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line"><span style="color: #D4D4D4">Elapsed: 00:00:00.029</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; -- with hook body</span></span>
<span class="line"><span style="color: #D4D4D4">SQL&gt; BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">   FOR i IN 1..1E6 LOOP</span></span>
<span class="line"><span style="color: #D4D4D4">      dummy_api.ins;</span></span>
<span class="line"><span style="color: #D4D4D4">   END LOOP;</span></span>
<span class="line"><span style="color: #D4D4D4">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">PL/SQL procedure successfully completed.</span></span>
<span class="line"><span style="color: #D4D4D4"></span></span>
<span class="line cbp-line-highlight"><span style="color: #D4D4D4">Elapsed: 00:00:00.632</span></span></code></pre></div>



<p class="wp-block-paragraph">It makes sense to provide a body with a NULL implementation to avoid the small overhead of handling the missing body exception.</p>



<p class="wp-block-paragraph">Nonetheless, the way the business logic is separated from the generated code is one of the many things I like about Bitemp Remodeler.</p>



<p class="wp-block-paragraph">Download Bitemp Remodeler from the&nbsp;<a href="https://www.salvis.com/blog/download/">Download</a> section on&nbsp;my blog or install it directly via the SQL Developer update site <a href="http://update.oddgen.org/">http://update.oddgen.org/</a></p>
<p>The post <a href="https://www.salvis.com/blog/2016/09/25/bitemp-remodeler-v0-1-0-released/">Bitemp Remodeler v0.1.0 Released</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PL/SQL Bulk Unwrap</title>
		<link>https://www.salvis.com/blog/2016/06/26/plsql-bulk-unwrap/</link>
					<comments>https://www.salvis.com/blog/2016/06/26/plsql-bulk-unwrap/#comments</comments>
		
		<dc:creator><![CDATA[Philipp Salvisberg]]></dc:creator>
		<pubDate>Sun, 26 Jun 2016 21:44:05 +0000</pubDate>
				<category><![CDATA[Oracle]]></category>
		<category><![CDATA[oddgen]]></category>
		<category><![CDATA[PL/SQL]]></category>
		<category><![CDATA[PL/SQL Unwrapper]]></category>
		<category><![CDATA[SQL Developer]]></category>
		<guid isPermaLink="false">https://www.salvis.com/blog/?p=7152</guid>

					<description><![CDATA[<p>406 days ago I released PL/SQL Unwrapper for SQL Developer version 0.1.1 and blogged about it. With this extension, you can unwrap the content of a SQL Developer window. Time for an update. With the new version 1.0 you can unwrap multiple selected objects with a few mouse clicks. In this blog<span class="excerpt-hellip"> […]</span></p>
<p>The post <a href="https://www.salvis.com/blog/2016/06/26/plsql-bulk-unwrap/">PL/SQL Bulk Unwrap</a> appeared first on <a href="https://www.salvis.com/blog">Philipp Salvisberg&#039;s Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">406 days ago I released PL/SQL Unwrapper for SQL Developer version 0.1.1 and blogged about it. With this extension, you can unwrap the content of a SQL Developer window. Time for an update. With the new version 1.0 you can unwrap multiple selected objects with a few mouse clicks. In this blog post, I show how.</p>



<h2 class="wp-block-heading">1. Install Extensions</h2>



<p class="wp-block-paragraph">I assume that you are already using&nbsp;SQL Developer 4.0.2 or higher. If not then it is about time that you grab the latest version from <a href="https://docs.oracle.com/en/database/oracle/sql-developer/index.html">here</a>&nbsp;and install it. It&#8217;s important to note that the extensions won&#8217;t run in older versions&nbsp;of SQL Developer.</p>



<p class="wp-block-paragraph">Configure the&nbsp;update center <a href="https://update.salvis.com/">https://update.salvis.com/</a> and <a href="https://update.oddgen.org/">https://update.oddgen.org/</a> to install the extensions for SQL Developer:</p>



<figure class="wp-block-image"><a href="https://www.salvis.com/blog/wp-content/uploads/2016/06/updates_oddgen_unwrapper.png"><img decoding="async" width="385" height="141" src="https://www.salvis.com/blog/wp-content/uploads/2016/06/updates_oddgen_unwrapper.png" alt="updates_oddgen_unwrapper" class="wp-image-7155" srcset="https://www.salvis.com/blog/wp-content/uploads/2016/06/updates_oddgen_unwrapper.png 385w, https://www.salvis.com/blog/wp-content/uploads/2016/06/updates_oddgen_unwrapper-300x110.png 300w" sizes="(max-width:767px) 385px, 385px" /></a></figure>



<p class="wp-block-paragraph">If you cannot use the update center because your company&#8217;s network restricts internet access then download <a href="https://github.com/oddgen/oddgen/releases">oddgen</a>,  <a href="https://github.com/Trivadis/plsql-unwrapper-sqldev/releases">unwrapper</a> and <a href="https://www.oddgen.org/download#installation_from_file">install them from file</a>.</p>



<p class="wp-block-paragraph">Why download oddgen for SQL Developer? Because the bulk unwrap feature is implemented as oddgen plugin. Unwrapping an editor content works without oddgen, but for&nbsp;bulk unwrap you need <a href="https://www.oddgen.org/">oddgen</a>.</p>



<h2 class="wp-block-heading">2.&nbsp;Setup Test Environment</h2>



<p class="wp-block-paragraph">If you have a schema in your Oracle database with wrapped code you may&nbsp;skip this step and use this schema for bulk unwrap.</p>



<p class="wp-block-paragraph">For the test environment, I&#8217;ve used Morten Braten&#8217;s&nbsp;<a href="http://ora-00001.blogspot.de/2015/02/alexandria-plsql-utility-library-moved-to-github.html">Alexandria PL/SQL Utility Library</a>. Clone or download the library from <a href="https://github.com/mortenbra/alexandria-plsql-utils">GitHub</a>. To install the library you need a dedicated user. Create such a user as SYS on your Oracle database instance 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);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">Create User AX for Alexandria Library</span><span role="button" tabindex="0" data-code="CREATE USER ax IDENTIFIED BY ax 
DEFAULT TABLESPACE users
TEMPORARY TABLESPACE temp;

ALTER USER ax QUOTA UNLIMITED ON users;

GRANT connect, resource TO ax;
GRANT execute ON dbms_crypto TO ax;" 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</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">USER</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">ax</span><span style="color: #D4D4D4"> IDENTIFIED </span><span style="color: #569CD6">BY</span><span style="color: #D4D4D4"> ax </span></span>
<span class="line"><span style="color: #569CD6">DEFAULT</span><span style="color: #D4D4D4"> TABLESPACE users</span></span>
<span class="line"><span style="color: #D4D4D4">TEMPORARY TABLESPACE temp;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">ALTER</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">USER</span><span style="color: #D4D4D4"> ax QUOTA </span><span style="color: #569CD6">UNLIMITED</span><span style="color: #D4D4D4"> </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"> </span><span style="color: #569CD6">connect</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">resource</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> ax;</span></span>
<span class="line"><span style="color: #569CD6">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">execute</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ON</span><span style="color: #D4D4D4"> dbms_crypto </span><span style="color: #569CD6">TO</span><span style="color: #D4D4D4"> ax;</span></span></code></pre></div>



<p class="wp-block-paragraph">Then run the install.sql script in the setup directory of the Alexandria PL/SQL Utility Library as user AX.</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">Install Alexandria PL/SQL Utility Library in Schema AX</span><span role="button" tabindex="0" data-code="@install.sql" 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">@install.</span><span style="color: #569CD6">sql</span></span></code></pre></div>



<p class="wp-block-paragraph">Wrap the PL/SQL code except package and type specifications in schema AX by running the script <a href="https://gist.github.com/PhilippSalvisberg/0e3b79e93f38af2fa530d4035e4d27ce#file-wrap_schema-sql">wrap_schema.sql</a>:</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-start:16;--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">Wrap PL/SQL Code</span><span role="button" tabindex="0" data-code="SET SERVEROUTPUT ON
DECLARE
   PROCEDURE wrap_and_install(in_code IN CLOB) IS
      co_chunksize INTEGER := 8196;
      l_array      dbms_sql.varchar2a;
      l_lb         INTEGER := 1;
      l_ub         INTEGER;
      l_cursor     PLS_INTEGER;
   BEGIN
      l_ub := ceil(sys.dbms_lob.getlength(in_code) / co_chunksize);
      &lt;&lt;clob_chunks&gt;&gt;
      FOR i IN l_lb .. l_ub
      LOOP
         l_array(i) := sys.dbms_lob.substr(lob_loc =&gt; in_code,
                                           offset  =&gt; (i - 1) * co_chunksize + 1,
                                           amount  =&gt; co_chunksize);
      END LOOP clob_chunks;
      l_cursor := sys.dbms_sql.open_cursor;
      sys.dbms_sql.parse(c             =&gt; l_cursor,
                         STATEMENT     =&gt; l_array,
                         lb            =&gt; l_lb,
                         ub            =&gt; l_ub,
                         lfflg         =&gt; FALSE,
                         language_flag =&gt; sys.dbms_sql.native);
      sys.dbms_ddl.create_wrapped(ddl =&gt; l_array, lb =&gt; l_lb, ub =&gt; l_ub);
      sys.dbms_sql.close_cursor(l_cursor);
   END wrap_and_install;
BEGIN
   &lt;&lt;unwrapped_sources&gt;&gt;
   FOR l_rec IN (SELECT TYPE AS original_type,
                        CASE TYPE
                           WHEN 'PACKAGE' THEN
                            'PACKAGE_SPEC'
                           WHEN 'PACKAGE BODY' THEN
                            'PACKAGE_BODY'
                           WHEN 'TYPE' THEN
                            'TYPE_SPEC'
                           WHEN 'TYPE BODY' THEN
                            'TYPE_BODY'
                           ELSE
                            TYPE
                        END AS object_type,
                        NAME AS object_name
                   FROM user_source
                  WHERE TYPE IN ('FUNCTION',
                                 'PROCEDURE',
                                 -- 'PACKAGE',
                                 'PACKAGE BODY',
                                 -- 'TYPE',
                                 'TYPE BODY',
                                 'LIBRARY')
                        AND line = 1
                        AND lower(text) NOT LIKE '% wrapped%'
                  ORDER BY type, name)
   LOOP
      &lt;&lt;try_to_wrap&gt;&gt;
      DECLARE
         l_ddl  CLOB;
         l_code CLOB;
      BEGIN
         l_ddl := sys.dbms_metadata.get_ddl(object_type =&gt; l_rec.object_type,
                                            NAME        =&gt; l_rec.object_name,
                                            SCHEMA      =&gt; USER);
         -- wrap with EDITIONABLE clause fails on 12.1.0.2.0 with: 
         --    ORA-24230: input to DBMS_DDL.WRAP is not a legal PL/SQL unit
         l_code := REPLACE(l_ddl, 'CREATE OR REPLACE EDITIONABLE ', 'CREATE OR REPLACE ');
         -- wrapping within database supported through DBMS_DDL since 10gR1
         wrap_and_install(in_code =&gt; l_code);
         sys.dbms_output.put_line(l_rec.original_type || ' ' || l_rec.object_name ||
                                  ' wrapped.');
      EXCEPTION
         WHEN OTHERS THEN
            sys.dbms_output.put_line(l_rec.original_type || ' ' || l_rec.object_name ||
                                     ' not wrapped because of ' || SQLERRM);
      END try_to_wrap;
   END LOOP unwrapped_sources;
END;
/" 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">SET</span><span style="color: #D4D4D4"> SERVEROUTPUT </span><span style="color: #569CD6">ON</span></span>
<span class="line"><span style="color: #569CD6">DECLARE</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">PROCEDURE</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">wrap_and_install</span><span style="color: #D4D4D4">(in_code </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">CLOB</span><span style="color: #D4D4D4">) </span><span style="color: #569CD6">IS</span></span>
<span class="line"><span style="color: #D4D4D4">      co_chunksize </span><span style="color: #569CD6">INTEGER</span><span style="color: #D4D4D4"> := </span><span style="color: #B5CEA8">8196</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">l_array</span><span style="color: #D4D4D4">      </span><span style="color: #DCDCAA">dbms_sql.</span><span style="color: #4EC9B0">varchar2a</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">l_lb</span><span style="color: #D4D4D4">         </span><span style="color: #569CD6">INTEGER</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">      </span><span style="color: #9CDCFE">l_ub</span><span style="color: #D4D4D4">         </span><span style="color: #569CD6">INTEGER</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">l_cursor</span><span style="color: #D4D4D4">     </span><span style="color: #569CD6">PLS_INTEGER</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">l_ub</span><span style="color: #D4D4D4"> := </span><span style="color: #DCDCAA">ceil</span><span style="color: #D4D4D4">(sys.</span><span style="color: #DCDCAA">dbms_lob.</span><span style="color: #4EC9B0">getlength</span><span style="color: #D4D4D4">(in_code) / co_chunksize);</span></span>
<span class="line"><span style="color: #D4D4D4">      &lt;&lt;clob_chunks&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #C586C0">FOR</span><span style="color: #D4D4D4"> i </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">l_lb</span><span style="color: #D4D4D4"> .. </span><span style="color: #9CDCFE">l_ub</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #C586C0">LOOP</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #9CDCFE">l_array</span><span style="color: #D4D4D4">(i) := sys.</span><span style="color: #DCDCAA">dbms_lob.</span><span style="color: #4EC9B0">substr</span><span style="color: #D4D4D4">(lob_loc =&gt; in_code,</span></span>
<span class="line"><span style="color: #D4D4D4">                                           offset  =&gt; (i - </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">) * co_chunksize + </span><span style="color: #B5CEA8">1</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                                           amount  =&gt; co_chunksize);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #C586C0">END LOOP</span><span style="color: #D4D4D4"> clob_chunks;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #9CDCFE">l_cursor</span><span style="color: #D4D4D4"> := sys.</span><span style="color: #DCDCAA">dbms_sql.</span><span style="color: #4EC9B0">open_cursor</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">      sys.</span><span style="color: #DCDCAA">dbms_sql.</span><span style="color: #4EC9B0">parse</span><span style="color: #D4D4D4">(</span><span style="color: #569CD6">c</span><span style="color: #D4D4D4">             =&gt; </span><span style="color: #9CDCFE">l_cursor</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                         STATEMENT     =&gt; </span><span style="color: #9CDCFE">l_array</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                         lb            =&gt; </span><span style="color: #9CDCFE">l_lb</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                         ub            =&gt; </span><span style="color: #9CDCFE">l_ub</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                         lfflg         =&gt; </span><span style="color: #569CD6">FALSE</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                         language_flag =&gt; sys.</span><span style="color: #DCDCAA">dbms_sql.</span><span style="color: #4EC9B0">native</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      sys.</span><span style="color: #DCDCAA">dbms_ddl.</span><span style="color: #4EC9B0">create_wrapped</span><span style="color: #D4D4D4">(ddl =&gt; </span><span style="color: #9CDCFE">l_array</span><span style="color: #D4D4D4">, lb =&gt; </span><span style="color: #9CDCFE">l_lb</span><span style="color: #D4D4D4">, ub =&gt; </span><span style="color: #9CDCFE">l_ub</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      sys.</span><span style="color: #DCDCAA">dbms_sql.</span><span style="color: #4EC9B0">close_cursor</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">l_cursor</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> wrap_and_install;</span></span>
<span class="line"><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">   &lt;&lt;unwrapped_sources&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #C586C0">FOR</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">l_rec</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> (</span><span style="color: #569CD6">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">TYPE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> original_type,</span></span>
<span class="line"><span style="color: #D4D4D4">                        </span><span style="color: #C586C0">CASE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">TYPE</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;PACKAGE&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">                            </span><span style="color: #CE9178">&#39;PACKAGE_SPEC&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;PACKAGE BODY&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">                            </span><span style="color: #CE9178">&#39;PACKAGE_BODY&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;TYPE&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">                            </span><span style="color: #CE9178">&#39;TYPE_SPEC&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;TYPE BODY&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">                            </span><span style="color: #CE9178">&#39;TYPE_BODY&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                           </span><span style="color: #C586C0">ELSE</span></span>
<span class="line"><span style="color: #D4D4D4">                            </span><span style="color: #569CD6">TYPE</span></span>
<span class="line"><span style="color: #D4D4D4">                        </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> object_type,</span></span>
<span class="line"><span style="color: #D4D4D4">                        </span><span style="color: #569CD6">NAME</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">AS</span><span style="color: #D4D4D4"> object_name</span></span>
<span class="line"><span style="color: #D4D4D4">                   </span><span style="color: #569CD6">FROM</span><span style="color: #D4D4D4"> user_source</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">TYPE</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">IN</span><span style="color: #D4D4D4"> (</span><span style="color: #CE9178">&#39;FUNCTION&#39;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                                 </span><span style="color: #CE9178">&#39;PROCEDURE&#39;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                                 </span><span style="color: #6A9955">-- &#39;PACKAGE&#39;,</span></span>
<span class="line"><span style="color: #D4D4D4">                                 </span><span style="color: #CE9178">&#39;PACKAGE BODY&#39;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                                 </span><span style="color: #6A9955">-- &#39;TYPE&#39;,</span></span>
<span class="line"><span style="color: #D4D4D4">                                 </span><span style="color: #CE9178">&#39;TYPE BODY&#39;</span><span style="color: #D4D4D4">,</span></span>
<span class="line"><span style="color: #D4D4D4">                                 </span><span style="color: #CE9178">&#39;LIBRARY&#39;</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">                        </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> line = </span><span style="color: #B5CEA8">1</span></span>
<span class="line"><span style="color: #D4D4D4">                        </span><span style="color: #569CD6">AND</span><span style="color: #D4D4D4"> </span><span style="color: #DCDCAA">lower</span><span style="color: #D4D4D4">(text) </span><span style="color: #569CD6">NOT</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">LIKE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;% wrapped%&#39;</span></span>
<span class="line"><span style="color: #D4D4D4">                  </span><span style="color: #569CD6">ORDER BY</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">type</span><span style="color: #D4D4D4">, </span><span style="color: #569CD6">name</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #C586C0">LOOP</span></span>
<span class="line"><span style="color: #D4D4D4">      &lt;&lt;try_to_wrap&gt;&gt;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">DECLARE</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #9CDCFE">l_ddl</span><span style="color: #D4D4D4">  </span><span style="color: #569CD6">CLOB</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #9CDCFE">l_code</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">CLOB</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">BEGIN</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #9CDCFE">l_ddl</span><span style="color: #D4D4D4"> := sys.</span><span style="color: #DCDCAA">dbms_metadata.</span><span style="color: #4EC9B0">get_ddl</span><span style="color: #D4D4D4">(object_type =&gt; </span><span style="color: #9CDCFE">l_rec</span><span style="color: #D4D4D4">.object_type,</span></span>
<span class="line"><span style="color: #D4D4D4">                                            </span><span style="color: #569CD6">NAME</span><span style="color: #D4D4D4">        =&gt; </span><span style="color: #9CDCFE">l_rec</span><span style="color: #D4D4D4">.object_name,</span></span>
<span class="line"><span style="color: #D4D4D4">                                            SCHEMA      =&gt; </span><span style="color: #DCDCAA">USER</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #6A9955">-- wrap with EDITIONABLE clause fails on 12.1.0.2.0 with: </span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #6A9955">--    ORA-24230: input to DBMS_DDL.WRAP is not a legal PL/SQL unit</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #9CDCFE">l_code</span><span style="color: #D4D4D4"> := </span><span style="color: #DCDCAA">REPLACE</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">l_ddl</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;CREATE OR REPLACE EDITIONABLE &#39;</span><span style="color: #D4D4D4">, </span><span style="color: #CE9178">&#39;CREATE OR REPLACE &#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #6A9955">-- wrapping within database supported through DBMS_DDL since 10gR1</span></span>
<span class="line"><span style="color: #D4D4D4">         wrap_and_install(in_code =&gt; </span><span style="color: #9CDCFE">l_code</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">         sys.</span><span style="color: #DCDCAA">dbms_output.</span><span style="color: #4EC9B0">put_line</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">l_rec</span><span style="color: #D4D4D4">.original_type || </span><span style="color: #CE9178">&#39; &#39;</span><span style="color: #D4D4D4"> || </span><span style="color: #9CDCFE">l_rec</span><span style="color: #D4D4D4">.object_name ||</span></span>
<span class="line"><span style="color: #D4D4D4">                                  </span><span style="color: #CE9178">&#39; wrapped.&#39;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">EXCEPTION</span></span>
<span class="line"><span style="color: #D4D4D4">         </span><span style="color: #569CD6">WHEN</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">OTHERS</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">THEN</span></span>
<span class="line"><span style="color: #D4D4D4">            sys.</span><span style="color: #DCDCAA">dbms_output.</span><span style="color: #4EC9B0">put_line</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">l_rec</span><span style="color: #D4D4D4">.original_type || </span><span style="color: #CE9178">&#39; &#39;</span><span style="color: #D4D4D4"> || </span><span style="color: #9CDCFE">l_rec</span><span style="color: #D4D4D4">.object_name ||</span></span>
<span class="line"><span style="color: #D4D4D4">                                     </span><span style="color: #CE9178">&#39; not wrapped because of &#39;</span><span style="color: #D4D4D4"> || </span><span style="color: #DCDCAA">SQLERRM</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">END</span><span style="color: #D4D4D4"> try_to_wrap;</span></span>
<span class="line"><span style="color: #D4D4D4">   </span><span style="color: #C586C0">END LOOP</span><span style="color: #D4D4D4"> unwrapped_sources;</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></code></pre></div>



<h2 class="wp-block-heading">3. Bulk Unwrap</h2>



<p class="wp-block-paragraph">Start SQL Developer and open a connection as user AX on your database.</p>



<p class="wp-block-paragraph">If the oddgen window is not visible then select &#8220;Generators&#8221; from the &#8220;View&#8221; menu as shown in the following picture:</p>



<figure class="wp-block-image"><a href="https://www.salvis.com/blog/wp-content/uploads/2016/05/menu_view_generators.png"><img loading="lazy" decoding="async" width="252" height="155" src="https://www.salvis.com/blog/wp-content/uploads/2016/05/menu_view_generators.png" alt="menu_view_generators" class="wp-image-7074"/></a></figure>



<p class="wp-block-paragraph">Afterwards, the Generators window appears in the lower left corner within SQL Developer.</p>



<figure class="wp-block-image"><a href="https://www.salvis.com/blog/wp-content/uploads/2016/06/generators.png"><img loading="lazy" decoding="async" width="293" height="132" src="https://www.salvis.com/blog/wp-content/uploads/2016/06/generators.png" alt="generators" class="wp-image-7170"/></a></figure>



<p class="wp-block-paragraph">Select the open connection in the combo box of the Generator window.&nbsp;Open the &#8220;PL/SQL Unwrapper&#8221; node and the &#8220;Package Bodies&#8221; node to show all wrapped package body names.</p>



<figure class="wp-block-image"><a href="https://www.salvis.com/blog/wp-content/uploads/2016/06/generators2.png"><img loading="lazy" decoding="async" width="294" height="461" src="https://www.salvis.com/blog/wp-content/uploads/2016/06/generators2.png" alt="generators2" class="wp-image-7171" srcset="https://www.salvis.com/blog/wp-content/uploads/2016/06/generators2.png 294w, https://www.salvis.com/blog/wp-content/uploads/2016/06/generators2-191x300.png 191w" sizes="auto, (max-width:767px) 294px, 294px" /></a></figure>



<p class="wp-block-paragraph">Select some or all package body nodes and press Return to generate the unwrapped code in a new worksheet. Afterwards, you just may execute the generated code. Add &#8220;SET DEFINE OFF&#8221; at the start of the script to ensure&nbsp;unwrapped code containing ampersand (&amp;) characters is processed correctly. Another option is to configure a connection startup script (login.sql) to change the default behaviour.</p>



<p class="wp-block-paragraph">The following audio-less video shows in just 56 seconds the whole bulk unwrapping process in detail.</p>



<figure class="wp-block-video"><video controls src="https://www.salvis.com/blog/wp-content/uploads/2015/12/Unwrapper.mp4"></video></figure>



<p class="wp-block-paragraph">I hope you find this new feature useful.</p>
<p>The post <a href="https://www.salvis.com/blog/2016/06/26/plsql-bulk-unwrap/">PL/SQL Bulk Unwrap</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/2016/06/26/plsql-bulk-unwrap/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		<enclosure url="https://www.salvis.com/blog/wp-content/uploads/2015/12/Unwrapper.mp4" length="11673419" type="video/mp4" />

			</item>
	</channel>
</rss>
