<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-15 --> <h2 id="stored-procedures" class="position-relative d-flex align-items-center group"> <span>Stored Procedures</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="stored-procedures" aria-haspopup="dialog" aria-label="Share link: Stored Procedures"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h2><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden> <div class="hsm-dialog" role="document"> <div class="hsm-header"> <h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2> <button type="button" class="hsm-close" aria-label="Close"> <i class="fa-solid fa-xmark"></i> </button> </div> <div class="hsm-body"> <label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label> <div class="input-group mb-4 hsm-url-group"> <input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" /> <button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy"> <i class="fa-duotone fa-clipboard" aria-hidden="true"></i> </button> </div> <div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div> <div class="hsm-share-grid"> <a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-twitter me-2"></i>Twitter </a> <a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-linkedin me-2"></i>LinkedIn </a> <a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer"> <i class="fa-brands fa-facebook me-2"></i>Facebook </a> </div> </div> </div> </div> <style> .heading-share-modal { position: fixed; inset: 0; display: flex; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); z-index: 1050; padding: 1rem; backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); } .heading-share-modal[hidden] { display: none !important; } .hsm-dialog { max-width: 420px; width: 100%; background: var(--bs-body-bg, #fff); color: var(--bs-body-color, #212529); border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); border-radius: 1rem; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); overflow: hidden; animation: hsm-fade-in 0.2s ease-out; } @keyframes hsm-fade-in { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } } [data-bs-theme="dark"] .hsm-dialog { background: #1e293b; border-color: rgba(255,255,255,0.1); color: #f8f9fa; } .hsm-header { display: flex; justify-content: space-between; align-items: center; padding: 1rem 1.5rem; border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1)); background: rgba(0,0,0,0.02); } [data-bs-theme="dark"] .hsm-header { background: rgba(255,255,255,0.02); border-color: rgba(255,255,255,0.1); } .hsm-close { background: transparent; border: none; color: inherit; opacity: 0.5; padding: 0.25rem 0.5rem; border-radius: 0.25rem; font-size: 1.2rem; line-height: 1; transition: opacity 0.2s; } .hsm-close:hover { opacity: 1; } .hsm-body { padding: 1.5rem; } .hsm-url-group { display: flex !important; align-items: stretch; } .hsm-url-group .form-control { flex: 1; min-width: 0; margin: 0; background: var(--bs-secondary-bg, #f8f9fa); border-color: var(--bs-border-color, #dee2e6); border-top-right-radius: 0; border-bottom-right-radius: 0; height: 42px; } .hsm-url-group .btn { flex: 0 0 auto; margin: 0; margin-left: -1px; border-top-left-radius: 0; border-bottom-left-radius: 0; height: 42px; display: flex; align-items: center; justify-content: center; padding: 0 1.25rem; z-index: 2; } [data-bs-theme="dark"] .hsm-url-group .form-control { background: #0f172a; border-color: #334155; color: #e2e8f0; } .hsm-share-grid { display: flex; flex-direction: column; gap: 0.5rem; } .hsm-share-grid .btn { display: flex; align-items: center; justify-content: center; font-size: 0.9rem; padding: 0.6rem; border-color: var(--bs-border-color); width: 100%; } [data-bs-theme="dark"] .hsm-share-grid .btn { color: #e2e8f0; border-color: #475569; } [data-bs-theme="dark"] .hsm-share-grid .btn:hover { background: #334155; border-color: #cbd5e1; } </style> <script> (function(){ const modal = document.getElementById('headingShareModal'); if(!modal) return; const input = modal.querySelector('#headingShareInput'); const copyBtn = modal.querySelector('.hsm-copy'); const twitter = modal.querySelector('#share-twitter'); const linkedin = modal.querySelector('#share-linkedin'); const facebook = modal.querySelector('#share-facebook'); const closeBtn = modal.querySelector('.hsm-close'); let lastFocus=null; let trapBound=false; function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; } function isOpen(){ return !modal.hasAttribute('hidden'); } function hydrate(id){ const url=buildUrl(id); input.value=url; const enc=encodeURIComponent(url); const text=encodeURIComponent(document.title); if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`; if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`; if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`; } function openModal(id){ lastFocus=document.activeElement; hydrate(id); if(!isOpen()){ modal.removeAttribute('hidden'); } requestAnimationFrame(()=>{ input.focus(); }); trapFocus(); } function closeModal(){ if(!isOpen()) return; modal.setAttribute('hidden',''); if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus(); } function copyCurrent(){ try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); } catch(e){ fallback(); } } function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} } function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); } function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); } function bindShareButtons(){ document.querySelectorAll('.h-share').forEach(btn=>{ if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; } }); } bindShareButtons(); if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', bindShareButtons); } else { requestAnimationFrame(bindShareButtons); } document.addEventListener('click', function(e){ const shareBtn=e.target.closest && e.target.closest('.h-share'); if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); } }, true); document.addEventListener('click', e=>{ if(e.target===modal) closeModal(); if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); } if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); } }); document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); }); function trapFocus(){ if(trapBound) return; trapBound=true; modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } }); } if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); }); })(); </script><p>Stored procedures are reusable, server-side programs written in GQL that encapsulate complex database logic within the database engine. They enable code reuse across applications, improve performance by reducing network roundtrips, enhance security through controlled data access, simplify maintenance by centralizing business logic, and provide transactional consistency for multi-step operations.</p> <h3 id="stored-procedure-fundamentals" class="position-relative d-flex align-items-center group"> <span>Stored Procedure Fundamentals</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="stored-procedure-fundamentals" aria-haspopup="dialog" aria-label="Share link: Stored Procedure Fundamentals"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="what-are-stored-procedures" class="position-relative d-flex align-items-center group"> <span>What are Stored Procedures?</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="what-are-stored-procedures" aria-haspopup="dialog" aria-label="Share link: What are Stored Procedures?"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Stored procedures are named GQL programs that:</p> <p><strong>Execute Server-Side</strong> - Run within the database <strong>Accept Parameters</strong> - Parameterized for reuse <strong>Return Results</strong> - Tables, scalars, or status codes <strong>Encapsulate Logic</strong> - Hide complexity from clients</p> <h4 id="benefits" class="position-relative d-flex align-items-center group"> <span>Benefits</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="benefits" aria-haspopup="dialog" aria-label="Share link: Benefits"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li><strong>Performance</strong> - Reduced network roundtrips</li> <li><strong>Reusability</strong> - Write once, call many times</li> <li><strong>Security</strong> - Control data access</li> <li><strong>Maintainability</strong> - Centralize business logic</li> <li><strong>Consistency</strong> - Ensure uniform data operations</li> </ul> <h3 id="creating-stored-procedures" class="position-relative d-flex align-items-center group"> <span>Creating Stored Procedures</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="creating-stored-procedures" aria-haspopup="dialog" aria-label="Share link: Creating Stored Procedures"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="basic-syntax" class="position-relative d-flex align-items-center group"> <span>Basic Syntax</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="basic-syntax" aria-haspopup="dialog" aria-label="Share link: Basic Syntax"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Simple</span><span class="w"> </span><span class="py">procedure</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">get_user_by_id</span><span class="p">(</span><span class="py">user_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">TABLE</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">name</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">email</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LANGUAGE</span><span class="w"> </span><span class="py">GQL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="kc">QUERY</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">:</span><span class="nc">User</span><span class="w"> </span><span class="p">{</span><span class="py">id</span><span class="p">:</span><span class="w"> </span><span class="nc">user_id</span><span class="p">})</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">email</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Call</span><span class="w"> </span><span class="py">procedure</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="py">get_user_by_id</span><span class="p">(</span><span class="err">&#39;</span><span class="py">user123</span><span class="err">&#39;</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="parameters" class="position-relative d-flex align-items-center group"> <span>Parameters</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="parameters" aria-haspopup="dialog" aria-label="Share link: Parameters"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Support multiple parameter types:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">search_users</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">min_age</span><span class="w"> </span><span class="py">INTEGER</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">max_age</span><span class="w"> </span><span class="py">INTEGER</span><span class="w"> </span><span class="py">DEFAULT</span><span class="w"> </span><span class="py">100</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">name_pattern</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">DEFAULT</span><span class="w"> </span><span class="err">&#39;%&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">TABLE</span><span class="w"> </span><span class="p">(</span><span class="py">id</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span><span class="py">name</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span><span class="py">age</span><span class="w"> </span><span class="py">INTEGER</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LANGUAGE</span><span class="w"> </span><span class="py">GQL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="kc">QUERY</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">u</span><span class="p">:</span><span class="nc">User</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">&gt;</span><span class="p">=</span><span class="w"> </span><span class="py">min_age</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">age</span><span class="w"> </span><span class="err">&lt;</span><span class="p">=</span><span class="w"> </span><span class="py">max_age</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">name</span><span class="w"> </span><span class="py">LIKE</span><span class="w"> </span><span class="py">name_pattern</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">age</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">u</span><span class="err">.</span><span class="py">name</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Call</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">all</span><span class="w"> </span><span class="py">parameters</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="py">search_users</span><span class="p">(</span><span class="py">18</span><span class="p">,</span><span class="w"> </span><span class="py">30</span><span class="p">,</span><span class="w"> </span><span class="err">&#39;</span><span class="py">A</span><span class="err">%&#39;</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Call</span><span class="w"> </span><span class="py">with</span><span class="w"> </span><span class="py">defaults</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="py">search_users</span><span class="p">(</span><span class="py">21</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="complex-procedures" class="position-relative d-flex align-items-center group"> <span>Complex Procedures</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="complex-procedures" aria-haspopup="dialog" aria-label="Share link: Complex Procedures"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="transaction-management" class="position-relative d-flex align-items-center group"> <span>Transaction Management</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="transaction-management" aria-haspopup="dialog" aria-label="Share link: Transaction Management"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Control transactions:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">transfer_funds</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">from_account</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">to_account</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">amount</span><span class="w"> </span><span class="py">DECIMAL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">BOOLEAN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LANGUAGE</span><span class="w"> </span><span class="py">GQL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DECLARE</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">from_balance</span><span class="w"> </span><span class="py">DECIMAL</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Start</span><span class="w"> </span><span class="py">transaction</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">BEGIN</span><span class="w"> </span><span class="py">TRANSACTION</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Check</span><span class="w"> </span><span class="py">balance</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SELECT</span><span class="w"> </span><span class="py">balance</span><span class="w"> </span><span class="py">INTO</span><span class="w"> </span><span class="py">from_balance</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="py">Account</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">from_account</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="py">UPDATE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">IF</span><span class="w"> </span><span class="py">from_balance</span><span class="w"> </span><span class="err">&lt;</span><span class="w"> </span><span class="py">amount</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">ROLLBACK</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">FALSE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">IF</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Debit</span><span class="w"> </span><span class="py">source</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">UPDATE</span><span class="w"> </span><span class="py">Account</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SET</span><span class="w"> </span><span class="py">balance</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">balance</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">amount</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">from_account</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Credit</span><span class="w"> </span><span class="py">destination</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">UPDATE</span><span class="w"> </span><span class="py">Account</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SET</span><span class="w"> </span><span class="py">balance</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">balance</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">amount</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">to_account</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">TRUE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="control-flow" class="position-relative d-flex align-items-center group"> <span>Control Flow</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="control-flow" aria-haspopup="dialog" aria-label="Share link: Control Flow"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Use conditionals and loops:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">calculate_bonus</span><span class="p">(</span><span class="py">employee_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">DECIMAL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LANGUAGE</span><span class="w"> </span><span class="py">GQL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DECLARE</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">salary</span><span class="w"> </span><span class="py">DECIMAL</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">years_employed</span><span class="w"> </span><span class="py">INTEGER</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">bonus</span><span class="w"> </span><span class="py">DECIMAL</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Get</span><span class="w"> </span><span class="py">employee</span><span class="w"> </span><span class="py">data</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SELECT</span><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">salary</span><span class="p">,</span><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">years_employed</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">INTO</span><span class="w"> </span><span class="py">salary</span><span class="p">,</span><span class="w"> </span><span class="py">years_employed</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="py">Employee</span><span class="w"> </span><span class="py">e</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">employee_id</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Calculate</span><span class="w"> </span><span class="py">base</span><span class="w"> </span><span class="py">bonus</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">bonus</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">salary</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">0</span><span class="mf">.1</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Apply</span><span class="w"> </span><span class="py">multipliers</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">IF</span><span class="w"> </span><span class="py">years_employed</span><span class="w"> </span><span class="err">&gt;</span><span class="p">=</span><span class="w"> </span><span class="py">10</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">bonus</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">bonus</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">1</span><span class="mf">.5</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">ELSIF</span><span class="w"> </span><span class="py">years_employed</span><span class="w"> </span><span class="err">&gt;</span><span class="p">=</span><span class="w"> </span><span class="py">5</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">bonus</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">bonus</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">1</span><span class="mf">.25</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">IF</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">bonus</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="calling-procedures" class="position-relative d-flex align-items-center group"> <span>Calling Procedures</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="calling-procedures" aria-haspopup="dialog" aria-label="Share link: Calling Procedures"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="from-gql" class="position-relative d-flex align-items-center group"> <span>From GQL</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="from-gql" aria-haspopup="dialog" aria-label="Share link: From GQL"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Simple</span><span class="w"> </span><span class="py">call</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="py">get_user_by_id</span><span class="p">(</span><span class="err">&#39;</span><span class="py">user123</span><span class="err">&#39;</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">With</span><span class="w"> </span><span class="py">results</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SELECT</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="py">get_user_by_id</span><span class="p">(</span><span class="err">&#39;</span><span class="py">user123</span><span class="err">&#39;</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="from-client-libraries" class="position-relative d-flex align-items-center group"> <span>From Client Libraries</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="from-client-libraries" aria-haspopup="dialog" aria-label="Share link: From Client Libraries"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p>Python:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Call procedure</span> </span></span><span class="line"><span class="cl"><span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">client</span><span class="o">.</span><span class="n">call_procedure</span><span class="p">(</span> </span></span><span class="line"><span class="cl"> <span class="s1">&#39;search_users&#39;</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">min_age</span><span class="o">=</span><span class="mi">18</span><span class="p">,</span> </span></span><span class="line"><span class="cl"> <span class="n">max_age</span><span class="o">=</span><span class="mi">30</span> </span></span><span class="line"><span class="cl"><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">],</span> <span class="n">row</span><span class="p">[</span><span class="s1">&#39;age&#39;</span><span class="p">])</span> </span></span></code></pre></div><p>Go:</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Call procedure </span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nx">rows</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">db</span><span class="p">.</span><span class="nf">Query</span><span class="p">(</span><span class="s">&#34;CALL search_users($1, $2)&#34;</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">30</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span><span class="line"><span class="cl"><span class="k">defer</span> <span class="nx">rows</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="nx">rows</span><span class="p">.</span><span class="nf">Next</span><span class="p">()</span> <span class="p">{</span> </span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">id</span><span class="p">,</span> <span class="nx">name</span> <span class="kt">string</span> </span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">age</span> <span class="kt">int</span> </span></span><span class="line"><span class="cl"> <span class="nx">rows</span><span class="p">.</span><span class="nf">Scan</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">id</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">name</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">age</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;%s: %d\n&#34;</span><span class="p">,</span> <span class="nx">name</span><span class="p">,</span> <span class="nx">age</span><span class="p">)</span> </span></span><span class="line"><span class="cl"><span class="p">}</span> </span></span></code></pre></div> <h3 id="advanced-patterns" class="position-relative d-flex align-items-center group"> <span>Advanced Patterns</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="advanced-patterns" aria-haspopup="dialog" aria-label="Share link: Advanced Patterns"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="dynamic-query-construction" class="position-relative d-flex align-items-center group"> <span>Dynamic Query Construction</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="dynamic-query-construction" aria-haspopup="dialog" aria-label="Share link: Dynamic Query Construction"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">search_entities</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">entity_type</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">filter_conditions</span><span class="w"> </span><span class="py">MAP</span><span class="err">&lt;</span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span><span class="py">ANY</span><span class="err">&gt;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">sort_field</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="py">DEFAULT</span><span class="w"> </span><span class="err">&#39;</span><span class="py">name</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">limit_count</span><span class="w"> </span><span class="py">INTEGER</span><span class="w"> </span><span class="py">DEFAULT</span><span class="w"> </span><span class="py">100</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">TABLE</span><span class="w"> </span><span class="p">(</span><span class="py">entity</span><span class="w"> </span><span class="py">MAP</span><span class="err">&lt;</span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span><span class="py">ANY</span><span class="err">&gt;</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LANGUAGE</span><span class="w"> </span><span class="py">GQL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DECLARE</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">query</span><span class="w"> </span><span class="nc">STRING</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">where_clause</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="err">&#39;&#39;;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nc">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Build</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">clause</span><span class="w"> </span><span class="py">dynamically</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="py">key</span><span class="p">,</span><span class="w"> </span><span class="py">value</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">filter_conditions</span><span class="w"> </span><span class="py">LOOP</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">IF</span><span class="w"> </span><span class="py">where_clause</span><span class="w"> </span><span class="err">&lt;&gt;</span><span class="w"> </span><span class="err">&#39;&#39;</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">where_clause</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">where_clause</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="err">&#39;;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">IF</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">where_clause</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">where_clause</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="py">key</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">$&#39;</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="py">key</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">LOOP</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Construct</span><span class="w"> </span><span class="py">dynamic</span><span class="w"> </span><span class="kd">query</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nc">query</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">MATCH</span><span class="w"> </span><span class="p">(</span><span class="py">n</span><span class="p">:</span><span class="err">&#39;</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="nc">entity_type</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;</span><span class="p">)</span><span class="w"> </span><span class="err">&#39;;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">IF</span><span class="w"> </span><span class="py">where_clause</span><span class="w"> </span><span class="err">&lt;&gt;</span><span class="w"> </span><span class="err">&#39;&#39;</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">query</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">query</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">WHERE</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="py">where_clause</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="err">&#39;;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">IF</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">query</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">query</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;</span><span class="nc">RETURN</span><span class="w"> </span><span class="py">n</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">entity</span><span class="w"> </span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">n</span><span class="err">.&#39;</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="py">sort_field</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="py">LIMIT</span><span class="w"> </span><span class="err">&#39;</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="py">limit_count</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Execute</span><span class="w"> </span><span class="py">dynamic</span><span class="w"> </span><span class="kd">query</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nc">RETURN</span><span class="w"> </span><span class="kc">QUERY</span><span class="w"> </span><span class="py">EXECUTE</span><span class="w"> </span><span class="kd">query</span><span class="w"> </span><span class="nc">USING</span><span class="w"> </span><span class="py">filter_conditions</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="batch-processing" class="position-relative d-flex align-items-center group"> <span>Batch Processing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="batch-processing" aria-haspopup="dialog" aria-label="Share link: Batch Processing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">batch_update_prices</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">price_adjustments</span><span class="w"> </span><span class="py">MAP</span><span class="err">&lt;</span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span><span class="py">DECIMAL</span><span class="err">&gt;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">TABLE</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">product_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">old_price</span><span class="w"> </span><span class="py">DECIMAL</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">new_price</span><span class="w"> </span><span class="py">DECIMAL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LANGUAGE</span><span class="w"> </span><span class="py">GQL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DECLARE</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">pid</span><span class="w"> </span><span class="py">STRING</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">adjustment</span><span class="w"> </span><span class="py">DECIMAL</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">batch_size</span><span class="w"> </span><span class="py">INTEGER</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">100</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">processed</span><span class="w"> </span><span class="py">INTEGER</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">0</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="py">pid</span><span class="p">,</span><span class="w"> </span><span class="py">adjustment</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="py">price_adjustments</span><span class="w"> </span><span class="py">LOOP</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">UPDATE</span><span class="w"> </span><span class="py">Product</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SET</span><span class="w"> </span><span class="py">price</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">price</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">adjustment</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">updated_at</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">NOW</span><span class="p">()</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">pid</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURNING</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">product_id</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">price</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="py">adjustment</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">old_price</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">price</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">new_price</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">processed</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">processed</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">1</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Commit</span><span class="w"> </span><span class="py">in</span><span class="w"> </span><span class="py">batches</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">IF</span><span class="w"> </span><span class="py">processed</span><span class="w"> </span><span class="err">%</span><span class="w"> </span><span class="py">batch_size</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">0</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">BEGIN</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">IF</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">LOOP</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">COMMIT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="recursive-procedures" class="position-relative d-flex align-items-center group"> <span>Recursive Procedures</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="recursive-procedures" aria-haspopup="dialog" aria-label="Share link: Recursive Procedures"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">calculate_org_hierarchy</span><span class="p">(</span><span class="py">root_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span><span class="py">max_depth</span><span class="w"> </span><span class="py">INTEGER</span><span class="w"> </span><span class="py">DEFAULT</span><span class="w"> </span><span class="py">10</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">TABLE</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">node_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">node_name</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">level</span><span class="w"> </span><span class="py">INTEGER</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">path</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">LANGUAGE</span><span class="w"> </span><span class="py">GQL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="kc">QUERY</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WITH</span><span class="w"> </span><span class="py">RECURSIVE</span><span class="w"> </span><span class="py">hierarchy</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Base</span><span class="w"> </span><span class="py">case</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SELECT</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">id</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">node_id</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">name</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">node_name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">0</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">level</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">CAST</span><span class="p">(</span><span class="py">e</span><span class="err">.</span><span class="py">id</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">STRING</span><span class="p">)</span><span class="w"> </span><span class="py">AS</span><span class="w"> </span><span class="py">path</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="py">Employee</span><span class="w"> </span><span class="py">e</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">root_id</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kc">UNION</span><span class="w"> </span><span class="py">ALL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Recursive</span><span class="w"> </span><span class="py">case</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SELECT</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">id</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">h</span><span class="err">.</span><span class="py">level</span><span class="w"> </span><span class="err">+</span><span class="w"> </span><span class="py">1</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">h</span><span class="err">.</span><span class="py">path</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="err">&#39;/&#39;</span><span class="w"> </span><span class="p">||</span><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">id</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="py">Employee</span><span class="w"> </span><span class="py">e</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">JOIN</span><span class="w"> </span><span class="py">hierarchy</span><span class="w"> </span><span class="py">h</span><span class="w"> </span><span class="py">ON</span><span class="w"> </span><span class="py">e</span><span class="err">.</span><span class="py">manager_id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">h</span><span class="err">.</span><span class="py">node_id</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">h</span><span class="err">.</span><span class="py">level</span><span class="w"> </span><span class="err">&lt;</span><span class="w"> </span><span class="py">max_depth</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SELECT</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="py">hierarchy</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">level</span><span class="p">,</span><span class="w"> </span><span class="py">node_name</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="versioning-and-migration" class="position-relative d-flex align-items-center group"> <span>Versioning and Migration</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="versioning-and-migration" aria-haspopup="dialog" aria-label="Share link: Versioning and Migration"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="version-management" class="position-relative d-flex align-items-center group"> <span>Version Management</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="version-management" aria-haspopup="dialog" aria-label="Share link: Version Management"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Version</span><span class="w"> </span><span class="py">1</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">REPLACE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">calculate_discount_v1</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">customer_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">order_total</span><span class="w"> </span><span class="py">DECIMAL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">DECIMAL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">order_total</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">0</span><span class="mf">.1</span><span class="err">;</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Simple</span><span class="w"> </span><span class="py">10</span><span class="err">%</span><span class="w"> </span><span class="py">discount</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Version</span><span class="w"> </span><span class="py">2</span><span class="p">:</span><span class="w"> </span><span class="nc">Enhanced</span><span class="w"> </span><span class="py">logic</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">REPLACE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">calculate_discount_v2</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">customer_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">order_total</span><span class="w"> </span><span class="py">DECIMAL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">DECIMAL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DECLARE</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">customer_tier</span><span class="w"> </span><span class="py">STRING</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">discount_rate</span><span class="w"> </span><span class="py">DECIMAL</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Get</span><span class="w"> </span><span class="py">customer</span><span class="w"> </span><span class="py">tier</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SELECT</span><span class="w"> </span><span class="py">tier</span><span class="w"> </span><span class="py">INTO</span><span class="w"> </span><span class="py">customer_tier</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="py">Customer</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">customer_id</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Tiered</span><span class="w"> </span><span class="py">discounts</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">discount_rate</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">CASE</span><span class="w"> </span><span class="py">customer_tier</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHEN</span><span class="w"> </span><span class="err">&#39;</span><span class="py">platinum</span><span class="err">&#39;</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span><span class="py">0</span><span class="mf">.20</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHEN</span><span class="w"> </span><span class="err">&#39;</span><span class="py">gold</span><span class="err">&#39;</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span><span class="py">0</span><span class="mf">.15</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHEN</span><span class="w"> </span><span class="err">&#39;</span><span class="py">silver</span><span class="err">&#39;</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span><span class="py">0</span><span class="mf">.10</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">ELSE</span><span class="w"> </span><span class="py">0</span><span class="mf">.05</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">order_total</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">discount_rate</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Create</span><span class="w"> </span><span class="py">alias</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">current</span><span class="w"> </span><span class="py">version</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">REPLACE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">calculate_discount</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">customer_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">order_total</span><span class="w"> </span><span class="py">DECIMAL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">DECIMAL</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">calculate_discount_v2</span><span class="p">(</span><span class="py">customer_id</span><span class="p">,</span><span class="w"> </span><span class="py">order_total</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="deprecation-strategy" class="position-relative d-flex align-items-center group"> <span>Deprecation Strategy</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="deprecation-strategy" aria-haspopup="dialog" aria-label="Share link: Deprecation Strategy"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">old_procedure</span><span class="p">(</span><span class="py">param</span><span class="w"> </span><span class="py">STRING</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Log</span><span class="w"> </span><span class="py">deprecation</span><span class="w"> </span><span class="py">warning</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RAISE</span><span class="w"> </span><span class="py">WARNING</span><span class="w"> </span><span class="err">&#39;</span><span class="py">Procedure</span><span class="w"> </span><span class="py">old_procedure</span><span class="w"> </span><span class="py">is</span><span class="w"> </span><span class="py">deprecated</span><span class="err">.</span><span class="w"> </span><span class="py">Use</span><span class="w"> </span><span class="py">new_procedure</span><span class="w"> </span><span class="py">instead</span><span class="err">.&#39;;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Forward</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">new</span><span class="w"> </span><span class="py">implementation</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">new_procedure</span><span class="p">(</span><span class="py">param</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="monitoring-and-debugging" class="position-relative d-flex align-items-center group"> <span>Monitoring and Debugging</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="monitoring-and-debugging" aria-haspopup="dialog" aria-label="Share link: Monitoring and Debugging"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="execution-logging" class="position-relative d-flex align-items-center group"> <span>Execution Logging</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="execution-logging" aria-haspopup="dialog" aria-label="Share link: Execution Logging"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">process_order_with_logging</span><span class="p">(</span><span class="py">order_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">BOOLEAN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DECLARE</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">start_time</span><span class="w"> </span><span class="py">TIMESTAMP</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">end_time</span><span class="w"> </span><span class="py">TIMESTAMP</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">rows_affected</span><span class="w"> </span><span class="py">INTEGER</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">start_time</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">NOW</span><span class="p">()</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Log</span><span class="w"> </span><span class="py">procedure</span><span class="w"> </span><span class="py">start</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">INSERT</span><span class="w"> </span><span class="py">INTO</span><span class="w"> </span><span class="py">procedure_log</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">procedure_name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">parameters</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">start_time</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">status</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="py">VALUES</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">&#39;</span><span class="py">process_order_with_logging</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">json_build_object</span><span class="p">(</span><span class="err">&#39;</span><span class="py">order_id</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span><span class="py">order_id</span><span class="p">),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">start_time</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">&#39;</span><span class="py">running</span><span class="err">&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Main</span><span class="w"> </span><span class="py">logic</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">UPDATE</span><span class="w"> </span><span class="py">Order</span><span class="w"> </span><span class="py">SET</span><span class="w"> </span><span class="py">status</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">processing</span><span class="err">&#39;</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">order_id</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">GET</span><span class="w"> </span><span class="py">DIAGNOSTICS</span><span class="w"> </span><span class="py">rows_affected</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">ROW_COUNT</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Process</span><span class="w"> </span><span class="py">order</span><span class="w"> </span><span class="py">steps</span><span class="kd">...</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">end_time</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">NOW</span><span class="p">()</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Log</span><span class="w"> </span><span class="py">completion</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">UPDATE</span><span class="w"> </span><span class="py">procedure_log</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SET</span><span class="w"> </span><span class="py">end_time</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">end_time</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">duration_ms</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">EXTRACT</span><span class="p">(</span><span class="py">MILLISECONDS</span><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="p">(</span><span class="py">end_time</span><span class="w"> </span><span class="err">-</span><span class="w"> </span><span class="py">start_time</span><span class="p">)),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">rows_affected</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">rows_affected</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">status</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">completed</span><span class="err">&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">procedure_name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">process_order_with_logging</span><span class="err">&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">start_time</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">start_time</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">TRUE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">EXCEPTION</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHEN</span><span class="w"> </span><span class="py">OTHERS</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Log</span><span class="w"> </span><span class="py">error</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">UPDATE</span><span class="w"> </span><span class="py">procedure_log</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SET</span><span class="w"> </span><span class="py">end_time</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">NOW</span><span class="p">(),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">status</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">failed</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">error_message</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">SQLERRM</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">procedure_name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">process_order_with_logging</span><span class="err">&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">AND</span><span class="w"> </span><span class="py">start_time</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">start_time</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RAISE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="performance-profiling" class="position-relative d-flex align-items-center group"> <span>Performance Profiling</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance-profiling" aria-haspopup="dialog" aria-label="Share link: Performance Profiling"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Query</span><span class="w"> </span><span class="py">procedure</span><span class="w"> </span><span class="py">statistics</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SELECT</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">procedure_name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">call_count</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">total_time_ms</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">avg_time_ms</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">min_time_ms</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">max_time_ms</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">last_called</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">FROM</span><span class="w"> </span><span class="py">system</span><span class="err">.</span><span class="py">procedure_stats</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">procedure_name</span><span class="w"> </span><span class="py">LIKE</span><span class="w"> </span><span class="err">&#39;</span><span class="py">process_</span><span class="err">%&#39;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">total_time_ms</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Identify</span><span class="w"> </span><span class="py">slow</span><span class="w"> </span><span class="py">procedures</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SELECT</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">procedure_name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">avg_time_ms</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">call_count</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">FROM</span><span class="w"> </span><span class="py">system</span><span class="err">.</span><span class="py">procedure_stats</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">avg_time_ms</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">1000</span><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Slower</span><span class="w"> </span><span class="py">than</span><span class="w"> </span><span class="py">1</span><span class="w"> </span><span class="py">second</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">ORDER</span><span class="w"> </span><span class="py">BY</span><span class="w"> </span><span class="py">avg_time_ms</span><span class="w"> </span><span class="py">DESC</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="testing-stored-procedures" class="position-relative d-flex align-items-center group"> <span>Testing Stored Procedures</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="testing-stored-procedures" aria-haspopup="dialog" aria-label="Share link: Testing Stored Procedures"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="unit-testing" class="position-relative d-flex align-items-center group"> <span>Unit Testing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="unit-testing" aria-haspopup="dialog" aria-label="Share link: Unit Testing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Test</span><span class="w"> </span><span class="py">procedure</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">test_calculate_discount</span><span class="p">()</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">BOOLEAN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DECLARE</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">result</span><span class="w"> </span><span class="py">DECIMAL</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">expected</span><span class="w"> </span><span class="py">DECIMAL</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Test</span><span class="w"> </span><span class="py">case</span><span class="w"> </span><span class="py">1</span><span class="p">:</span><span class="w"> </span><span class="nc">Regular</span><span class="w"> </span><span class="py">customer</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">result</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">calculate_discount</span><span class="p">(</span><span class="err">&#39;</span><span class="py">cust_123</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span><span class="py">100</span><span class="mf">.00</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">expected</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">10</span><span class="mf">.00</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">IF</span><span class="w"> </span><span class="py">result</span><span class="w"> </span><span class="err">&lt;&gt;</span><span class="w"> </span><span class="py">expected</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RAISE</span><span class="w"> </span><span class="py">EXCEPTION</span><span class="w"> </span><span class="err">&#39;</span><span class="py">Test</span><span class="w"> </span><span class="py">failed</span><span class="p">:</span><span class="w"> </span><span class="nc">Expected</span><span class="w"> </span><span class="err">%</span><span class="p">,</span><span class="w"> </span><span class="py">got</span><span class="w"> </span><span class="err">%&#39;</span><span class="p">,</span><span class="w"> </span><span class="py">expected</span><span class="p">,</span><span class="w"> </span><span class="py">result</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">IF</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Test</span><span class="w"> </span><span class="py">case</span><span class="w"> </span><span class="py">2</span><span class="p">:</span><span class="w"> </span><span class="nc">Platinum</span><span class="w"> </span><span class="py">customer</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">result</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">calculate_discount</span><span class="p">(</span><span class="err">&#39;</span><span class="py">cust_platinum</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span><span class="py">100</span><span class="mf">.00</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">expected</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">20</span><span class="mf">.00</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">IF</span><span class="w"> </span><span class="py">result</span><span class="w"> </span><span class="err">&lt;&gt;</span><span class="w"> </span><span class="py">expected</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RAISE</span><span class="w"> </span><span class="py">EXCEPTION</span><span class="w"> </span><span class="err">&#39;</span><span class="py">Test</span><span class="w"> </span><span class="py">failed</span><span class="p">:</span><span class="w"> </span><span class="nc">Expected</span><span class="w"> </span><span class="err">%</span><span class="p">,</span><span class="w"> </span><span class="py">got</span><span class="w"> </span><span class="err">%&#39;</span><span class="p">,</span><span class="w"> </span><span class="py">expected</span><span class="p">,</span><span class="w"> </span><span class="py">result</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">IF</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">All</span><span class="w"> </span><span class="py">tests</span><span class="w"> </span><span class="py">passed</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">TRUE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Run</span><span class="w"> </span><span class="py">tests</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CALL</span><span class="w"> </span><span class="py">test_calculate_discount</span><span class="p">()</span><span class="err">;</span><span class="w"> </span></span></span></code></pre></div> <h4 id="integration-testing" class="position-relative d-flex align-items-center group"> <span>Integration Testing</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="integration-testing" aria-haspopup="dialog" aria-label="Share link: Integration Testing"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># Python integration tests</span> </span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pytest</span> </span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">Client</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"><span class="nd">@pytest.mark.asyncio</span> </span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">test_process_order_procedure</span><span class="p">():</span> </span></span><span class="line"><span class="cl"> <span class="n">client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="s2">&#34;localhost&#34;</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="mi">3141</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span> </span></span><span class="line"><span class="cl"> <span class="c1"># Setup test data</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> CREATE (o:Order { </span></span></span><span class="line"><span class="cl"><span class="s2"> id: &#39;test_order_1&#39;, </span></span></span><span class="line"><span class="cl"><span class="s2"> status: &#39;pending&#39;, </span></span></span><span class="line"><span class="cl"><span class="s2"> total: 150.00 </span></span></span><span class="line"><span class="cl"><span class="s2"> }) </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Call procedure</span> </span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">&#34;CALL process_order(&#39;test_order_1&#39;)&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Verify results</span> </span></span><span class="line"><span class="cl"> <span class="n">order</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;&#34;&#34; </span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (o:Order {id: &#39;test_order_1&#39;}) </span></span></span><span class="line"><span class="cl"><span class="s2"> RETURN o.status, o.processed_at </span></span></span><span class="line"><span class="cl"><span class="s2"> &#34;&#34;&#34;</span><span class="p">)</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="n">order</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s1">&#39;o.status&#39;</span><span class="p">]</span> <span class="o">==</span> <span class="s1">&#39;completed&#39;</span> </span></span><span class="line"><span class="cl"> <span class="k">assert</span> <span class="n">order</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s1">&#39;o.processed_at&#39;</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> </span></span><span class="line"><span class="cl"> </span></span><span class="line"><span class="cl"> <span class="c1"># Cleanup</span> </span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&#34;MATCH (o:Order {id: &#39;test_order_1&#39;}) DELETE o&#34;</span><span class="p">)</span> </span></span></code></pre></div> <h3 id="best-practices" class="position-relative d-flex align-items-center group"> <span>Best Practices</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="best-practices" aria-haspopup="dialog" aria-label="Share link: Best Practices"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="design-principles" class="position-relative d-flex align-items-center group"> <span>Design Principles</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="design-principles" aria-haspopup="dialog" aria-label="Share link: Design Principles"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ol> <li><strong>Single Responsibility</strong>: Each procedure does one thing well</li> <li><strong>Clear Naming</strong>: Use descriptive verb-noun names (calculate_discount, process_order)</li> <li><strong>Parameter Validation</strong>: Validate all inputs at procedure start</li> <li><strong>Error Handling</strong>: Comprehensive exception handling with meaningful messages</li> <li><strong>Documentation</strong>: Document parameters, return values, and business logic</li> <li><strong>Version Control</strong>: Version procedures and maintain backwards compatibility</li> <li><strong>Idempotency</strong>: Design procedures to be safely re-executed</li> </ol> <h4 id="performance-guidelines" class="position-relative d-flex align-items-center group"> <span>Performance Guidelines</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="performance-guidelines" aria-haspopup="dialog" aria-label="Share link: Performance Guidelines"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><ul> <li><strong>Minimize Locks</strong>: Keep transactions short</li> <li><strong>Use Indexes</strong>: Ensure queries within procedures use indexes</li> <li><strong>Batch Operations</strong>: Process multiple items in single transaction</li> <li><strong>Avoid Cursors</strong>: Use set-based operations when possible</li> <li><strong>Cache Results</strong>: Store expensive calculations in temp tables</li> <li><strong>Monitor Metrics</strong>: Track execution time and resource usage</li> </ul> <h4 id="security-best-practices" class="position-relative d-flex align-items-center group"> <span>Security Best Practices</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="security-best-practices" aria-haspopup="dialog" aria-label="Share link: Security Best Practices"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">secure_update_salary</span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">employee_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">new_salary</span><span class="w"> </span><span class="py">DECIMAL</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">updater_id</span><span class="w"> </span><span class="py">STRING</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">RETURNS</span><span class="w"> </span><span class="py">BOOLEAN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DECLARE</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">updater_role</span><span class="w"> </span><span class="py">STRING</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Authorization</span><span class="w"> </span><span class="py">check</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SELECT</span><span class="w"> </span><span class="py">role</span><span class="w"> </span><span class="py">INTO</span><span class="w"> </span><span class="py">updater_role</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="py">User</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">updater_id</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">IF</span><span class="w"> </span><span class="py">updater_role</span><span class="w"> </span><span class="py">NOT</span><span class="w"> </span><span class="py">IN</span><span class="w"> </span><span class="p">(</span><span class="err">&#39;</span><span class="py">admin</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span><span class="err">&#39;</span><span class="py">hr_manager</span><span class="err">&#39;</span><span class="p">)</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RAISE</span><span class="w"> </span><span class="py">EXCEPTION</span><span class="w"> </span><span class="err">&#39;</span><span class="py">Unauthorized</span><span class="p">:</span><span class="w"> </span><span class="nc">Only</span><span class="w"> </span><span class="py">admins</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">HR</span><span class="w"> </span><span class="py">managers</span><span class="w"> </span><span class="py">can</span><span class="w"> </span><span class="py">update</span><span class="w"> </span><span class="py">salaries</span><span class="err">&#39;;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">IF</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Input</span><span class="w"> </span><span class="py">validation</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">IF</span><span class="w"> </span><span class="py">new_salary</span><span class="w"> </span><span class="err">&lt;</span><span class="w"> </span><span class="py">0</span><span class="w"> </span><span class="py">OR</span><span class="w"> </span><span class="py">new_salary</span><span class="w"> </span><span class="err">&gt;</span><span class="w"> </span><span class="py">1000000</span><span class="w"> </span><span class="py">THEN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RAISE</span><span class="w"> </span><span class="py">EXCEPTION</span><span class="w"> </span><span class="err">&#39;</span><span class="py">Invalid</span><span class="w"> </span><span class="py">salary</span><span class="p">:</span><span class="w"> </span><span class="nc">Must</span><span class="w"> </span><span class="py">be</span><span class="w"> </span><span class="py">between</span><span class="w"> </span><span class="py">0</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">1</span><span class="p">,</span><span class="py">000</span><span class="p">,</span><span class="py">000</span><span class="err">&#39;;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">END</span><span class="w"> </span><span class="py">IF</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Audit</span><span class="w"> </span><span class="py">logging</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">INSERT</span><span class="w"> </span><span class="py">INTO</span><span class="w"> </span><span class="py">audit_log</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">action</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">table_name</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">record_id</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">performed_by</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">timestamp</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="py">VALUES</span><span class="w"> </span><span class="p">(</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">&#39;</span><span class="py">UPDATE_SALARY</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">&#39;</span><span class="py">Employee</span><span class="err">&#39;</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">employee_id</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">updater_id</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">NOW</span><span class="p">()</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Perform</span><span class="w"> </span><span class="py">update</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">UPDATE</span><span class="w"> </span><span class="py">Employee</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SET</span><span class="w"> </span><span class="py">salary</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">new_salary</span><span class="p">,</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">updated_at</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">NOW</span><span class="p">(),</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">updated_by</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">updater_id</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">employee_id</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">RETURN</span><span class="w"> </span><span class="py">TRUE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="troubleshooting" class="position-relative d-flex align-items-center group"> <span>Troubleshooting</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="troubleshooting" aria-haspopup="dialog" aria-label="Share link: Troubleshooting"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3> <h4 id="common-issues" class="position-relative d-flex align-items-center group"> <span>Common Issues</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="common-issues" aria-haspopup="dialog" aria-label="Share link: Common Issues"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h4><p><strong>Problem</strong>: Procedure is slow</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Solution</span><span class="p">:</span><span class="w"> </span><span class="nc">Profile</span><span class="w"> </span><span class="py">and</span><span class="w"> </span><span class="py">optimize</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">EXPLAIN</span><span class="w"> </span><span class="py">ANALYZE</span><span class="w"> </span><span class="py">CALL</span><span class="w"> </span><span class="py">my_procedure</span><span class="p">(</span><span class="err">&#39;</span><span class="py">param</span><span class="err">&#39;</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">--</span><span class="w"> </span><span class="py">Check</span><span class="w"> </span><span class="py">for</span><span class="w"> </span><span class="py">missing</span><span class="w"> </span><span class="py">indexes</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">SELECT</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="py">system</span><span class="err">.</span><span class="py">procedure_stats</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">WHERE</span><span class="w"> </span><span class="py">procedure_name</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="err">&#39;</span><span class="py">my_procedure</span><span class="err">&#39;;</span><span class="w"> </span></span></span></code></pre></div><p><strong>Problem</strong>: Deadlocks in concurrent execution</p> <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gql" data-lang="gql"><span class="line"><span class="cl"><span class="err">--</span><span class="w"> </span><span class="py">Solution</span><span class="p">:</span><span class="w"> </span><span class="nc">Use</span><span class="w"> </span><span class="py">explicit</span><span class="w"> </span><span class="py">lock</span><span class="w"> </span><span class="py">ordering</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">CREATE</span><span class="w"> </span><span class="py">PROCEDURE</span><span class="w"> </span><span class="py">safe_transfer</span><span class="p">(</span><span class="py">from_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span><span class="py">to_id</span><span class="w"> </span><span class="py">STRING</span><span class="p">,</span><span class="w"> </span><span class="py">amount</span><span class="w"> </span><span class="py">DECIMAL</span><span class="p">)</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">AS</span><span class="w"> </span><span class="err">$$</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">DECLARE</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">first_id</span><span class="w"> </span><span class="py">STRING</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">second_id</span><span class="w"> </span><span class="py">STRING</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">BEGIN</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Always</span><span class="w"> </span><span class="py">lock</span><span class="w"> </span><span class="py">in</span><span class="w"> </span><span class="py">same</span><span class="w"> </span><span class="py">order</span><span class="w"> </span><span class="py">to</span><span class="w"> </span><span class="py">prevent</span><span class="w"> </span><span class="py">deadlock</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">first_id</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">LEAST</span><span class="p">(</span><span class="py">from_id</span><span class="p">,</span><span class="w"> </span><span class="py">to_id</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">second_id</span><span class="w"> </span><span class="p">:=</span><span class="w"> </span><span class="nc">GREATEST</span><span class="p">(</span><span class="py">from_id</span><span class="p">,</span><span class="w"> </span><span class="py">to_id</span><span class="p">)</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Lock</span><span class="w"> </span><span class="py">accounts</span><span class="w"> </span><span class="py">in</span><span class="w"> </span><span class="py">deterministic</span><span class="w"> </span><span class="py">order</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SELECT</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="py">Account</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">first_id</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="py">UPDATE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="py">SELECT</span><span class="w"> </span><span class="err">*</span><span class="w"> </span><span class="py">FROM</span><span class="w"> </span><span class="py">Account</span><span class="w"> </span><span class="py">WHERE</span><span class="w"> </span><span class="py">id</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="py">second_id</span><span class="w"> </span><span class="py">FOR</span><span class="w"> </span><span class="py">UPDATE</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="py">Perform</span><span class="w"> </span><span class="py">transfer</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="err">--</span><span class="w"> </span><span class="kd">...</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="py">END</span><span class="err">;</span><span class="w"> </span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="err">$$;</span><span class="w"> </span></span></span></code></pre></div> <h3 id="related-topics" class="position-relative d-flex align-items-center group"> <span>Related Topics</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="related-topics" aria-haspopup="dialog" aria-label="Share link: Related Topics"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><a href="/tags/functions/" >Functions</a> - User-defined functions</li> <li><a href="/tags/transactions/" >Transactions</a> - Transaction management</li> <li><a href="/tags/security/" >Security</a> - Access control and authorization</li> <li><a href="/tags/performance/" >Performance</a> - Query optimization</li> </ul> <h3 id="further-reading" class="position-relative d-flex align-items-center group"> <span>Further Reading</span> <button type="button" class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1" data-share-target="further-reading" aria-haspopup="dialog" aria-label="Share link: Further Reading"> <i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i> <span class="visually-hidden">Share link</span> </button> </h3><ul> <li><a href="https://www.postgresql.org/docs/current/sql-createprocedure.html" aria-label="PostgreSQL Stored Procedures – opens in new window" target="_blank" rel="noopener noreferrer" >PostgreSQL Stored Procedures <span aria-hidden="true" class="external-icon">↗</span> </a> - PostgreSQL documentation</li> <li><a href="https://docs.microsoft.com/en-us/sql/relational-databases/stored-procedures/stored-procedures-database-engine" aria-label="T-SQL Procedures – opens in new window" target="_blank" rel="noopener noreferrer" >T-SQL Procedures <span aria-hidden="true" class="external-icon">↗</span> </a> - SQL Server guide</li> <li><a href="https://docs.oracle.com/en/database/oracle/oracle-database/21/lnpls/CREATE-PROCEDURE-statement.html" aria-label="PL/SQL Procedures – opens in new window" target="_blank" rel="noopener noreferrer" >PL/SQL Procedures <span aria-hidden="true" class="external-icon">↗</span> </a> - Oracle documentation</li> </ul>

Related Articles

No articles found with this tag yet.

Back to Home