<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Redstone Apps]]></title><description><![CDATA[Redstone Content Solutions provides cutting edge solutions on Cloud platforms specializing in Oracle Cloud Infrastructure (OCI).]]></description><link>https://blog.redstoneapps.com</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 03:28:22 GMT</lastBuildDate><atom:link href="https://blog.redstoneapps.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Oracle APEX Collections: Rediscover]]></title><description><![CDATA[Oracle APEX Collections are a feature that has stood the test of time. They are a simple yet powerful tool in Oracle APEX. They allow developers to manage and manipulate data within a session. Collections are an example of a developer centric feature...]]></description><link>https://blog.redstoneapps.com/oracle-apex-collections-rediscover</link><guid isPermaLink="true">https://blog.redstoneapps.com/oracle-apex-collections-rediscover</guid><category><![CDATA[orclapex]]></category><dc:creator><![CDATA[Jason Stortz]]></dc:creator><pubDate>Tue, 20 Aug 2024 14:01:24 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724162459343/e89281df-a1cb-4703-9de5-a690fdf862bd.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Oracle APEX Collections are a feature that has stood the test of time. They are a simple yet powerful tool in Oracle APEX. They allow developers to manage and manipulate data within a session. Collections are an example of a developer centric feature of Oracle APEX (not really a Low Code feature). Despite the evolving landscape of Oracle APEX, Collections remain relevant. This post explores their history, evolution, and modern applications.</p>
<h2 id="heading-what-are-oracle-apex-collections">What are Oracle APEX Collections?</h2>
<p>Oracle APEX Collections are in-memory data structures that exist within a session. Think of them as temporary tables that live only as long as the session does. You can create, manipulate, and query these collections using PL/SQL. They provide a way to store and manage data temporarily without needing to create actual database tables.</p>
<p>Here's an example of fetching all the planets from SWAPI (Star Wars API):</p>
<pre><code class="lang-sql"><span class="hljs-keyword">DECLARE</span>
  l_url           <span class="hljs-built_in">VARCHAR2</span>(<span class="hljs-number">1000</span>) := <span class="hljs-string">'https://swapi.dev/api/planets/'</span>;
  l_response      CLOB;
  l_planets       JSON_OBJECT_T;
  l_planet_array  JSON_ARRAY_T;
  l_planet        JSON_OBJECT_T;
  l_next_page     VARCHAR2(4000);
<span class="hljs-keyword">BEGIN</span>

  <span class="hljs-comment">-- Create or truncate the PLANETS collection</span>
  APEX_COLLECTION.CREATE_OR_TRUNCATE_COLLECTION(<span class="hljs-string">'PLANETS'</span>);

  <span class="hljs-comment">-- Loop through all pages of results</span>
  LOOP
    <span class="hljs-comment">-- Make the API call</span>
    l_response := APEX_WEB_SERVICE.MAKE_REST_REQUEST(
      p_url         =&gt; l_url,
      p_http_method =&gt; 'GET'
    );

    <span class="hljs-comment">-- Parse the JSON response</span>
    l_planets := JSON_OBJECT_T.PARSE(l_response);
    l_planet_array := l_planets.GET_ARRAY('results');

    <span class="hljs-comment">-- Loop through the planets in the current page</span>
    FOR i IN 0 .. l_planet_array.GET_SIZE - 1 LOOP
      l_planet := TREAT(l_planet_array.GET(i) AS JSON_OBJECT_T);

      <span class="hljs-comment">-- Add planet to the collection</span>
      APEX_COLLECTION.ADD_MEMBER(
        p_collection_name =&gt; 'PLANETS',
        p_c001            =&gt; l_planet.GET_STRING('url'),  <span class="hljs-comment">-- Using URL as ID</span>
        p_c002            =&gt; l_planet.GET_STRING('name')
      );
    <span class="hljs-keyword">END</span> <span class="hljs-keyword">LOOP</span>;

    <span class="hljs-comment">-- Check if there's a next page</span>
    l_next_page := l_planets.GET_STRING('next');
    EXIT WHEN l_next_page IS NULL;

    l_url := l_next_page;
  <span class="hljs-keyword">END</span> <span class="hljs-keyword">LOOP</span>;
<span class="hljs-keyword">END</span>;
</code></pre>
<p>Once the collection is populated you can simply query it like a table:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">SELECT</span> c001 <span class="hljs-keyword">AS</span> planet_id, c002 <span class="hljs-keyword">AS</span> planet_name
    <span class="hljs-keyword">FROM</span> APEX_COLLECTIONS
    <span class="hljs-keyword">WHERE</span> COLLECTION_NAME = <span class="hljs-string">'PLANETS'</span>
    <span class="hljs-keyword">ORDER</span> <span class="hljs-keyword">BY</span> c002;
</code></pre>
<h2 id="heading-the-origins-of-apex-collections">The Origins of APEX Collections</h2>
<p>Oracle introduced APEX Collections to solve a specific problem: managing multi-row data in web applications without committing it to the database. They were first available in earlier versions of Oracle APEX (back when it was called HTML DB). The goal was to allow developers to collect and work with data across multiple pages or processes without relying on database tables for storage.</p>
<h2 id="heading-key-features-and-functionalities-of-apex-collections">Key Features and Functionalities of APEX Collections</h2>
<p>APEX Collections come with a set of built-in functionalities:</p>
<ol>
<li><p><strong>Creating Collections</strong>: You can <a target="_blank" href="https://docs.oracle.com/en/database/oracle/apex/24.1/aeapi/Creating-a-Collection.html#GUID-CF12682F-CBA4-422C-A7E5-E7A3A1B7D122">create a collection</a> using several different API methods (example: <a target="_blank" href="https://docs.oracle.com/en/database/oracle/apex/24.1/aeapi/CREATE_COLLECTION-Procedure.html#GUID-99D165B6-26C8-4142-9013-9948AFD67FF2">APEX_COLLECTION.CREATE_COLLECTION</a>). Once created, you can add, modify, or delete data in the collection. Also, see the method used in the example above of <a target="_blank" href="https://docs.oracle.com/en/database/oracle/apex/24.1/aeapi/CREATE_OR_TRUNCATE_COLLECTION-Procedure.html">APEX_COLLECTION.CREATE_OR_TRUNCATE_COLLECTION</a>.</p>
</li>
<li><p><strong>Manipulating Collections</strong>: APEX provides a variety of procedures to manipulate collections, such as ADD_MEMBER, UPDATE_MEMBER, and DELETE_MEMBER.</p>
</li>
<li><p><strong>Querying Collections</strong>: You can query collections just like you would with a regular SQL table using the APEX_COLLECTIONS view (including using them in JOINs!).</p>
</li>
</ol>
<p>These features made Collections an essential tool in early APEX applications, especially for handling multi-row data in forms, shopping carts, and complex reports.</p>
<h2 id="heading-modern-use-cases-for-apex-collections">Modern Use Cases for APEX Collections</h2>
<p>Even with the advancements in Oracle APEX, Collections remain useful in many scenarios. Here are a few modern applications:</p>
<ol>
<li><p><strong>Temporary Data Storage</strong>: Use Collections to hold temporary data that doesn’t need to be stored permanently in the database. This is useful for complex calculations or multi-step forms where data is accumulated over several pages. One example might be flags calculated on session data to drive features of the app or security requirements.</p>
</li>
<li><p><strong>Multi-Row Processing</strong>: Collections allow you to handle multiple rows of data in a session. This is ideal for scenarios like batch processing, where you need to collect and process data in chunks before committing it to the database.</p>
</li>
<li><p><strong>Data Staging</strong>: Before committing data to the database, you can stage it in a Collection. This allows for validation and modification before finalizing the transaction.</p>
</li>
</ol>
<h2 id="heading-migration-and-compatibility-considerations">Migration and Compatibility Considerations</h2>
<p>APEX Collections have remained consistent across different versions of Oracle APEX. This makes migrating legacy applications that use Collections relatively straightforward. However, it’s essential to review your Collections during migration to ensure they align with the best practices of the newer APEX versions.</p>
<p>If you’re maintaining or upgrading an application that uses APEX Collections, ensure that the Collections are used efficiently. Avoid keeping large amounts of data in a Collection for too long, as this can affect session performance.</p>
<h2 id="heading-case-studies-and-real-world-examples">Case Studies and Real-World Examples</h2>
<ol>
<li><p><strong>Multi-Page Form Handling:</strong> In one legacy APEX application, a multi-page form needed to collect data across three pages before submission. Instead of writing the data to the database after each page, a Collection was used. This allowed the user to review and edit the data before the final submission, alleviating potential locks and increasing performance.</p>
</li>
<li><p><strong>Shopping Cart Implementation:</strong> A typical e-commerce application used APEX Collections to manage the shopping cart. Items added to the cart were stored in a Collection, allowing users to modify quantities or remove items before checkout.</p>
</li>
</ol>
<h2 id="heading-common-pitfalls-and-challenges">Common Pitfalls and Challenges</h2>
<p>While APEX Collections are powerful, they have limitations:</p>
<ol>
<li><p><strong>Session Dependency</strong>: Collections exist only within a session. If the session ends, the Collection data is lost. This makes them unsuitable for long-term data storage.</p>
</li>
<li><p><strong>Performance</strong>: Large Collections can/will impact session performance. It’s crucial to manage the size and lifespan of Collections carefully.</p>
</li>
</ol>
<p>When using Collections, ensure that they are the right tool for the job. If your data needs to persist beyond a session, consider using temporary tables or other database structures.</p>
<h2 id="heading-future-outlook-the-role-of-apex-collections-in-emerging-apex-features">Future Outlook: The Role of APEX Collections in Emerging APEX Features</h2>
<p>As Oracle APEX continues to evolve, the role of Collections may change. However, their ability to manage data within a session will likely remain valuable. Developers should keep an eye on new APEX features that might integrate with or enhance Collections.</p>
<p>For example, you might store user responses in a collection to use as part of a RAG process for enhanced LLM interaction!</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Oracle APEX Collections have been a reliable tool for many years. They offer a flexible way to manage data within a session, making them useful in various scenarios. Whether you’re working with legacy applications or building new ones, APEX Collections are worth exploring.</p>
<h2 id="heading-references-and-further-reading">References and Further Reading</h2>
<ol>
<li><p><a target="_blank" href="https://docs.oracle.com/en/database/oracle/apex/24.1/aeapi/APEX_COLLECTION.html#GUID-859B488C-2628-44D7-969F-50872C685B76">Oracle APEX Collections Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://www.youtube.com/playlist?list=PLDA9e80Z1R0XoNwM_0rxJYCXchBq0r0WI">YouTube Video Library - APEX Collections</a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Exploring Session State in Oracle APEX with JavaScript]]></title><description><![CDATA[Hello APEX developers! Today, we're exploring how to work with session state using JavaScript in Oracle APEX. We'll cover the basics with easy-to-understand examples and show you both the shortcut and long-form ways to do things.
Reading Session Stat...]]></description><link>https://blog.redstoneapps.com/exploring-session-state-in-oracle-apex-with-javascript</link><guid isPermaLink="true">https://blog.redstoneapps.com/exploring-session-state-in-oracle-apex-with-javascript</guid><category><![CDATA[orclapex]]></category><dc:creator><![CDATA[Jason Stortz]]></dc:creator><pubDate>Mon, 05 Aug 2024 13:23:18 GMT</pubDate><content:encoded><![CDATA[<p>Hello APEX developers! Today, we're exploring how to work with session state using JavaScript in Oracle APEX. We'll cover the basics with easy-to-understand examples and show you both the shortcut and long-form ways to do things.</p>
<h2 id="heading-reading-session-state">Reading Session State</h2>
<p>To get a value from session state, we use the <code>$v()</code> function or its longer form:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Shortcut</span>
<span class="hljs-keyword">let</span> username = $v(<span class="hljs-string">'P1_USERNAME'</span>);

<span class="hljs-comment">// Long form</span>
<span class="hljs-keyword">let</span> email = apex.item(<span class="hljs-string">'P1_EMAIL'</span>).getValue();

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Username: "</span> + username);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Email: "</span> + email);
</code></pre>
<h2 id="heading-writing-to-session-state">Writing to Session State</h2>
<p>To set a value in session state, we use <code>$s()</code> or the setValue() method:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Shortcut</span>
$s(<span class="hljs-string">'P1_FAVORITE_COLOR'</span>, <span class="hljs-string">'Blue'</span>);

<span class="hljs-comment">// Long form</span>
apex.item(<span class="hljs-string">'P1_FAVORITE_ANIMAL'</span>).setValue(<span class="hljs-string">'Dolphin'</span>);
</code></pre>
<h2 id="heading-checking-if-an-item-exists">Checking if an Item Exists</h2>
<p>Before working with an item, it's smart to check if it exists. We use <code>$x()</code> for this:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Shortcut</span>
<span class="hljs-keyword">if</span> ($x(<span class="hljs-string">'P1_PHONE'</span>)) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Phone field exists"</span>);
}

<span class="hljs-comment">// Long form</span>
<span class="hljs-keyword">if</span> (apex.item(<span class="hljs-string">'P1_ADDRESS'</span>).node) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Address field exists"</span>);
}
</code></pre>
<h2 id="heading-working-with-select-lists-and-radio-groups">Working with Select Lists and Radio Groups</h2>
<p>For items based on a List of Values (LOV), APEX provides special functions:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Get the display value</span>
<span class="hljs-keyword">let</span> deptName = apex.item(<span class="hljs-string">'P1_DEPARTMENT'</span>).displayValueFor(<span class="hljs-number">10</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Department 10 is: "</span> + deptName);

<span class="hljs-comment">// Set both return and display value (useful for Popup LOVs)</span>
apex.item(<span class="hljs-string">'P1_EMPLOYEE'</span>).setValue(<span class="hljs-number">7839</span>, <span class="hljs-string">'KING'</span>);
</code></pre>
<h2 id="heading-detecting-changes">Detecting Changes</h2>
<p>To check if an item's value has changed:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (apex.item(<span class="hljs-string">'P1_SALARY'</span>).isChanged()) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Salary has been modified!"</span>);
}
</code></pre>
<h2 id="heading-silent-updates">Silent Updates</h2>
<p>Sometimes, we want to update a value without triggering events. The <a target="_blank" href="https://docs.oracle.com/en/database/oracle/apex/24.1/aexjs/item.html#setValue">setValue</a> method accepts three arguments:</p>
<ol>
<li><p>pValue - The value to set</p>
</li>
<li><p>pDisplayValue - The display value</p>
</li>
<li><p>pSuppressChangeEvent - defaults to false, true suppresses the change event</p>
</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-comment">// Set value without firing change event</span>
apex.item(<span class="hljs-string">'P1_DEPARTMENT'</span>).setValue(<span class="hljs-number">20</span>, <span class="hljs-literal">null</span>, <span class="hljs-literal">true</span>);
</code></pre>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>These JavaScript techniques allow you to create more interactive APEX applications. Remember:</p>
<ol>
<li><p><code>$v()</code> or <code>getValue()</code> to read</p>
</li>
<li><p><code>$s()</code> or <code>setValue()</code> to write</p>
</li>
<li><p><code>$x()</code> to check for item existence</p>
</li>
</ol>
<p>Remember...these values aren't set into session state until you submit the page in some fashion!</p>
<p>#orclAPEX</p>
]]></content:encoded></item><item><title><![CDATA[Run APEX Code from SQL Developer Web]]></title><description><![CDATA[Do you want to run Oracle APEX code from SQL Developer Web? Some commands will work just fine, but others will fail. Sometimes silently.
Consider APEX_APP_SETTING.GET_VALUE.
If you run this command in SQL Developer Web it won't fail, but it won't wor...]]></description><link>https://blog.redstoneapps.com/run-apex-code-from-sql-developer-web</link><guid isPermaLink="true">https://blog.redstoneapps.com/run-apex-code-from-sql-developer-web</guid><category><![CDATA[orclapex]]></category><dc:creator><![CDATA[Jason Stortz]]></dc:creator><pubDate>Tue, 30 Jul 2024 12:14:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722217888100/3759cf57-4e3d-4fc9-b7b8-904fd3bd79da.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Do you want to run Oracle APEX code from SQL Developer Web? Some commands will work just fine, but others will fail. Sometimes silently.</p>
<p>Consider <a target="_blank" href="https://docs.oracle.com/en/database/oracle/apex/24.1/aeapi/APEX_APP_SETTING.GET_VALUE-Function.html">APEX_APP_SETTING.GET_VALUE</a>.</p>
<p>If you run this command in SQL Developer Web it won't fail, but it won't work as you might either:</p>
<pre><code class="lang-sql"><span class="hljs-keyword">DECLARE</span>
    l_value <span class="hljs-built_in">VARCHAR2</span> (<span class="hljs-number">4000</span>);
<span class="hljs-keyword">BEGIN</span>
    l_value := APEX_APP_SETTING.GET_VALUE (p_name =&gt; <span class="hljs-string">'ROLE_READER'</span>);
    DBMS_OUTPUT.put_line (l_value);
<span class="hljs-keyword">END</span>;
</code></pre>
<p>Running that command will produce no real output.</p>
<p>Why doesn't it just work?</p>
<p>You need to set a little additional context for this to work! A session must be created (and cleaned up) to provide the context to the rest of the code.</p>
<p><a target="_blank" href="https://docs.oracle.com/en/database/oracle/apex/24.1/aeapi/CREATE_SESSION-Procedure.html">APEX_SESSION.CREATE_SESSION</a></p>
<p><a target="_blank" href="https://docs.oracle.com/en/database/oracle/apex/24.1/aeapi/DELETE_SESSION-Procedure.html">APEX_SESSION.DELETE_SESSION</a></p>
<pre><code class="lang-sql"><span class="hljs-keyword">DECLARE</span>
    l_value   <span class="hljs-built_in">VARCHAR2</span> (<span class="hljs-number">4000</span>);
<span class="hljs-keyword">BEGIN</span>
    <span class="hljs-comment">-- Provide the context of an APEX Session</span>
    APEX_SESSION.CREATE_SESSION(
        p_app_id =&gt; <span class="hljs-number">100</span>,  <span class="hljs-comment">-- Use the Application ID fo your app</span>
        p_page_id =&gt; <span class="hljs-number">2</span>,   <span class="hljs-comment">-- Use a page id from your app</span>
        p_username =&gt; <span class="hljs-string">'jstortz'</span> <span class="hljs-comment">-- Use your username</span>
    );
    l_value := APEX_APP_SETTING.GET_VALUE (p_name =&gt; 'ROLEREADER');
    DBMS_OUTPUT.put_line (l_value);
    <span class="hljs-comment">-- Now that we're done, cleanup the session</span>
    APEX_SESSION.DELETE_SESSION;
<span class="hljs-keyword">END</span>;
</code></pre>
]]></content:encoded></item><item><title><![CDATA[A Comparison of Oracle APEX and Microsoft Power Apps]]></title><description><![CDATA[In today's fast-paced business environment, the demand for rapid application development has surged. Low-code and no-code platforms have emerged as pivotal tools, enabling organizations to create applications swiftly without extensive coding. Among t...]]></description><link>https://blog.redstoneapps.com/a-comparison-of-oracle-apex-and-microsoft-power-apps</link><guid isPermaLink="true">https://blog.redstoneapps.com/a-comparison-of-oracle-apex-and-microsoft-power-apps</guid><category><![CDATA[orclapex]]></category><dc:creator><![CDATA[Jason Stortz]]></dc:creator><pubDate>Mon, 29 Jul 2024 01:02:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1722214916318/86e1ff6b-66ea-44ec-aa3a-bea86ded6451.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In today's fast-paced business environment, the demand for rapid application development has surged. Low-code and no-code platforms have emerged as pivotal tools, enabling organizations to create applications swiftly without extensive coding. Among these platforms, Oracle APEX and Microsoft Power Apps stand out, each offering unique features and benefits tailored to different user bases and business needs. </p>
<p>This article provides a comparison of Oracle APEX and Microsoft Power Apps, covering a few key features, capabilities, pricing, strengths, and weaknesses.</p>
<h2 id="heading-overview-of-oracle-apex">Overview of Oracle APEX</h2>
<p><strong>Oracle APEX (Application Express)</strong> is a low-code / no-code platform from Oracle, designed for building web applications and enterprise solutions. Initially released in 2004, APEX has evolved into a robust tool that leverages the power of the Oracle Database to deliver scalable, secure, and feature-rich applications including reporting, process and workflow automation, integrations and analytics.</p>
<h3 id="heading-key-features">Key Features</h3>
<p>1. <strong>Performance</strong>: Known for its high performance, APEX can handle large-scale data and complex applications, making it ideal for organizations with extensive data management needs.</p>
<p>2. <strong>Customization</strong>: APEX offers extensive customization capabilities, allowing developers to tailor applications to specific requirements with a high degree of control over appearance and functionality.</p>
<p>3. <strong>Integration</strong>: Seamlessly integrates with Oracle Databases, enabling organizations to leverage their existing infrastructure and investments. ORDS provides fantastic capabilities for integrations with other platforms as well.</p>
<p>4. <strong>Security</strong>: Incorporates robust security measures, ensuring compliance with industry standards and protecting sensitive information. Integrations with many Identity systems are supported out of the box.</p>
<p>5. <strong>Scalability</strong>: Can scale to meet the demands of large enterprises, managing complex workflows and high user loads effectively.</p>
<h3 id="heading-limitations">Limitations</h3>
<p>1. <strong>Connectivity with Non-Oracle Databases</strong>: While integration with Oracle databases is seamless, connecting to non-Oracle databases may require additional configuration.</p>
<p>2. <strong>Learning Curve</strong>: Despite being user-friendly, there is a learning curve, particularly for advanced features that require a solid understanding of SQL and PL/SQL.</p>
<p>3. <strong>Customization Constraints</strong>: <em>Extensive</em> customization may introduce long-term ownership challenges, particularly beyond the provided components and templates.</p>
<h2 id="heading-overview-of-microsoft-power-apps">Overview of Microsoft Power Apps</h2>
<p><strong>Microsoft Power Apps</strong> is a low-code/no-code platform launched in 2016, aimed at democratizing app development by making it accessible to users of all skill levels. Part of the Microsoft Power Platform, it includes services like Power Automate, Power BI, and Power Virtual Agents, facilitating data integration, automation, and analytics.</p>
<h3 id="heading-key-features-1">Key Features</h3>
<p>1. <strong>Accessibility</strong>: Designed for users without deep technical backgrounds, enabling them to create applications quickly.</p>
<p>2. <strong>Ease of Use</strong>: Features an intuitive drag-and-drop interface, making it accessible to a broad audience.</p>
<p>3. <strong>Integration with Microsoft Ecosystem</strong>: Integrates well with other Microsoft tools, such as SharePoint, Teams, and Dynamics 365, benefiting organizations invested in the Microsoft ecosystem.</p>
<p>4. <strong>Rapid Prototyping</strong>: Ideal for quickly prototyping and testing ideas, prioritizing speed over depth of capability.</p>
<h3 id="heading-limitations-1">Limitations</h3>
<p>1. <strong>Data Retrieval</strong>: Suited for small datasets; performance degrades with larger data volumes.</p>
<p>2. <strong>Concurrent Development</strong>: Does not support simultaneous development by multiple developers.</p>
<p>3. <strong>JavaScript Integration</strong>: Lacks support for JavaScript, limiting flexibility for professional developers.</p>
<p>4. <strong>External Sharing</strong>: Applications cannot be shared with users outside the organization, restricting external collaboration.</p>
<h2 id="heading-data-integration-and-management">Data Integration and Management</h2>
<p><strong>Oracle APEX</strong> excels in integrating with Oracle Databases, offering direct access to SQL and PL/SQL for data manipulation. This tight integration allows developers to leverage existing database skills without learning new programming languages. Additionally, APEX supports calling and executing stored procedures directly from the application, making it efficient for database-centric applications. The Citizen Developer (business user) can often utilize expressions as well as new APEX Assistant capabilities to develop applications without SQL knowledge.</p>
<p>In contrast, <strong>Microsoft Power Apps</strong> uses a set of functions and expressions to query databases, translating these queries to SQL. However, it lacks the direct access to SQL's full power, often requiring workarounds like creating views. Stored procedures cannot be called directly within Power Apps and must be executed through Power Automate, adding complexity and potential additional costs.</p>
<h2 id="heading-customization-and-extensibility">Customization and Extensibility</h2>
<p><strong>Oracle APEX</strong> provides extensive customization options through SQL, PL/SQL, JavaScript and Template Components. Developers can create plugins and include custom JavaScript and CSS to enhance application functionality and appearance as needed. This flexibility allows for highly tailored solutions that can meet specific deep business needs. It also allows for shared functionality between applications.</p>
<p><strong>Microsoft Power Apps</strong> focuses on simplicity and ease of use, limiting customization capabilities. It does not support JavaScript, which can restrict the ability to implement complex client-side behaviors. The platform is geared more towards non-professional developers, making it less flexible for those with advanced development skills.</p>
<h2 id="heading-scalability-and-performance">Scalability and Performance</h2>
<p><strong>Oracle APEX</strong> is known for its scalability, capable of handling large user bases and complex workflows. Its performance is optimized for Oracle Databases, ensuring efficient data processing and application responsiveness.</p>
<p><strong>Microsoft Power Apps</strong> performs well for small to medium-sized applications but may struggle with larger data volumes. Its scalability is limited compared to APEX, making it less suitable for enterprise-level applications requiring high performance and large-scale data management.</p>
<h2 id="heading-pricing">Pricing</h2>
<p><strong>Oracle APEX</strong> is cost-effective for organizations already using Oracle Database or Oracle Cloud services. It is included with Oracle Database licenses, and there are no additional costs for the platform itself. This can result in significant savings, particularly for enterprises heavily invested in Oracle products. For those without an Oracle Database the OCI Oracle APEX Service can provide a cost-efficient avenue to gain access to all Oracle APEX functionality. Oracle APEX offers unlimited users and applications.</p>
<p><strong>Microsoft Power Apps</strong> offers a free plan with limited capabilities. Beware, costs can escalate as more features and higher usage are required. Licensing fees are typically per user or per app, which can become expensive as the organization grows and usage increases.</p>
<h2 id="heading-oracle-apex-examples">Oracle APEX Examples</h2>
<p>1. <strong>Large Financial Institution</strong>: A major bank used Oracle APEX to develop an internal loan management system. The platform's seamless integration with the Oracle Database allowed the bank to leverage existing data and infrastructure, resulting in a scalable and secure solution that improved processing times and user satisfaction. In a later phase they used the Workflow feature to add task management and request routing to their application.</p>
<p>2. <strong>Government Agency</strong>: A government agency adopted Oracle APEX to create a public-facing portal for managing citizen services. The robust security features and scalability of APEX enabled the agency to handle high user volumes while ensuring data protection and compliance with regulatory standards. In this case the agency strived to utilize only out of the box functionality with point and click configuration and eschewed all customization.</p>
<h2 id="heading-microsoft-power-apps-examples">Microsoft Power Apps Examples</h2>
<p>1. <strong>Retail Chain</strong>: A retail company implemented Power Apps to streamline inventory management across multiple locations. The integration with Microsoft 365 and Dynamics 365 allowed employees to access and update inventory data in real-time, improving efficiency and reducing errors. This use case highlights the tight integration with other Microsoft products.</p>
<ol start="2">
<li><strong>Healthcare Provider</strong>: A local urgent care provider used Power Apps to develop a patient scheduling and tracking system. The platform's ease of use enabled non-technical staff to build and maintain the application, reducing dependency on outside IT vendors. A simple, yet impactful application that provided good business value.</li>
</ol>
<h2 id="heading-recommendations">Recommendations</h2>
<p>For organizations considering which platform to use, several factors should be evaluated:</p>
<p>1. <strong>Existing Infrastructure</strong>: Organizations already using Oracle databases, or which are invested in Oracle products may find Oracle APEX to be the most cost-effective and seamless option. Conversely, businesses deeply integrated with Microsoft tools and services might prefer Microsoft Power Apps for its ease of use and integration capabilities.</p>
<p>2. <strong>Development Skills</strong>: Both platforms can be used without development skillsets. Teams with stronger development skills will find they can push Oracle APEX to greater heights than Microsoft Power Apps.</p>
<p>3. <strong>Project Complexity and Scale</strong>: For large-scale, data-centric applications requiring high performance and scalability, Oracle APEX is likely the better choice. For smaller, less complex applications or rapid prototyping, Microsoft Power Apps may be more acceptable.</p>
<p>4. <strong>Cost Considerations</strong>: Organizations should carefully evaluate the licensing and operational costs of each platform, considering both current and future needs.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Both Oracle APEX and Microsoft Power Apps offer solutions for low-code development, each with unique strengths and limitations. Oracle APEX excels in performance, scalability, and deep integration with Oracle databases, making it ideal for enterprise-level applications. Microsoft Power Apps shines in accessibility, ease of use, and integration within the Microsoft ecosystem.</p>
]]></content:encoded></item><item><title><![CDATA[Ten Lessons Learned with Oracle Document Understanding Service (DUS)]]></title><description><![CDATA[Introduction
Kicking off your project with Oracle Document Understanding Service (DUS) can be a game-changer for handling huge amounts of document data, such as invoices. However, navigating this powerful tool requires a strategic approach and a keen...]]></description><link>https://blog.redstoneapps.com/ten-lessons-learned-with-oracle-document-understanding-service-dus</link><guid isPermaLink="true">https://blog.redstoneapps.com/ten-lessons-learned-with-oracle-document-understanding-service-dus</guid><category><![CDATA[Oracle]]></category><dc:creator><![CDATA[Jason Stortz]]></dc:creator><pubDate>Wed, 17 Jul 2024 18:13:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1721239974835/387d718f-6cff-4ba8-ac92-5de76fd60de9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Kicking off your project with Oracle Document Understanding Service (DUS) can be a game-changer for handling huge amounts of document data, such as invoices. However, navigating this powerful tool requires a strategic approach and a keen awareness of its nuances. Here are ten lessons learned from our extensive experience with DUS, which will help streamline your workflow and maximize efficiency.</p>
<h2 id="heading-1-managing-millions-of-invoices-across-multiple-sources">1. Managing Millions of Invoices Across Multiple Sources</h2>
<p>We faced the overwhelming task of processing millions of invoices from various sources, each with its unique format and structure. DUS proved invaluable, but the initial challenge was the sheer volume and diversity of the data. The key takeaway is to approach the problem systematically, categorizing and pre-processing data to ensure compatibility with DUS. This initial step is crucial for setting a solid foundation for subsequent processing.</p>
<h2 id="heading-2-efficient-data-loading-to-object-storage">2. Efficient Data Loading to Object Storage</h2>
<p>One surprising discovery was the ease with which we could load significant amounts of data into Oracle Object Storage. Contrary to initial concerns, we managed this without resorting to transfer disks, even within tight timelines. The trick lies in leveraging high-bandwidth internet connections and parallel upload strategies. This lesson underscores the importance of understanding and utilizing Oracle's robust data transfer capabilities. You can do a lot more with OCI CLI than you think!</p>
<h2 id="heading-3-the-necessity-of-batch-processing">3. The Necessity of Batch Processing</h2>
<p>Batch processing is not just a recommendation; it's a necessity. Attempting to process documents individually will significantly delay your project. By grouping documents into batches, you can optimize processing time and resource usage. This approach ensures a smoother, faster, and more efficient workflow, allowing you to handle large volumes of documents.</p>
<h2 id="heading-4-managing-job-submissions-and-status-checks">4. Managing Job Submissions and Status Checks</h2>
<p>Effective management of job submissions and status checks is critical. DUS provides APIs for these tasks, and scripting these interactions is an absolute necessity. Consider using tools like Oracle APEX for a more user-friendly interface. Automation here can save considerable time and reduce the risk of errors, ensuring that you can monitor and manage job statuses efficiently.</p>
<h2 id="heading-5-aggregating-resulting-json-files">5. Aggregating Resulting JSON Files</h2>
<p>After processing, DUS outputs JSON files, which need to be aggregated and transformed before being loaded into a final system. Scripting the API to handle this aggregation is essential. This step consolidates the data, making it easier to work with and analyze. Proper aggregation scripts can significantly streamline the data handling process, facilitating better data management and insights. Warning, DUS analysis is very detailed and produces a LOT of data!</p>
<h2 id="heading-6-reconciling-and-resubmitting-errors">6. Reconciling and Resubmitting Errors</h2>
<p>Errors are inevitable, and having a strategy to reconcile and resubmit them is vital. We encountered situations where DUS was overwhelmed, leading to processing errors. Establish a robust error-handling mechanism to identify, correct, and resubmit these errors. This proactive approach minimizes disruptions and ensures a more consistent data processing pipeline.</p>
<h2 id="heading-7-understanding-job-limits">7. Understanding Job Limits</h2>
<p> DUS imposes a limit of 2,000 documents per job. This constraint necessitates careful planning of how you batch your documents. Avoiding errors based on this limit will require splitting your data into smaller, manageable batches. Additionally, smaller batch sizes can mean reprocessing smaller numbers of documents in the case of errors.</p>
<h2 id="heading-8-handling-429-error-codes">8. Handling 429 Error Codes</h2>
<p>When submitting more than 200 to 220 jobs, you might begin to encounter 429 error codes, indicating too many requests. This throttling is a protective measure by Oracle to maintain system integrity. Implement a strategy to handle these errors, such as back-off and retry mechanisms, to maintain a smooth processing flow.</p>
<h2 id="heading-9-dealing-with-incomplete-data-extraction">9. Dealing with Incomplete Data Extraction</h2>
<p>DUS can occasionally fail to identify certain data points, resulting in empty values. It's crucial to create reports to identify these instances and establish a manual process for correction. This step ensures data completeness and accuracy, maintaining the integrity of your processed data. Again, consider APEX to assist in this post-processing phase.</p>
<h2 id="heading-10-monitoring-costs">10. Monitoring Costs</h2>
<p>While the cost of using DUS is minimal, it is not negligible especially at volume. Regular monitoring of your usage and associated costs is essential to avoid surprises. Implementing cost-monitoring scripts or tools can help keep track of expenses, ensuring that your project remains within budget.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Oracle Document Understanding Service (DUS) offers powerful capabilities for processing large volumes of document data. By learning from these ten lessons, you can optimize your workflow, avoid common pitfalls, and make the most of what DUS has to offer. Remember, strategic planning and proactive management are key to a successful implementation.</p>
<p>Feel free to reach out if you have any questions or need further assistance with your Oracle Cloud projects. Happy processing!</p>
]]></content:encoded></item><item><title><![CDATA[Embed YouTube in Oracle APEX Rich Text Editor (RTE)]]></title><description><![CDATA[By default, a YouTube video or other iframe based content cannot be embedded in the Oracle APEX Rich Text Editor (RTE). To accomplish this, add the following code to an RTE Page Item in the Initialization JavaScript Function property:
function(option...]]></description><link>https://blog.redstoneapps.com/embed-youtube-in-oracle-apex-rich-text-editor-rte</link><guid isPermaLink="true">https://blog.redstoneapps.com/embed-youtube-in-oracle-apex-rich-text-editor-rte</guid><category><![CDATA[orclapex]]></category><dc:creator><![CDATA[Jason Stortz]]></dc:creator><pubDate>Sun, 25 Feb 2024 18:00:00 GMT</pubDate><content:encoded><![CDATA[<p>By default, a YouTube video or other iframe based content cannot be embedded in the Oracle APEX Rich Text Editor (RTE). To accomplish this, add the following code to an RTE Page Item in the Initialization JavaScript Function property:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">options</span>)</span>{
  DOMPurify.setConfig({
      <span class="hljs-attr">ADD_TAGS</span>: [<span class="hljs-string">'iframe'</span>]
  });
  options.editorOptions.extended_valid_elements = <span class="hljs-string">"iframe[src|frameborder|style|scrolling|class|width|height|name|align]"</span>;
  <span class="hljs-keyword">return</span> options;
}
</code></pre>
<p>Many more options await as well.</p>
<p>Fullscreen editing:</p>
<pre><code class="lang-sql">function(options){
  options.editorOptions.plugins += " fullscreen";
  options.editorOptions.toolbar.find(i =&gt; i.name === "Extras").items.push("fullscreen");
  return options;
}
</code></pre>
<p>Word Count:</p>
<pre><code class="lang-sql">function(options){
  options.editorOptions.plugins += " wordcount";
  options.editorOptions.toolbar.find(i =&gt; i.name === "Extras").items.push("wordcount");
  return options;
}
</code></pre>
<p>There are so many fun options, check it out over at the <a target="_blank" href="https://www.tiny.cloud/docs/tinymce/latest/basic-setup/">TinyMCE Docs</a></p>
]]></content:encoded></item><item><title><![CDATA[OCI Container Registry Introduction]]></title><description><![CDATA[The OCI Container Registry (Registry) allows you to store private and public container repositories. In this article we cover the basics of connecting to and pushing an image to a private repository to store images.
Before you begin you must have an ...]]></description><link>https://blog.redstoneapps.com/oci-container-registry-introduction</link><guid isPermaLink="true">https://blog.redstoneapps.com/oci-container-registry-introduction</guid><category><![CDATA[OCI]]></category><dc:creator><![CDATA[Jason Stortz]]></dc:creator><pubDate>Fri, 16 Feb 2024 13:59:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1708091881052/4f5a5038-4d07-47d8-b78e-9060630fdaa9.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The OCI Container Registry (Registry) allows you to store private and public container repositories. In this article we cover the basics of connecting to and pushing an image to a private repository to store images.</p>
<p>Before you begin you must have an Oracle Cloud Account as well as <a target="_blank" href="https://www.docker.com/products/docker-desktop/">Docker Desktop</a> all setup and be able to execute this command in your terminal:</p>
<pre><code class="lang-bash">docker -h
</code></pre>
<p>We will assume you already have a docker image locally and you want to push it to OCI Container Registry.</p>
<p>List your local docker images with the <code>docker images</code> command:</p>
<pre><code class="lang-bash">&gt; docker images

myapp-server    latest        9fcb20691b9b   39 hours ago    137MB
</code></pre>
<p>Before you can push that image to OCI you need to do two things</p>
<ol>
<li><p>Sign into OCI.</p>
</li>
<li><p>Tag the local image with a specifically formatted name.</p>
</li>
</ol>
<h2 id="heading-sign-into-oci">Sign into OCI</h2>
<p>Here's an example of signing into OCI:</p>
<pre><code class="lang-bash">&gt; docker login ord.ocir.io

User: yourtenancy/oracleidentitycloudservice/jstortz
Password: &lt;your oci auth token here&gt;
</code></pre>
<p>As you can see, you'll need to get an OCI Auth token before you can complete the sign-in step. To do this:</p>
<ol>
<li><p>In the top-right corner of the Console, open the <strong>Profile</strong> menu and then click <strong>User settings</strong> to view the details.</p>
</li>
<li><p>On the <strong>Auth Tokens</strong> page, click <strong>Generate Token</strong>.</p>
</li>
<li><p>Enter a friendly description for the auth token. Avoid entering confidential information.</p>
</li>
<li><p>Click <strong>Generate Token</strong>. The new auth token is displayed.</p>
</li>
<li><p>Copy the auth token immediately to a secure location from where you can retrieve it later, because you won't see the auth token again in the Console.</p>
</li>
<li><p>Close the Generate Token dialog.</p>
</li>
</ol>
<p>Now you can attempt to sign-in with OCI.</p>
<h2 id="heading-tag-and-push">Tag and Push</h2>
<p>First, tag the image. You can see what "ID" you need to use by running <code>docker images</code>.</p>
<p>The basic syntax to tag your image looks like this:</p>
<p>docker tag &lt;image-id&gt; &lt;region-domain&gt;/&lt;tenancy&gt;/&lt;container-name&gt;:&lt;version&gt;</p>
<p>Example:</p>
<pre><code class="lang-markdown">docker tag d2973444a992 ord.ocir.io/redstone/myapp:v1
</code></pre>
<p>The "ord.ocir.io" part depends on what <a target="_blank" href="https://docs.oracle.com/en-us/iaas/Content/Registry/Concepts/registryprerequisites.htm#regional-availability">OCI Region</a> you want to use.</p>
<p>Use <code>docker images</code> to list your local images and confirm you now see this new tag</p>
<p>Then push with:</p>
<p>docker push &lt;region-domain&gt;/&lt;tenancy&gt;/&lt;container-name&gt;:version</p>
<p>Like this:</p>
<pre><code class="lang-markdown">docker push ord.ocir.io/redstone/myapp:v1
</code></pre>
<p>Voila! Your image is in OCI Registry and ready for you to deploy with various technologies like <a target="_blank" href="https://www.oracle.com/cloud/cloud-native/container-instances/">OCI Container Instances</a>.</p>
<h3 id="heading-references">References</h3>
<p><a target="_blank" href="https://docs.oracle.com/en-us/iaas/Content/Registry/Tasks/registrypushingimagesusingthedockercli.htm">Pushing Images Using the Docker CLI (oracle.com)</a></p>
<p><a target="_blank" href="https://docs.oracle.com/en-us/iaas/Content/container-instances/home.htm">Container Instances Documentation (oracle.com)</a></p>
]]></content:encoded></item></channel></rss>